/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 16 - (hide annotations)
Thu Sep 28 07:04:14 2000 UTC (23 years, 7 months ago) by matty
File MIME type: text/plain
File size: 12107 byte(s)
Added specific handler for triblt opcode 0x69 (used by Microsoft Word),
and fixed a typo in the default handler.
Fixed implementation of desktop cache code, which was sometimes
overlapping saves.

1 matty 6 /*
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 matty 10 #include <X11/Xlib.h>
22     #include <time.h>
23     #include "rdesktop.h"
24 matty 6
25 matty 10 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 matty 6 {
37 matty 10 Screen *screen;
38 matty 9 XSetWindowAttributes attribs;
39 matty 10 unsigned long input_mask;
40     int i;
41 matty 6
42     display = XOpenDisplay(NULL);
43     if (display == NULL)
44 matty 10 return False;
45 matty 6
46 matty 10 /* 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 matty 9 visual = DefaultVisual(display, DefaultScreen(display));
60 matty 6
61 matty 10 attribs.background_pixel = BlackPixel(display, DefaultScreen(display));
62 matty 9 attribs.backing_store = Always;
63 matty 10 wnd = XCreateWindow(display, DefaultRootWindow(display),
64     0, 0, width, height, 0, 8, InputOutput, visual,
65 matty 9 CWBackingStore | CWBackPixel, &attribs);
66    
67 matty 10 XStoreName(display, wnd, title);
68     XMapWindow(display, wnd);
69 matty 6
70 matty 10 input_mask = KeyPressMask | KeyReleaseMask;
71     input_mask |= ButtonPressMask | ButtonReleaseMask;
72     if (motion)
73     input_mask |= PointerMotionMask;
74 matty 6
75 matty 10 XSelectInput(display, wnd, input_mask);
76     gc = XCreateGC(display, wnd, 0, NULL);
77 matty 7
78 matty 10 IM = XOpenIM(display, NULL, NULL, NULL);
79     return True;
80 matty 6 }
81    
82 matty 10 void ui_destroy_window()
83 matty 6 {
84 matty 10 XCloseIM(IM);
85     XFreeGC(display, gc);
86     XDestroyWindow(display, wnd);
87     XCloseDisplay(display);
88 matty 6 }
89    
90 matty 9 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 matty 10 void ui_process_events()
130 matty 9 {
131     XEvent event;
132     uint8 scancode;
133     uint16 button;
134 matty 10 uint32 ev_time;
135 matty 9
136 matty 10 if (display == NULL)
137 matty 9 return;
138    
139 matty 10 while (XCheckWindowEvent(display, wnd, 0xffffffff, &event))
140 matty 9 {
141 matty 10 ev_time = time(NULL);
142    
143 matty 9 switch (event.type)
144     {
145     case KeyPress:
146     scancode = xwin_translate_key(event.xkey.keycode);
147     if (scancode == 0)
148     break;
149    
150 matty 10 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,
151 matty 9 scancode, 0);
152     break;
153    
154     case KeyRelease:
155     scancode = xwin_translate_key(event.xkey.keycode);
156     if (scancode == 0)
157     break;
158    
159 matty 10 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
160 matty 9 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 matty 10 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
171 matty 9 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 matty 10 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
182 matty 9 button,
183     event.xbutton.x,
184     event.xbutton.y);
185 matty 10 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 matty 9 }
193     }
194     }
195    
196 matty 10 void ui_move_pointer(int x, int y)
197 matty 9 {
198 matty 10 XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
199 matty 9 }
200    
201 matty 10 HBITMAP ui_create_bitmap(int width, int height, uint8 *data)
202 matty 6 {
203     XImage *image;
204 matty 9 Pixmap bitmap;
205 matty 6
206 matty 10 bitmap = XCreatePixmap(display, wnd, width, height, 8);
207 matty 9
208 matty 10 image = XCreateImage(display, visual, 8, ZPixmap, 0,
209 matty 9 data, width, height, 8, width);
210 matty 10 XSetFunction(display, gc, GXcopy);
211     XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
212 matty 9 XFree(image);
213    
214     return (HBITMAP)bitmap;
215 matty 6 }
216    
217 matty 10 void ui_paint_bitmap(int x, int y, int cx, int cy,
218     int width, int height, uint8 *data)
219 matty 6 {
220 matty 10 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 matty 6 }
228    
229 matty 10 void ui_destroy_bitmap(HBITMAP bmp)
230 matty 6 {
231 matty 10 XFreePixmap(display, (Pixmap)bmp);
232     }
233    
234     HGLYPH ui_create_glyph(int width, int height, uint8 *data)
235     {
236 matty 9 XImage *image;
237     Pixmap bitmap;
238     int scanline;
239     GC gc;
240 matty 6
241 matty 9 scanline = (width + 7) / 8;
242 matty 6
243 matty 10 bitmap = XCreatePixmap(display, wnd, width, height, 1);
244     gc = XCreateGC(display, bitmap, 0, NULL);
245 matty 9
246 matty 10 image = XCreateImage(display, visual, 1, ZPixmap, 0,
247 matty 9 data, width, height, 8, scanline);
248 matty 10 XSetFunction(display, gc, GXcopy);
249     XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
250 matty 9 XFree(image);
251 matty 10 XFreeGC(display, gc);
252 matty 9
253     return (HGLYPH)bitmap;
254 matty 6 }
255 matty 7
256 matty 10 void ui_destroy_glyph(HGLYPH glyph)
257 matty 7 {
258 matty 10 XFreePixmap(display, (Pixmap)glyph);
259 matty 9 }
260    
261 matty 10 HCOLOURMAP ui_create_colourmap(COLOURMAP *colours)
262 matty 9 {
263     COLOURENTRY *entry;
264     XColor *xcolours, *xentry;
265 matty 7 Colormap map;
266 matty 9 int i, ncolours = colours->ncolours;
267 matty 7
268 matty 10 xcolours = xmalloc(sizeof(XColor) * ncolours);
269 matty 9 for (i = 0; i < ncolours; i++)
270 matty 7 {
271 matty 9 entry = &colours->colours[i];
272     xentry = &xcolours[i];
273 matty 7
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 matty 10 map = XCreateColormap(display, wnd, visual, AllocAll);
282     XStoreColors(display, map, xcolours, ncolours);
283 matty 7
284 matty 10 xfree(xcolours);
285 matty 9 return (HCOLOURMAP)map;
286 matty 7 }
287    
288 matty 10 void ui_destroy_colourmap(HCOLOURMAP map)
289 matty 7 {
290 matty 10 XFreeColormap(display, (Colormap)map);
291 matty 7 }
292    
293 matty 10 void ui_set_colourmap(HCOLOURMAP map)
294 matty 7 {
295 matty 10 XSetWindowColormap(display, wnd, (Colormap)map);
296 matty 7 }
297    
298 matty 10 void ui_set_clip(int x, int y, int cx, int cy)
299 matty 7 {
300 matty 9 XRectangle rect;
301 matty 7
302 matty 9 rect.x = x;
303     rect.y = y;
304     rect.width = cx;
305     rect.height = cy;
306 matty 10 XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
307 matty 9 }
308 matty 7
309 matty 10 void ui_reset_clip()
310 matty 9 {
311     XRectangle rect;
312    
313     rect.x = 0;
314     rect.y = 0;
315 matty 10 rect.width = width;
316     rect.height = height;
317     XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
318 matty 7 }
319    
320 matty 10 void ui_bell()
321     {
322     XBell(display, 0);
323     }
324    
325 matty 9 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 matty 10 static void xwin_set_function(uint8 rop2)
345 matty 7 {
346 matty 10 XSetFunction(display, gc, rop2_map[rop2]);
347 matty 7 }
348 matty 9
349 matty 10 void ui_destblt(uint8 opcode,
350 matty 9 /* dest */ int x, int y, int cx, int cy)
351     {
352 matty 10 xwin_set_function(opcode);
353 matty 9
354 matty 10 XFillRectangle(display, wnd, gc, x, y, cx, cy);
355 matty 9 }
356    
357 matty 10 void ui_patblt(uint8 opcode,
358 matty 9 /* dest */ int x, int y, int cx, int cy,
359     /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
360     {
361 matty 10 Display *dpy = display;
362 matty 9 Pixmap fill;
363    
364 matty 10 xwin_set_function(opcode);
365 matty 9
366     switch (brush->style)
367     {
368     case 0: /* Solid */
369     XSetForeground(dpy, gc, fgcolour);
370 matty 10 XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
371 matty 9 break;
372    
373     case 3: /* Pattern */
374 matty 10 fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);
375 matty 9
376     XSetForeground(dpy, gc, fgcolour);
377     XSetBackground(dpy, gc, bgcolour);
378     XSetFillStyle(dpy, gc, FillOpaqueStippled);
379     XSetStipple(dpy, gc, fill);
380    
381 matty 10 XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
382 matty 9
383     XSetFillStyle(dpy, gc, FillSolid);
384 matty 10 ui_destroy_glyph((HGLYPH)fill);
385 matty 9 break;
386    
387     default:
388 matty 10 NOTIMP("brush %d\n", brush->style);
389 matty 9 }
390     }
391    
392 matty 10 void ui_screenblt(uint8 opcode,
393 matty 9 /* dest */ int x, int y, int cx, int cy,
394     /* src */ int srcx, int srcy)
395     {
396 matty 10 xwin_set_function(opcode);
397 matty 9
398 matty 10 XCopyArea(display, wnd, wnd, gc, srcx, srcy,
399 matty 9 cx, cy, x, y);
400     }
401    
402 matty 10 void ui_memblt(uint8 opcode,
403 matty 9 /* dest */ int x, int y, int cx, int cy,
404     /* src */ HBITMAP src, int srcx, int srcy)
405     {
406 matty 10 xwin_set_function(opcode);
407 matty 9
408 matty 10 XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy,
409 matty 9 cx, cy, x, y);
410     }
411    
412 matty 10 void ui_triblt(uint8 opcode,
413 matty 9 /* 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 matty 10 comes up with a more efficient way of doing it I am using cases. */
419 matty 9
420     switch (opcode)
421     {
422 matty 16 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 matty 9 case 0xb8: /* PSDPxax */
429 matty 10 ui_patblt(ROP2_XOR, x, y, cx, cy,
430 matty 9 brush, bgcolour, fgcolour);
431 matty 16 ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
432 matty 10 ui_patblt(ROP2_XOR, x, y, cx, cy,
433 matty 9 brush, bgcolour, fgcolour);
434     break;
435    
436     default:
437 matty 10 NOTIMP("triblt 0x%x\n", opcode);
438 matty 16 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
439 matty 9 }
440     }
441    
442 matty 10 void ui_line(uint8 opcode,
443 matty 9 /* dest */ int startx, int starty, int endx, int endy,
444     /* pen */ PEN *pen)
445     {
446 matty 10 xwin_set_function(opcode);
447 matty 9
448 matty 10 XSetForeground(display, gc, pen->colour);
449     XDrawLine(display, wnd, gc, startx, starty, endx, endy);
450 matty 9 }
451    
452 matty 10 void ui_rect(
453 matty 9 /* dest */ int x, int y, int cx, int cy,
454     /* brush */ int colour)
455     {
456 matty 10 xwin_set_function(ROP2_COPY);
457 matty 9
458 matty 10 XSetForeground(display, gc, colour);
459     XFillRectangle(display, wnd, gc, x, y, cx, cy);
460 matty 9 }
461    
462 matty 10 void ui_draw_glyph(int mixmode,
463 matty 9 /* 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 matty 10 xwin_set_function(ROP2_COPY);
469 matty 9
470 matty 10 XSetForeground(display, gc, fgcolour);
471 matty 9
472     switch (mixmode)
473     {
474     case MIX_TRANSPARENT:
475 matty 10 XSetStipple(display, gc, pixmap);
476     XSetFillStyle(display, gc, FillStippled);
477     XSetTSOrigin(display, gc, x, y);
478     XFillRectangle(display, wnd, gc,
479 matty 9 x, y, cx, cy);
480 matty 10 XSetFillStyle(display, gc, FillSolid);
481 matty 9 break;
482    
483     case MIX_OPAQUE:
484 matty 10 XSetBackground(display, gc, bgcolour);
485     XCopyPlane(display, pixmap, wnd, gc,
486 matty 9 srcx, srcy, cx, cy, x, y, 1);
487     break;
488    
489     default:
490 matty 10 NOTIMP("mix %d\n", mixmode);
491 matty 9 }
492     }
493    
494 matty 10 void ui_draw_text(uint8 font, uint8 flags, int mixmode, int x,
495 matty 9 int y, int boxx, int boxy, int boxcx, int boxcy,
496     int bgcolour, int fgcolour, uint8 *text, uint8 length)
497     {
498 matty 10 FONTGLYPH *glyph;
499 matty 9 int i;
500    
501     if (boxcx > 1)
502     {
503 matty 10 ui_rect(boxx, boxy, boxcx, boxcy, bgcolour);
504 matty 9 }
505    
506     /* Paint text, character by character */
507     for (i = 0; i < length; i++)
508     {
509 matty 10 glyph = cache_get_font(font, text[i]);
510 matty 9
511     if (glyph != NULL)
512     {
513 matty 10 ui_draw_glyph(mixmode, x,
514 matty 9 y + (short)glyph->baseline,
515     glyph->width, glyph->height,
516     glyph->pixmap, 0, 0,
517     bgcolour, fgcolour);
518    
519     if (flags & TEXT2_IMPLICIT_X)
520     x += glyph->width;
521     else
522     x += text[++i];
523     }
524     }
525     }
526    
527 matty 10 void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
528 matty 9 {
529     XImage *image;
530    
531 matty 10 image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap);
532 matty 16 cache_put_desktop(offset, cx, cy, image->bytes_per_line, image->data);
533 matty 10 XFree(image->data);
534     XFree(image);
535 matty 9 }
536    
537 matty 10 void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
538 matty 9 {
539     XImage *image;
540 matty 10 uint8 *data;
541 matty 9
542 matty 16 data = cache_get_desktop(offset, cx, cy);
543 matty 10 if (data == NULL)
544     return;
545    
546     image = XCreateImage(display, visual, 8, ZPixmap, 0,
547 matty 16 data, cx, cy, 32, cx);
548 matty 10 XSetFunction(display, gc, GXcopy);
549     XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
550 matty 9 XFree(image);
551     }

  ViewVC Help
Powered by ViewVC 1.1.26