/[rdesktop]/sourceforge.net/trunk/rdesktop/xwin.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /sourceforge.net/trunk/rdesktop/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 17 - (show annotations)
Thu Sep 28 15:54:11 2000 UTC (23 years, 7 months ago) by matty
File MIME type: text/plain
File size: 12273 byte(s)
Fixes (?) for font problems with Microsoft Office
Added URL to website http://www.rdesktop.org/
Releasing 0.9.0-alpha2

1 /*
2 rdesktop: A Remote Desktop Protocol client.
3 User interface services - X-Windows
4 Copyright (C) Matthew Chapman 1999-2000
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <X11/Xlib.h>
22 #include <time.h>
23 #include "rdesktop.h"
24
25 extern int width;
26 extern int height;
27 extern BOOL motion;
28
29 static Display *display;
30 static Window wnd;
31 static GC gc;
32 static Visual *visual;
33 static XIM IM;
34
35 BOOL ui_create_window(char *title)
36 {
37 Screen *screen;
38 XSetWindowAttributes attribs;
39 unsigned long input_mask;
40 int i;
41
42 display = XOpenDisplay(NULL);
43 if (display == NULL)
44 return False;
45
46 /* Check the screen supports 8-bit depth. */
47 screen = DefaultScreenOfDisplay(display);
48 for (i = 0; i < screen->ndepths; i++)
49 if (screen->depths[i].depth == 8)
50 break;
51
52 if (i >= screen->ndepths)
53 {
54 ERROR("8-bit depth required (in this version).\n");
55 XCloseDisplay(display);
56 return False;
57 }
58
59 visual = DefaultVisual(display, DefaultScreen(display));
60
61 attribs.background_pixel = BlackPixel(display, DefaultScreen(display));
62 attribs.backing_store = Always;
63 wnd = XCreateWindow(display, DefaultRootWindow(display),
64 0, 0, width, height, 0, 8, InputOutput, visual,
65 CWBackingStore | CWBackPixel, &attribs);
66
67 XStoreName(display, wnd, title);
68 XMapWindow(display, wnd);
69
70 input_mask = KeyPressMask | KeyReleaseMask;
71 input_mask |= ButtonPressMask | ButtonReleaseMask;
72 if (motion)
73 input_mask |= PointerMotionMask;
74
75 XSelectInput(display, wnd, input_mask);
76 gc = XCreateGC(display, wnd, 0, NULL);
77
78 IM = XOpenIM(display, NULL, NULL, NULL);
79 return True;
80 }
81
82 void ui_destroy_window()
83 {
84 XCloseIM(IM);
85 XFreeGC(display, gc);
86 XDestroyWindow(display, wnd);
87 XCloseDisplay(display);
88 }
89
90 static uint8 xwin_translate_key(unsigned long key)
91 {
92 DEBUG("KEY(code=0x%lx)\n", key);
93
94 if ((key > 8) && (key <= 0x60))
95 return (key - 8);
96
97 switch (key)
98 {
99 case 0x62: /* left arrow */
100 return 0x48;
101 case 0x64: /* up arrow */
102 return 0x4b;
103 case 0x66: /* down arrow */
104 return 0x4d;
105 case 0x68: /* right arrow */
106 return 0x50;
107 case 0x73: /* Windows key */
108 DEBUG("CHECKPOINT\n");
109 }
110
111 return 0;
112 }
113
114 static uint16 xwin_translate_mouse(unsigned long button)
115 {
116 switch (button)
117 {
118 case Button1: /* left */
119 return MOUSE_FLAG_BUTTON1;
120 case Button2: /* middle */
121 return MOUSE_FLAG_BUTTON3;
122 case Button3: /* right */
123 return MOUSE_FLAG_BUTTON2;
124 }
125
126 return 0;
127 }
128
129 void ui_process_events()
130 {
131 XEvent event;
132 uint8 scancode;
133 uint16 button;
134 uint32 ev_time;
135
136 if (display == NULL)
137 return;
138
139 while (XCheckWindowEvent(display, wnd, 0xffffffff, &event))
140 {
141 ev_time = time(NULL);
142
143 switch (event.type)
144 {
145 case KeyPress:
146 scancode = xwin_translate_key(event.xkey.keycode);
147 if (scancode == 0)
148 break;
149
150 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,
151 scancode, 0);
152 break;
153
154 case KeyRelease:
155 scancode = xwin_translate_key(event.xkey.keycode);
156 if (scancode == 0)
157 break;
158
159 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
160 KBD_FLAG_DOWN | KBD_FLAG_UP,
161 scancode, 0);
162 break;
163
164 case ButtonPress:
165 button = xwin_translate_mouse(event.xbutton.button);
166
167 if (button == 0)
168 break;
169
170 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
171 button | MOUSE_FLAG_DOWN,
172 event.xbutton.x,
173 event.xbutton.y);
174 break;
175
176 case ButtonRelease:
177 button = xwin_translate_mouse(event.xbutton.button);
178 if (button == 0)
179 break;
180
181 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
182 button,
183 event.xbutton.x,
184 event.xbutton.y);
185 break;
186
187 case MotionNotify:
188 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
189 MOUSE_FLAG_MOVE,
190 event.xmotion.x,
191 event.xmotion.y);
192 }
193 }
194 }
195
196 void ui_move_pointer(int x, int y)
197 {
198 XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
199 }
200
201 HBITMAP ui_create_bitmap(int width, int height, uint8 *data)
202 {
203 XImage *image;
204 Pixmap bitmap;
205
206 bitmap = XCreatePixmap(display, wnd, width, height, 8);
207
208 image = XCreateImage(display, visual, 8, ZPixmap, 0,
209 data, width, height, 8, width);
210 XSetFunction(display, gc, GXcopy);
211 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
212 XFree(image);
213
214 return (HBITMAP)bitmap;
215 }
216
217 void ui_paint_bitmap(int x, int y, int cx, int cy,
218 int width, int height, uint8 *data)
219 {
220 XImage *image;
221
222 image = XCreateImage(display, visual, 8, ZPixmap, 0,
223 data, width, height, 8, width);
224 XSetFunction(display, gc, GXcopy);
225 XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
226 XFree(image);
227 }
228
229 void ui_destroy_bitmap(HBITMAP bmp)
230 {
231 XFreePixmap(display, (Pixmap)bmp);
232 }
233
234 HGLYPH ui_create_glyph(int width, int height, uint8 *data)
235 {
236 XImage *image;
237 Pixmap bitmap;
238 int scanline;
239 GC gc;
240
241 scanline = (width + 7) / 8;
242
243 bitmap = XCreatePixmap(display, wnd, width, height, 1);
244 gc = XCreateGC(display, bitmap, 0, NULL);
245
246 image = XCreateImage(display, visual, 1, ZPixmap, 0,
247 data, width, height, 8, scanline);
248 XSetFunction(display, gc, GXcopy);
249 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
250 XFree(image);
251 XFreeGC(display, gc);
252
253 return (HGLYPH)bitmap;
254 }
255
256 void ui_destroy_glyph(HGLYPH glyph)
257 {
258 XFreePixmap(display, (Pixmap)glyph);
259 }
260
261 HCOLOURMAP ui_create_colourmap(COLOURMAP *colours)
262 {
263 COLOURENTRY *entry;
264 XColor *xcolours, *xentry;
265 Colormap map;
266 int i, ncolours = colours->ncolours;
267
268 xcolours = xmalloc(sizeof(XColor) * ncolours);
269 for (i = 0; i < ncolours; i++)
270 {
271 entry = &colours->colours[i];
272 xentry = &xcolours[i];
273
274 xentry->pixel = i;
275 xentry->red = entry->red << 8;
276 xentry->blue = entry->blue << 8;
277 xentry->green = entry->green << 8;
278 xentry->flags = DoRed | DoBlue | DoGreen;
279 }
280
281 map = XCreateColormap(display, wnd, visual, AllocAll);
282 XStoreColors(display, map, xcolours, ncolours);
283
284 xfree(xcolours);
285 return (HCOLOURMAP)map;
286 }
287
288 void ui_destroy_colourmap(HCOLOURMAP map)
289 {
290 XFreeColormap(display, (Colormap)map);
291 }
292
293 void ui_set_colourmap(HCOLOURMAP map)
294 {
295 XSetWindowColormap(display, wnd, (Colormap)map);
296 }
297
298 void ui_set_clip(int x, int y, int cx, int cy)
299 {
300 XRectangle rect;
301
302 rect.x = x;
303 rect.y = y;
304 rect.width = cx;
305 rect.height = cy;
306 XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
307 }
308
309 void ui_reset_clip()
310 {
311 XRectangle rect;
312
313 rect.x = 0;
314 rect.y = 0;
315 rect.width = width;
316 rect.height = height;
317 XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
318 }
319
320 void ui_bell()
321 {
322 XBell(display, 0);
323 }
324
325 static int rop2_map[] = {
326 GXclear, /* 0 */
327 GXnor, /* DPon */
328 GXandInverted, /* DPna */
329 GXcopyInverted, /* Pn */
330 GXandReverse, /* PDna */
331 GXinvert, /* Dn */
332 GXxor, /* DPx */
333 GXnand, /* DPan */
334 GXand, /* DPa */
335 GXequiv, /* DPxn */
336 GXnoop, /* D */
337 GXorInverted, /* DPno */
338 GXcopy, /* P */
339 GXorReverse, /* PDno */
340 GXor, /* DPo */
341 GXset /* 1 */
342 };
343
344 static void xwin_set_function(uint8 rop2)
345 {
346 XSetFunction(display, gc, rop2_map[rop2]);
347 }
348
349 void ui_destblt(uint8 opcode,
350 /* dest */ int x, int y, int cx, int cy)
351 {
352 xwin_set_function(opcode);
353
354 XFillRectangle(display, wnd, gc, x, y, cx, cy);
355 }
356
357 void ui_patblt(uint8 opcode,
358 /* dest */ int x, int y, int cx, int cy,
359 /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
360 {
361 Display *dpy = display;
362 Pixmap fill;
363
364 xwin_set_function(opcode);
365
366 switch (brush->style)
367 {
368 case 0: /* Solid */
369 XSetForeground(dpy, gc, fgcolour);
370 XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
371 break;
372
373 case 3: /* Pattern */
374 fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);
375
376 XSetForeground(dpy, gc, fgcolour);
377 XSetBackground(dpy, gc, bgcolour);
378 XSetFillStyle(dpy, gc, FillOpaqueStippled);
379 XSetStipple(dpy, gc, fill);
380
381 XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
382
383 XSetFillStyle(dpy, gc, FillSolid);
384 ui_destroy_glyph((HGLYPH)fill);
385 break;
386
387 default:
388 NOTIMP("brush %d\n", brush->style);
389 }
390 }
391
392 void ui_screenblt(uint8 opcode,
393 /* dest */ int x, int y, int cx, int cy,
394 /* src */ int srcx, int srcy)
395 {
396 xwin_set_function(opcode);
397
398 XCopyArea(display, wnd, wnd, gc, srcx, srcy,
399 cx, cy, x, y);
400 }
401
402 void ui_memblt(uint8 opcode,
403 /* dest */ int x, int y, int cx, int cy,
404 /* src */ HBITMAP src, int srcx, int srcy)
405 {
406 xwin_set_function(opcode);
407
408 XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy,
409 cx, cy, x, y);
410 }
411
412 void ui_triblt(uint8 opcode,
413 /* dest */ int x, int y, int cx, int cy,
414 /* src */ HBITMAP src, int srcx, int srcy,
415 /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
416 {
417 /* This is potentially difficult to do in general. Until someone
418 comes up with a more efficient way of doing it I am using cases. */
419
420 switch (opcode)
421 {
422 case 0x69: /* PDSxxn */
423 ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
424 ui_patblt(ROP2_NXOR, x, y, cx, cy,
425 brush, bgcolour, fgcolour);
426 break;
427
428 case 0xb8: /* PSDPxax */
429 ui_patblt(ROP2_XOR, x, y, cx, cy,
430 brush, bgcolour, fgcolour);
431 ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
432 ui_patblt(ROP2_XOR, x, y, cx, cy,
433 brush, bgcolour, fgcolour);
434 break;
435
436 default:
437 NOTIMP("triblt 0x%x\n", opcode);
438 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
439 }
440 }
441
442 void ui_line(uint8 opcode,
443 /* dest */ int startx, int starty, int endx, int endy,
444 /* pen */ PEN *pen)
445 {
446 xwin_set_function(opcode);
447
448 XSetForeground(display, gc, pen->colour);
449 XDrawLine(display, wnd, gc, startx, starty, endx, endy);
450 }
451
452 void ui_rect(
453 /* dest */ int x, int y, int cx, int cy,
454 /* brush */ int colour)
455 {
456 xwin_set_function(ROP2_COPY);
457
458 XSetForeground(display, gc, colour);
459 XFillRectangle(display, wnd, gc, x, y, cx, cy);
460 }
461
462 void ui_draw_glyph(int mixmode,
463 /* dest */ int x, int y, int cx, int cy,
464 /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour, int fgcolour)
465 {
466 Pixmap pixmap = (Pixmap)glyph;
467
468 xwin_set_function(ROP2_COPY);
469
470 XSetForeground(display, gc, fgcolour);
471
472 switch (mixmode)
473 {
474 case MIX_TRANSPARENT:
475 XSetStipple(display, gc, pixmap);
476 XSetFillStyle(display, gc, FillStippled);
477 XSetTSOrigin(display, gc, x, y);
478 XFillRectangle(display, wnd, gc,
479 x, y, cx, cy);
480 XSetFillStyle(display, gc, FillSolid);
481 break;
482
483 case MIX_OPAQUE:
484 XSetBackground(display, gc, bgcolour);
485 XCopyPlane(display, pixmap, wnd, gc,
486 srcx, srcy, cx, cy, x, y, 1);
487 break;
488
489 default:
490 NOTIMP("mix %d\n", mixmode);
491 }
492 }
493
494 void ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
495 int clipx, int clipy, int clipcx, int clipcy,
496 int boxx, int boxy, int boxcx, int boxcy,
497 int bgcolour, int fgcolour, uint8 *text, uint8 length)
498 {
499 FONTGLYPH *glyph;
500 int i;
501
502 if (boxcx > 1)
503 {
504 ui_rect(boxx, boxy, boxcx, boxcy, bgcolour);
505 }
506 else if (mixmode == MIX_OPAQUE)
507 {
508 ui_rect(clipx, clipy, clipcx, clipcy, bgcolour);
509 }
510
511 /* Paint text, character by character */
512 for (i = 0; i < length; i++)
513 {
514 glyph = cache_get_font(font, text[i]);
515
516 if (!(flags & TEXT2_IMPLICIT_X))
517 x += text[++i];
518
519 if (glyph != NULL)
520 {
521 ui_draw_glyph(mixmode, x,
522 y + (short)glyph->baseline,
523 glyph->width, glyph->height,
524 glyph->pixmap, 0, 0,
525 bgcolour, fgcolour);
526
527 if (flags & TEXT2_IMPLICIT_X)
528 x += glyph->width;
529 }
530 }
531 }
532
533 void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
534 {
535 XImage *image;
536
537 image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap);
538 cache_put_desktop(offset, cx, cy, image->bytes_per_line, image->data);
539 XFree(image->data);
540 XFree(image);
541 }
542
543 void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
544 {
545 XImage *image;
546 uint8 *data;
547
548 data = cache_get_desktop(offset, cx, cy);
549 if (data == NULL)
550 return;
551
552 image = XCreateImage(display, visual, 8, ZPixmap, 0,
553 data, cx, cy, 32, cx);
554 XSetFunction(display, gc, GXcopy);
555 XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
556 XFree(image);
557 }

  ViewVC Help
Powered by ViewVC 1.1.26