/[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 64 - (hide annotations)
Thu Jul 18 16:38:31 2002 UTC (21 years, 10 months ago) by astrand
File MIME type: text/plain
File size: 29146 byte(s)
Fixed indentation with indent

1 matty 6 /*
2     rdesktop: A Remote Desktop Protocol client.
3 matthewc 38 User interface services - X Window System
4 matty 30 Copyright (C) Matthew Chapman 1999-2001
5 n-ki 52
6 matty 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 n-ki 52
11 matty 6 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 n-ki 52
16 matty 6 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 matty 28 #include <X11/Xutil.h>
23 n-ki 52 #include <X11/XKBlib.h>
24 matty 10 #include <time.h>
25 matty 33 #include <errno.h>
26 matty 10 #include "rdesktop.h"
27 matty 6
28 matthewc 38 extern char keymapname[16];
29     extern int keylayout;
30 matty 10 extern int width;
31     extern int height;
32 matty 29 extern BOOL sendmotion;
33 matty 28 extern BOOL fullscreen;
34 matty 10
35 matthewc 50 Display *display;
36 n-ki 52 XkbDescPtr xkb;
37 matty 33 static int x_socket;
38 matty 10 static Window wnd;
39     static GC gc;
40     static Visual *visual;
41 matty 29 static int depth;
42     static int bpp;
43    
44 matty 33 /* endianness */
45     static BOOL host_be;
46     static BOOL xserver_be;
47    
48     /* software backing store */
49 matty 31 static BOOL ownbackstore;
50     static Pixmap backstore;
51    
52 n-ki 52 /* needed to keep track of the modifiers */
53 n-ki 54 static unsigned int numlock_modifier_mask = 0;
54 n-ki 52 static unsigned int key_down_state = 0;
55    
56 n-ki 54
57 n-ki 52 #define DShift1Mask (1<<0)
58 n-ki 54 #define DLockMask (1<<1)
59 n-ki 52 #define DControl1Mask (1<<2)
60 n-ki 54 #define DMod1Mask (1<<3)
61     #define DMod2Mask (1<<4)
62     #define DMod3Mask (1<<5)
63     #define DMod4Mask (1<<6)
64     #define DMod5Mask (1<<7)
65     #define DShift2Mask (1<<8)
66     #define DControl2Mask (1<<9)
67     #define DNumLockMask (1<<10)
68 n-ki 52
69 matty 31 #define FILL_RECTANGLE(x,y,cx,cy)\
70     { \
71     XFillRectangle(display, wnd, gc, x, y, cx, cy); \
72     if (ownbackstore) \
73     XFillRectangle(display, backstore, gc, x, y, cx, cy); \
74     }
75    
76 matty 33 /* colour maps */
77 matty 29 static BOOL owncolmap;
78     static Colormap xcolmap;
79     static uint32 white;
80 matty 28 static uint32 *colmap;
81 matty 10
82 matty 33 #define TRANSLATE(col) ( owncolmap ? col : translate_colour(colmap[col]) )
83 matty 29 #define SET_FOREGROUND(col) XSetForeground(display, gc, TRANSLATE(col));
84     #define SET_BACKGROUND(col) XSetBackground(display, gc, TRANSLATE(col));
85 matty 28
86     static int rop2_map[] = {
87     GXclear, /* 0 */
88     GXnor, /* DPon */
89     GXandInverted, /* DPna */
90     GXcopyInverted, /* Pn */
91     GXandReverse, /* PDna */
92     GXinvert, /* Dn */
93     GXxor, /* DPx */
94     GXnand, /* DPan */
95     GXand, /* DPa */
96     GXequiv, /* DPxn */
97     GXnoop, /* D */
98     GXorInverted, /* DPno */
99     GXcopy, /* P */
100     GXorReverse, /* PDno */
101     GXor, /* DPo */
102     GXset /* 1 */
103     };
104    
105 matty 29 #define SET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
106     #define RESET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
107    
108 n-ki 54 void xwin_get_numlock_mask();
109 astrand 64 void xwin_mod_update(uint32 state, uint32 ev_time);
110 n-ki 54 void xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode);
111     void xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode);
112 n-ki 52
113 matty 28 static void
114 astrand 64 translate8(uint8 * data, uint8 * out, uint8 * end)
115 matty 28 {
116 matty 29 while (out < end)
117 astrand 64 *(out++) = (uint8) colmap[*(data++)];
118 matty 29 }
119 matty 28
120 matty 29 static void
121 astrand 64 translate16(uint8 * data, uint16 * out, uint16 * end)
122 matty 29 {
123     while (out < end)
124 astrand 64 *(out++) = (uint16) colmap[*(data++)];
125 matty 29 }
126    
127 matty 33 /* little endian - conversion happens when colourmap is built */
128 matty 29 static void
129 astrand 64 translate24(uint8 * data, uint8 * out, uint8 * end)
130 matty 29 {
131     uint32 value;
132    
133     while (out < end)
134 matty 28 {
135 matty 29 value = colmap[*(data++)];
136     *(out++) = value;
137     *(out++) = value >> 8;
138     *(out++) = value >> 16;
139 matty 28 }
140     }
141    
142     static void
143 astrand 64 translate32(uint8 * data, uint32 * out, uint32 * end)
144 matty 28 {
145 matty 29 while (out < end)
146     *(out++) = colmap[*(data++)];
147 matty 28 }
148    
149 matty 29 static uint8 *
150 astrand 64 translate_image(int width, int height, uint8 * data)
151 matty 28 {
152 astrand 64 int size = width * height * bpp / 8;
153 matty 29 uint8 *out = xmalloc(size);
154     uint8 *end = out + size;
155    
156     switch (bpp)
157     {
158     case 8:
159     translate8(data, out, end);
160     break;
161    
162     case 16:
163 astrand 64 translate16(data, (uint16 *) out, (uint16 *) end);
164 matty 29 break;
165    
166     case 24:
167     translate24(data, out, end);
168     break;
169    
170     case 32:
171 astrand 64 translate32(data, (uint32 *) out, (uint32 *) end);
172 matty 29 break;
173     }
174    
175     return out;
176 matty 28 }
177    
178 matty 35 #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
179     #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }
180     #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
181     x = (x << 16) | (x >> 16); }
182 matty 29
183 matty 33 static uint32
184     translate_colour(uint32 colour)
185     {
186     switch (bpp)
187     {
188     case 16:
189     if (host_be != xserver_be)
190     BSWAP16(colour);
191     break;
192 matty 29
193 matty 33 case 24:
194     if (xserver_be)
195     BSWAP24(colour);
196     break;
197    
198     case 32:
199     if (host_be != xserver_be)
200     BSWAP32(colour);
201     break;
202     }
203    
204     return colour;
205     }
206    
207 matty 25 BOOL
208     ui_create_window(char *title)
209 matty 6 {
210 matty 9 XSetWindowAttributes attribs;
211 matty 28 XClassHint *classhints;
212     XSizeHints *sizehints;
213 matty 10 unsigned long input_mask;
214 matty 28 XPixmapFormatValues *pfm;
215 matty 29 Screen *screen;
216 matty 33 uint16 test;
217 matty 29 int i;
218 astrand 64
219 n-ki 52 int xkb_minor, xkb_major;
220     int xkb_event, xkb_error, xkb_reason;
221 matty 6
222 n-ki 52 /* compare compiletime libs with runtime libs. */
223     xkb_major = XkbMajorVersion;
224     xkb_minor = XkbMinorVersion;
225 astrand 64 if (XkbLibraryVersion(&xkb_major, &xkb_minor) == False)
226 n-ki 52 {
227     error("please re-compile rdesktop\ncompile time version of xkb is not compatible with\nyour runtime version of the library\n");
228     return False;
229     }
230    
231    
232 astrand 64 display =
233     XkbOpenDisplay(NULL, &xkb_event, &xkb_error, &xkb_major,
234     &xkb_minor, &xkb_reason);
235     switch (xkb_reason)
236 n-ki 52 {
237     case XkbOD_BadLibraryVersion:
238     error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n");
239     break;
240     case XkbOD_ConnectionRefused:
241     error("XkbOD_ConnectionRefused\n");
242     break;
243     case XkbOD_BadServerVersion:
244     error("XkbOD_BadServerVersion\n");
245     break;
246     case XkbOD_NonXkbServer:
247     error("XkbOD_NonXkbServer: XKB extension not present in server\nupdate your X server.\n");
248     break;
249     case XkbOD_Success:
250     DEBUG("XkbOD_Success: Connection established with display\n");
251     break;
252     }
253    
254 matty 6 if (display == NULL)
255 matty 21 {
256 matty 30 error("Failed to open display\n");
257 matty 10 return False;
258 matty 21 }
259 matty 6
260 matty 33 x_socket = ConnectionNumber(display);
261 matty 29 screen = DefaultScreenOfDisplay(display);
262     visual = DefaultVisualOfScreen(screen);
263     depth = DefaultDepthOfScreen(screen);
264 astrand 64
265 matty 29 pfm = XListPixmapFormats(display, &i);
266 matty 28 if (pfm != NULL)
267     {
268 matty 29 /* Use maximum bpp for this depth - this is generally
269     desirable, e.g. 24 bits->32 bits. */
270     while (i--)
271 matty 28 {
272 matty 29 if ((pfm[i].depth == depth)
273     && (pfm[i].bits_per_pixel > bpp))
274 matty 28 {
275 matty 29 bpp = pfm[i].bits_per_pixel;
276 matty 28 }
277     }
278     XFree(pfm);
279     }
280 matty 10
281 matty 28 if (bpp < 8)
282 matty 10 {
283 matty 30 error("Less than 8 bpp not currently supported.\n");
284 matty 10 XCloseDisplay(display);
285     return False;
286     }
287    
288 matty 29 if (depth <= 8)
289     owncolmap = True;
290     else
291     xcolmap = DefaultColormapOfScreen(screen);
292 matty 6
293 matty 33 test = 1;
294 astrand 64 host_be = !(BOOL) (*(uint8 *) (&test));
295 matty 33 xserver_be = (ImageByteOrder(display) == MSBFirst);
296    
297 matty 29 white = WhitePixelOfScreen(screen);
298     attribs.background_pixel = BlackPixelOfScreen(screen);
299     attribs.backing_store = DoesBackingStore(screen);
300 matty 28
301 matty 29 if (attribs.backing_store == NotUseful)
302 matty 31 ownbackstore = True;
303 matty 29
304 matty 28 if (fullscreen)
305     {
306     attribs.override_redirect = True;
307 matty 29 width = WidthOfScreen(screen);
308     height = HeightOfScreen(screen);
309 matty 28 }
310     else
311     {
312     attribs.override_redirect = False;
313     }
314    
315 astrand 64 width = (width + 3) & ~3; /* make width a multiple of 32 bits */
316 matty 29
317     wnd = XCreateWindow(display, RootWindowOfScreen(screen),
318 matty 28 0, 0, width, height, 0, CopyFromParent,
319     InputOutput, CopyFromParent,
320     CWBackingStore | CWBackPixel | CWOverrideRedirect,
321     &attribs);
322 matty 9
323 matty 10 XStoreName(display, wnd, title);
324 matty 6
325 matty 28 classhints = XAllocClassHint();
326     if (classhints != NULL)
327     {
328 matty 29 classhints->res_name = classhints->res_class = "rdesktop";
329 matty 28 XSetClassHint(display, wnd, classhints);
330     XFree(classhints);
331     }
332    
333     sizehints = XAllocSizeHints();
334     if (sizehints)
335     {
336 matty 29 sizehints->flags = PMinSize | PMaxSize;
337     sizehints->min_width = sizehints->max_width = width;
338     sizehints->min_height = sizehints->max_height = height;
339 matty 28 XSetWMNormalHints(display, wnd, sizehints);
340     XFree(sizehints);
341     }
342    
343 matthewc 50 xkeymap_init();
344 matthewc 38
345 n-ki 52 input_mask = KeyPressMask | KeyReleaseMask |
346 astrand 64 ButtonPressMask | ButtonReleaseMask |
347     EnterWindowMask | LeaveWindowMask;
348 matty 29 if (sendmotion)
349 matty 10 input_mask |= PointerMotionMask;
350 matty 6
351 matty 31 if (ownbackstore)
352     input_mask |= ExposureMask;
353    
354 matty 10 XSelectInput(display, wnd, input_mask);
355     gc = XCreateGC(display, wnd, 0, NULL);
356 matty 7
357 matty 31 if (ownbackstore)
358     backstore = XCreatePixmap(display, wnd, width, height, depth);
359    
360 matty 28 XMapWindow(display, wnd);
361 n-ki 52
362     /* TODO: error texts... make them friendly. */
363     xkb = XkbGetKeyboard(display, XkbAllComponentsMask, XkbUseCoreKbd);
364 astrand 64 if ((int) xkb == BadAlloc || xkb == NULL)
365     {
366     error("XkbGetKeyboard failed.\n");
367     exit(0);
368     }
369 n-ki 52
370     /* TODO: error texts... make them friendly. */
371 astrand 64 if (XkbSelectEvents
372     (display, xkb->device_spec, XkbAllEventsMask,
373     XkbAllEventsMask) == False)
374 n-ki 52 {
375 astrand 64 error("XkbSelectEvents failed.\n");
376     exit(0);
377 n-ki 52 }
378 astrand 64
379 n-ki 54 xwin_get_numlock_mask();
380 n-ki 52
381 matty 10 return True;
382 matty 6 }
383    
384 matty 25 void
385 n-ki 54 xwin_get_numlock_mask()
386     {
387     KeyCode numlockcode;
388 astrand 64 KeyCode *keycode;
389 n-ki 54 XModifierKeymap *modmap;
390 astrand 64 int i, j;
391 n-ki 54
392     /* Find out if numlock is already defined as a modifier key, and if so where */
393     numlockcode = XKeysymToKeycode(display, 0xFF7F); /* XF_Num_Lock = 0xFF7F */
394 astrand 64 if (numlockcode)
395     {
396 n-ki 54 modmap = XGetModifierMapping(display);
397 astrand 64 if (modmap)
398     {
399 n-ki 54 keycode = modmap->modifiermap;
400     for (i = 0; i < 8; i++)
401 astrand 64 for (j = modmap->max_keypermod; j--;)
402     {
403     if (*keycode == numlockcode)
404     {
405     numlock_modifier_mask =
406     (1 << i);
407 n-ki 54 i = 8;
408     break;
409     }
410     keycode++;
411     }
412 astrand 64 if (!numlock_modifier_mask)
413     {
414     modmap->modifiermap[7 *
415     modmap->max_keypermod] =
416     numlockcode;
417     if (XSetModifierMapping(display, modmap) ==
418     MappingSuccess)
419 n-ki 54 numlock_modifier_mask = (1 << 7);
420     else
421     printf("XSetModifierMapping failed!\n");
422     }
423     XFreeModifiermap(modmap);
424     }
425     }
426    
427     if (!numlock_modifier_mask)
428     printf("WARNING: Failed to get a numlock modifier mapping.\n");
429 astrand 64
430 n-ki 54 }
431    
432     void
433 matty 25 ui_destroy_window()
434 matty 6 {
435 astrand 64 if (xkb != NULL)
436 n-ki 52 XkbFreeKeyboard(xkb, XkbAllControlsMask, True);
437    
438 matty 31 if (ownbackstore)
439     XFreePixmap(display, backstore);
440    
441 matty 10 XFreeGC(display, gc);
442     XDestroyWindow(display, wnd);
443     XCloseDisplay(display);
444 matty 28 display = NULL;
445 matty 6 }
446    
447 matty 33 static void
448     xwin_process_events()
449 matty 9 {
450 n-ki 54 XEvent xevent;
451    
452 matthewc 38 KeySym keysym;
453 matty 9 uint8 scancode;
454 matthewc 50 uint16 button, flags;
455 matty 10 uint32 ev_time;
456 n-ki 52 uint32 tmpmods;
457 matty 9
458 n-ki 54 while (XCheckMaskEvent(display, ~0, &xevent))
459 matty 9 {
460 matty 10 ev_time = time(NULL);
461 matthewc 50 flags = 0;
462 matty 10
463 n-ki 54 switch (xevent.type)
464 matty 9 {
465 matthewc 50 case KeyRelease:
466     flags = KBD_FLAG_DOWN | KBD_FLAG_UP;
467     /* fall through */
468 matty 9 case KeyPress:
469 astrand 64 if (XkbTranslateKeyCode
470     (xkb, xevent.xkey.keycode,
471     xevent.xkey.state, &tmpmods,
472     &keysym) == False)
473 matty 9 break;
474 astrand 64 scancode =
475     xkeymap_translate_key(keysym,
476     xevent.xkey.
477     keycode,
478     &flags);
479 matty 9
480 astrand 64 if (scancode == 0)
481 n-ki 52 break;
482    
483     /* keep track of the modifiers -- needed for stickykeys... */
484 astrand 64 if (xevent.type == KeyPress)
485     xwin_mod_press(xevent.xkey.state,
486     ev_time, scancode);
487 n-ki 52
488 astrand 64 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
489     flags, scancode, 0);
490 n-ki 52
491 astrand 64 if (xevent.type == KeyRelease)
492     xwin_mod_release(xevent.xkey.state,
493     ev_time, scancode);
494 n-ki 52
495 matty 9 break;
496    
497     case ButtonPress:
498 matthewc 50 flags = MOUSE_FLAG_DOWN;
499     /* fall through */
500 matty 9
501     case ButtonRelease:
502 astrand 64 button = xkeymap_translate_button(xevent.
503     xbutton.
504     button);
505 matty 9 if (button == 0)
506     break;
507    
508 matty 10 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
509 matthewc 50 flags | button,
510 n-ki 54 xevent.xbutton.x,
511     xevent.xbutton.y);
512 matty 10 break;
513    
514     case MotionNotify:
515     rdp_send_input(ev_time, RDP_INPUT_MOUSE,
516 matty 24 MOUSE_FLAG_MOVE,
517 n-ki 54 xevent.xmotion.x,
518     xevent.xmotion.y);
519 matty 28 break;
520    
521     case EnterNotify:
522 astrand 64 XGrabKeyboard(display, wnd, True,
523     GrabModeAsync, GrabModeAsync,
524     CurrentTime);
525 n-ki 54
526 astrand 64 xwin_mod_update(xevent.xcrossing.state,
527     ev_time);
528 matty 28 break;
529    
530     case LeaveNotify:
531 matty 29 XUngrabKeyboard(display, CurrentTime);
532 matty 28 break;
533 matty 31
534     case Expose:
535     XCopyArea(display, backstore, wnd, gc,
536 n-ki 54 xevent.xexpose.x, xevent.xexpose.y,
537 astrand 64 xevent.xexpose.width,
538     xevent.xexpose.height,
539 n-ki 54 xevent.xexpose.x, xevent.xexpose.y);
540 matty 31 break;
541 matty 9 }
542     }
543     }
544    
545 matty 25 void
546 astrand 64 xwin_mod_update(uint32 state, uint32 ev_time)
547 n-ki 52 {
548 n-ki 54 xwin_mod_press(state, ev_time, 0);
549     xwin_mod_release(state, ev_time, 0);
550     }
551    
552     void
553     xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode)
554     {
555 astrand 64 switch (scancode)
556     {
557     case 0x2a:
558     key_down_state &= ~DShift1Mask;
559     break;
560     case 0x36:
561     key_down_state &= ~DShift2Mask;
562     break;
563     case 0x1d:
564     key_down_state &= ~DControl1Mask;
565     break;
566     case 0x9d:
567     key_down_state &= ~DControl2Mask;
568     break;
569     case 0x38:
570     key_down_state &= ~DMod1Mask;
571     break;
572     case 0xb8:
573     key_down_state &= ~DMod2Mask;
574     break;
575 n-ki 52 }
576    
577 astrand 64 if (!(numlock_modifier_mask & state)
578     && (key_down_state & DNumLockMask))
579 n-ki 52 {
580 n-ki 54 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);
581 astrand 64 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
582     KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);
583 n-ki 54 key_down_state &= ~DNumLockMask;
584     }
585    
586 astrand 64 if (!(LockMask & state) && (key_down_state & DLockMask))
587 n-ki 54 {
588     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);
589 astrand 64 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
590     KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);
591 n-ki 54 key_down_state &= ~DLockMask;
592    
593     }
594    
595    
596 astrand 64 if (!(ShiftMask & state) && (key_down_state & DShift1Mask))
597 n-ki 54 {
598 astrand 64 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a,
599     0);
600 n-ki 52 key_down_state &= ~DShift1Mask;
601    
602     }
603    
604 astrand 64 if (!(ControlMask & state) && (key_down_state & DControl1Mask))
605 n-ki 52 {
606 astrand 64 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d,
607     0);
608 n-ki 52 key_down_state &= ~DControl1Mask;
609    
610     }
611 n-ki 54
612 astrand 64 if (!(Mod1Mask & state) && (key_down_state & DMod1Mask))
613 n-ki 52 {
614 astrand 64 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38,
615     0);
616 n-ki 52 key_down_state &= ~DMod1Mask;
617    
618     }
619 n-ki 54
620 astrand 64 if (!(Mod2Mask & state) && (key_down_state & DMod2Mask))
621 n-ki 52 {
622 astrand 64 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8,
623     0);
624 n-ki 52 key_down_state &= ~DMod2Mask;
625     }
626     }
627    
628    
629     void
630 n-ki 54 xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode)
631 n-ki 52 {
632    
633 astrand 64 switch (scancode)
634     {
635     case 0x2a:
636     key_down_state |= DShift1Mask;
637     break;
638     case 0x36:
639     key_down_state |= DShift2Mask;
640     break;
641     case 0x1d:
642     key_down_state |= DControl1Mask;
643     break;
644     case 0x9d:
645     key_down_state |= DControl2Mask;
646     break;
647     case 0x3a:
648     key_down_state ^= DLockMask;
649     break;
650     case 0x45:
651     key_down_state ^= DNumLockMask;
652     break;
653     case 0x38:
654     key_down_state |= DMod1Mask;
655     break;
656     case 0xb8:
657     key_down_state |= DMod2Mask;
658     break;
659 n-ki 52 }
660    
661 astrand 64 if ((numlock_modifier_mask && state)
662     && !(key_down_state & DNumLockMask))
663 n-ki 52 {
664 n-ki 54 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);
665 astrand 64 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
666     KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);
667 n-ki 54 key_down_state |= DNumLockMask;
668     }
669    
670 astrand 64 if ((LockMask & state) && !(key_down_state & DLockMask))
671 n-ki 54 {
672     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);
673 astrand 64 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
674     KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);
675 n-ki 54 key_down_state |= DLockMask;
676    
677     }
678    
679    
680 astrand 64 if ((ShiftMask & state)
681     && !((key_down_state & DShift1Mask)
682     || (key_down_state & DShift2Mask)))
683 n-ki 54 {
684 astrand 64 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,
685     0x2a, 0);
686 n-ki 52 key_down_state |= DShift1Mask;
687    
688     }
689    
690 astrand 64 if ((ControlMask & state)
691     && !((key_down_state & DControl1Mask)
692     || (key_down_state & DControl2Mask)))
693 n-ki 52 {
694 astrand 64 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,
695     0x1d, 0);
696 n-ki 52 key_down_state |= DControl1Mask;
697    
698     }
699    
700 astrand 64 if ((Mod1Mask & state) && !(key_down_state & DMod1Mask))
701 n-ki 52 {
702 astrand 64 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,
703     0x38, 0);
704 n-ki 52 key_down_state |= DMod1Mask;
705    
706     }
707    
708 astrand 64 if ((Mod2Mask & state) && !(key_down_state & DMod2Mask))
709 n-ki 52 {
710 astrand 64 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,
711     0xb8, 0);
712 n-ki 52 key_down_state |= DMod2Mask;
713    
714     }
715     }
716    
717     void
718 matty 33 ui_select(int rdp_socket)
719     {
720 astrand 64 int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
721 matty 33 fd_set rfds;
722    
723     FD_ZERO(&rfds);
724    
725     while (True)
726     {
727     FD_ZERO(&rfds);
728     FD_SET(rdp_socket, &rfds);
729 matthewc 53 if (display != NULL)
730     {
731     FD_SET(x_socket, &rfds);
732     XFlush(display);
733     }
734 matty 33
735     switch (select(n, &rfds, NULL, NULL, NULL))
736     {
737     case -1:
738     error("select: %s\n", strerror(errno));
739    
740     case 0:
741     continue;
742     }
743    
744     if (FD_ISSET(x_socket, &rfds))
745     xwin_process_events();
746    
747     if (FD_ISSET(rdp_socket, &rfds))
748     return;
749     }
750     }
751    
752     void
753 matty 25 ui_move_pointer(int x, int y)
754 matty 9 {
755 matty 10 XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
756 matty 9 }
757    
758 matty 25 HBITMAP
759 astrand 64 ui_create_bitmap(int width, int height, uint8 * data)
760 matty 6 {
761     XImage *image;
762 matty 9 Pixmap bitmap;
763 matty 28 uint8 *tdata;
764 matty 29
765 matty 33 tdata = (owncolmap ? data : translate_image(width, height, data));
766 matty 28 bitmap = XCreatePixmap(display, wnd, width, height, depth);
767 matty 29 image = XCreateImage(display, visual, depth, ZPixmap,
768     0, tdata, width, height, 8, 0);
769 matty 6
770 matty 28 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
771 matty 9
772     XFree(image);
773 matty 29 if (!owncolmap)
774 matty 28 xfree(tdata);
775 matty 24 return (HBITMAP) bitmap;
776 matty 6 }
777    
778 matty 25 void
779     ui_paint_bitmap(int x, int y, int cx, int cy,
780 astrand 64 int width, int height, uint8 * data)
781 matty 6 {
782 matty 10 XImage *image;
783 matty 29 uint8 *tdata;
784 matty 10
785 matty 33 tdata = (owncolmap ? data : translate_image(width, height, data));
786 matty 29 image = XCreateImage(display, visual, depth, ZPixmap,
787     0, tdata, width, height, 8, 0);
788 matty 28
789 matty 31 if (ownbackstore)
790     {
791     XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
792     XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
793     }
794     else
795     {
796     XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
797     }
798 matty 29
799 matty 24 XFree(image);
800 matty 29 if (!owncolmap)
801 matty 28 xfree(tdata);
802 matty 6 }
803    
804 matty 25 void
805     ui_destroy_bitmap(HBITMAP bmp)
806 matty 6 {
807 astrand 64 XFreePixmap(display, (Pixmap) bmp);
808 matty 10 }
809    
810 matty 25 HGLYPH
811 astrand 64 ui_create_glyph(int width, int height, uint8 * data)
812 matty 10 {
813 matty 9 XImage *image;
814     Pixmap bitmap;
815     int scanline;
816     GC gc;
817 matty 6
818 matty 9 scanline = (width + 7) / 8;
819 matty 6
820 matty 10 bitmap = XCreatePixmap(display, wnd, width, height, 1);
821     gc = XCreateGC(display, bitmap, 0, NULL);
822 matty 9
823 matty 10 image = XCreateImage(display, visual, 1, ZPixmap, 0,
824 matty 24 data, width, height, 8, scanline);
825 matty 23 image->byte_order = MSBFirst;
826     image->bitmap_bit_order = MSBFirst;
827     XInitImage(image);
828    
829 matty 10 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
830 matty 29
831 matty 9 XFree(image);
832 matty 10 XFreeGC(display, gc);
833 astrand 64 return (HGLYPH) bitmap;
834 matty 6 }
835 matty 7
836 matty 25 void
837     ui_destroy_glyph(HGLYPH glyph)
838 matty 7 {
839 astrand 64 XFreePixmap(display, (Pixmap) glyph);
840 matty 9 }
841    
842 matty 29 HCURSOR
843     ui_create_cursor(unsigned int x, unsigned int y, int width,
844 astrand 64 int height, uint8 * andmask, uint8 * xormask)
845 matty 9 {
846 matty 29 HGLYPH maskglyph, cursorglyph;
847     XColor bg, fg;
848     Cursor xcursor;
849     uint8 *cursor, *pcursor;
850     uint8 *mask, *pmask;
851     uint8 nextbit;
852     int scanline, offset;
853     int i, j;
854    
855     scanline = (width + 7) / 8;
856     offset = scanline * height;
857    
858     cursor = xmalloc(offset);
859     memset(cursor, 0, offset);
860    
861     mask = xmalloc(offset);
862     memset(mask, 0, offset);
863    
864     /* approximate AND and XOR masks with a monochrome X pointer */
865     for (i = 0; i < height; i++)
866 matty 7 {
867 matty 29 offset -= scanline;
868     pcursor = &cursor[offset];
869     pmask = &mask[offset];
870    
871     for (j = 0; j < scanline; j++)
872 matty 28 {
873 matty 29 for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
874     {
875     if (xormask[0] || xormask[1] || xormask[2])
876     {
877     *pcursor |= (~(*andmask) & nextbit);
878     *pmask |= nextbit;
879     }
880     else
881     {
882     *pcursor |= ((*andmask) & nextbit);
883     *pmask |= (~(*andmask) & nextbit);
884     }
885    
886     xormask += 3;
887     }
888    
889     andmask++;
890     pcursor++;
891     pmask++;
892 matty 28 }
893 matty 7 }
894 matty 29
895     fg.red = fg.blue = fg.green = 0xffff;
896     bg.red = bg.blue = bg.green = 0x0000;
897     fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
898    
899     cursorglyph = ui_create_glyph(width, height, cursor);
900     maskglyph = ui_create_glyph(width, height, mask);
901    
902 astrand 64 xcursor = XCreatePixmapCursor(display, (Pixmap) cursorglyph,
903     (Pixmap) maskglyph, &fg, &bg, x, y);
904    
905 matty 29 ui_destroy_glyph(maskglyph);
906     ui_destroy_glyph(cursorglyph);
907     xfree(mask);
908     xfree(cursor);
909 astrand 64 return (HCURSOR) xcursor;
910 matty 29 }
911    
912     void
913     ui_set_cursor(HCURSOR cursor)
914     {
915 astrand 64 XDefineCursor(display, wnd, (Cursor) cursor);
916 matty 29 }
917    
918     void
919     ui_destroy_cursor(HCURSOR cursor)
920     {
921 astrand 64 XFreeCursor(display, (Cursor) cursor);
922 matty 29 }
923    
924     #define MAKE_XCOLOR(xc,c) \
925     (xc)->red = ((c)->red << 8) | (c)->red; \
926     (xc)->green = ((c)->green << 8) | (c)->green; \
927     (xc)->blue = ((c)->blue << 8) | (c)->blue; \
928     (xc)->flags = DoRed | DoGreen | DoBlue;
929    
930     HCOLOURMAP
931 astrand 64 ui_create_colourmap(COLOURMAP * colours)
932 matty 29 {
933     COLOURENTRY *entry;
934     int i, ncolours = colours->ncolours;
935    
936     if (owncolmap)
937 matty 28 {
938     XColor *xcolours, *xentry;
939     Colormap map;
940 matty 29
941 matty 28 xcolours = xmalloc(sizeof(XColor) * ncolours);
942     for (i = 0; i < ncolours; i++)
943     {
944     entry = &colours->colours[i];
945     xentry = &xcolours[i];
946     xentry->pixel = i;
947 matty 29 MAKE_XCOLOR(xentry, entry);
948 matty 28 }
949 matty 7
950 matty 28 map = XCreateColormap(display, wnd, visual, AllocAll);
951     XStoreColors(display, map, xcolours, ncolours);
952    
953     xfree(xcolours);
954 astrand 64 return (HCOLOURMAP) map;
955 matty 28 }
956 matty 29 else
957     {
958     uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
959     XColor xentry;
960 matty 33 uint32 colour;
961 matty 29
962     for (i = 0; i < ncolours; i++)
963     {
964     entry = &colours->colours[i];
965     MAKE_XCOLOR(&xentry, entry);
966    
967     if (XAllocColor(display, xcolmap, &xentry) != 0)
968 matty 34 colour = xentry.pixel;
969 matty 29 else
970 matty 34 colour = white;
971 matty 33
972     /* byte swap here to make translate_image faster */
973     map[i] = translate_colour(colour);
974 matty 29 }
975    
976     return map;
977     }
978 matty 7 }
979    
980 matty 25 void
981     ui_destroy_colourmap(HCOLOURMAP map)
982 matty 7 {
983 matty 29 if (owncolmap)
984 astrand 64 XFreeColormap(display, (Colormap) map);
985 matty 29 else
986     xfree(map);
987 matty 7 }
988    
989 matty 25 void
990     ui_set_colourmap(HCOLOURMAP map)
991 matty 7 {
992 matty 29 if (owncolmap)
993 astrand 64 XSetWindowColormap(display, wnd, (Colormap) map);
994 matty 29 else
995 matty 28 colmap = map;
996 matty 7 }
997    
998 matty 25 void
999     ui_set_clip(int x, int y, int cx, int cy)
1000 matty 7 {
1001 matty 9 XRectangle rect;
1002 matty 7
1003 matty 9 rect.x = x;
1004     rect.y = y;
1005     rect.width = cx;
1006     rect.height = cy;
1007 matty 10 XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
1008 matty 9 }
1009 matty 7
1010 matty 25 void
1011     ui_reset_clip()
1012 matty 9 {
1013     XRectangle rect;
1014    
1015     rect.x = 0;
1016     rect.y = 0;
1017 matty 10 rect.width = width;
1018     rect.height = height;
1019     XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
1020 matty 7 }
1021    
1022 matty 25 void
1023     ui_bell()
1024 matty 10 {
1025     XBell(display, 0);
1026     }
1027    
1028 matty 25 void
1029     ui_destblt(uint8 opcode,
1030     /* dest */ int x, int y, int cx, int cy)
1031 matty 9 {
1032 matty 29 SET_FUNCTION(opcode);
1033 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1034 matty 29 RESET_FUNCTION(opcode);
1035 matty 9 }
1036    
1037 matty 25 void
1038     ui_patblt(uint8 opcode,
1039     /* dest */ int x, int y, int cx, int cy,
1040 astrand 64 /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1041 matty 9 {
1042     Pixmap fill;
1043 jsorg71 59 uint8 i, ipattern[8];
1044 matty 9
1045 matty 29 SET_FUNCTION(opcode);
1046 matty 9
1047     switch (brush->style)
1048     {
1049 matty 24 case 0: /* Solid */
1050 matty 29 SET_FOREGROUND(fgcolour);
1051 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1052 matty 9 break;
1053    
1054 matty 24 case 3: /* Pattern */
1055 jsorg71 59 for (i = 0; i != 8; i++)
1056     ipattern[7 - i] = brush->pattern[i];
1057     fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
1058 matty 9
1059 matty 29 SET_FOREGROUND(bgcolour);
1060     SET_BACKGROUND(fgcolour);
1061     XSetFillStyle(display, gc, FillOpaqueStippled);
1062     XSetStipple(display, gc, fill);
1063 astrand 64 XSetTSOrigin(display, gc, brush->xorigin,
1064     brush->yorigin);
1065 matty 9
1066 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1067 matty 9
1068 matty 29 XSetFillStyle(display, gc, FillSolid);
1069 astrand 64 ui_destroy_glyph((HGLYPH) fill);
1070 matty 9 break;
1071    
1072     default:
1073 matty 30 unimpl("brush %d\n", brush->style);
1074 matty 9 }
1075 matty 29
1076     RESET_FUNCTION(opcode);
1077 matty 9 }
1078    
1079 matty 25 void
1080     ui_screenblt(uint8 opcode,
1081     /* dest */ int x, int y, int cx, int cy,
1082     /* src */ int srcx, int srcy)
1083 matty 9 {
1084 matty 29 SET_FUNCTION(opcode);
1085 matty 24 XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1086 matty 31 if (ownbackstore)
1087     XCopyArea(display, backstore, backstore, gc, srcx, srcy,
1088     cx, cy, x, y);
1089 matty 29 RESET_FUNCTION(opcode);
1090 matty 9 }
1091    
1092 matty 25 void
1093     ui_memblt(uint8 opcode,
1094     /* dest */ int x, int y, int cx, int cy,
1095     /* src */ HBITMAP src, int srcx, int srcy)
1096 matty 9 {
1097 matty 29 SET_FUNCTION(opcode);
1098 astrand 64 XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1099 matty 31 if (ownbackstore)
1100 astrand 64 XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy,
1101 matty 31 cx, cy, x, y);
1102 matty 29 RESET_FUNCTION(opcode);
1103 matty 9 }
1104    
1105 matty 25 void
1106     ui_triblt(uint8 opcode,
1107     /* dest */ int x, int y, int cx, int cy,
1108     /* src */ HBITMAP src, int srcx, int srcy,
1109 astrand 64 /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1110 matty 9 {
1111     /* This is potentially difficult to do in general. Until someone
1112 matty 10 comes up with a more efficient way of doing it I am using cases. */
1113 matty 9
1114     switch (opcode)
1115     {
1116 matty 24 case 0x69: /* PDSxxn */
1117 matty 16 ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1118     ui_patblt(ROP2_NXOR, x, y, cx, cy,
1119 matty 24 brush, bgcolour, fgcolour);
1120 matty 16 break;
1121    
1122 matty 24 case 0xb8: /* PSDPxax */
1123 matty 10 ui_patblt(ROP2_XOR, x, y, cx, cy,
1124 matty 24 brush, bgcolour, fgcolour);
1125 matty 16 ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1126 matty 10 ui_patblt(ROP2_XOR, x, y, cx, cy,
1127 matty 24 brush, bgcolour, fgcolour);
1128 matty 9 break;
1129    
1130 matty 29 case 0xc0: /* PSa */
1131 matty 28 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1132     ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,
1133     fgcolour);
1134     break;
1135    
1136 matty 9 default:
1137 matty 30 unimpl("triblt 0x%x\n", opcode);
1138 matty 16 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1139 matty 9 }
1140     }
1141    
1142 matty 25 void
1143     ui_line(uint8 opcode,
1144     /* dest */ int startx, int starty, int endx, int endy,
1145 astrand 64 /* pen */ PEN * pen)
1146 matty 9 {
1147 matty 29 SET_FUNCTION(opcode);
1148     SET_FOREGROUND(pen->colour);
1149 matty 10 XDrawLine(display, wnd, gc, startx, starty, endx, endy);
1150 matty 31 if (ownbackstore)
1151     XDrawLine(display, backstore, gc, startx, starty, endx, endy);
1152 matty 29 RESET_FUNCTION(opcode);
1153 matty 9 }
1154    
1155 matty 25 void
1156     ui_rect(
1157     /* dest */ int x, int y, int cx, int cy,
1158     /* brush */ int colour)
1159 matty 9 {
1160 matty 29 SET_FOREGROUND(colour);
1161 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1162 matty 9 }
1163    
1164 matty 25 void
1165     ui_draw_glyph(int mixmode,
1166     /* dest */ int x, int y, int cx, int cy,
1167     /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,
1168     int fgcolour)
1169 matty 9 {
1170 matty 29 SET_FOREGROUND(fgcolour);
1171     SET_BACKGROUND(bgcolour);
1172 matty 9
1173 matty 29 XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)
1174     ? FillStippled : FillOpaqueStippled);
1175 astrand 64 XSetStipple(display, gc, (Pixmap) glyph);
1176 matty 29 XSetTSOrigin(display, gc, x, y);
1177 matty 9
1178 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1179 matty 9
1180 matty 29 XSetFillStyle(display, gc, FillSolid);
1181 matty 9 }
1182    
1183 mmihalik 49 #define DO_GLYPH(ttext,idx) \
1184     {\
1185     glyph = cache_get_font (font, ttext[idx]);\
1186     if (!(flags & TEXT2_IMPLICIT_X))\
1187     {\
1188     xyoffset = ttext[++idx];\
1189     if ((xyoffset & 0x80))\
1190     {\
1191     if (flags & TEXT2_VERTICAL) \
1192     y += ttext[++idx] | (ttext[++idx] << 8);\
1193     else\
1194     x += ttext[++idx] | (ttext[++idx] << 8);\
1195     }\
1196     else\
1197     {\
1198     if (flags & TEXT2_VERTICAL) \
1199     y += xyoffset;\
1200     else\
1201     x += xyoffset;\
1202     }\
1203     }\
1204     if (glyph != NULL)\
1205     {\
1206     ui_draw_glyph (mixmode, x + (short) glyph->offset,\
1207     y + (short) glyph->baseline,\
1208     glyph->width, glyph->height,\
1209     glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1210     if (flags & TEXT2_IMPLICIT_X)\
1211     x += glyph->width;\
1212     }\
1213     }
1214    
1215 matty 25 void
1216     ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
1217 mmihalik 49 int clipx, int clipy, int clipcx, int clipcy, int boxx,
1218     int boxy, int boxcx, int boxcy, int bgcolour,
1219     int fgcolour, uint8 * text, uint8 length)
1220 matty 9 {
1221 matty 10 FONTGLYPH *glyph;
1222 mmihalik 49 int i, j, xyoffset;
1223     DATABLOB *entry;
1224 matty 9
1225 matty 29 SET_FOREGROUND(bgcolour);
1226 matty 28
1227 matty 9 if (boxcx > 1)
1228 matty 31 {
1229     FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);
1230     }
1231 matty 17 else if (mixmode == MIX_OPAQUE)
1232 matty 31 {
1233     FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
1234     }
1235 matty 9
1236     /* Paint text, character by character */
1237 astrand 64 for (i = 0; i < length;)
1238     {
1239     switch (text[i])
1240     {
1241     case 0xff:
1242     if (i + 2 < length)
1243     cache_put_text(text[i + 1], text,
1244     text[i + 2]);
1245     else
1246     {
1247     error("this shouldn't be happening\n");
1248     break;
1249     }
1250     /* this will move pointer from start to first character after FF command */
1251     length -= i + 3;
1252     text = &(text[i + 3]);
1253     i = 0;
1254 mmihalik 49 break;
1255 matty 9
1256 astrand 64 case 0xfe:
1257     entry = cache_get_text(text[i + 1]);
1258     if (entry != NULL)
1259     {
1260     if ((((uint8 *) (entry->data))[1] ==
1261     0)
1262     && (!(flags & TEXT2_IMPLICIT_X)))
1263     {
1264     if (flags & TEXT2_VERTICAL)
1265     y += text[i + 2];
1266     else
1267     x += text[i + 2];
1268     }
1269     if (i + 2 < length)
1270     i += 3;
1271 mmihalik 49 else
1272 astrand 64 i += 2;
1273     length -= i;
1274     /* this will move pointer from start to first character after FE command */
1275     text = &(text[i]);
1276     i = 0;
1277     for (j = 0; j < entry->size; j++)
1278     DO_GLYPH(((uint8 *) (entry->
1279     data)),
1280     j);
1281 matthewc 44 }
1282 astrand 64 break;
1283 matty 17
1284 astrand 64 default:
1285     DO_GLYPH(text, i);
1286     i++;
1287     break;
1288 matty 29 }
1289 mmihalik 49 }
1290 matty 28
1291 matty 9
1292     }
1293    
1294 matty 25 void
1295     ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
1296 matty 9 {
1297 matty 28 Pixmap pix;
1298 matty 9 XImage *image;
1299    
1300 matty 31 if (ownbackstore)
1301     {
1302     image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,
1303     ZPixmap);
1304     }
1305     else
1306     {
1307     pix = XCreatePixmap(display, wnd, cx, cy, depth);
1308     XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1309     image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,
1310     ZPixmap);
1311     XFreePixmap(display, pix);
1312     }
1313 matty 28
1314 astrand 64 offset *= bpp / 8;
1315 matty 28 cache_put_desktop(offset, cx, cy, image->bytes_per_line,
1316 astrand 64 bpp / 8, (uint8 *) image->data);
1317 matty 28
1318     XDestroyImage(image);
1319 matty 9 }
1320    
1321 matty 25 void
1322     ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
1323 matty 9 {
1324     XImage *image;
1325 matty 10 uint8 *data;
1326 matty 9
1327 astrand 64 offset *= bpp / 8;
1328     data = cache_get_desktop(offset, cx, cy, bpp / 8);
1329 matty 10 if (data == NULL)
1330     return;
1331 matty 29
1332     image = XCreateImage(display, visual, depth, ZPixmap,
1333 matty 28 0, data, cx, cy, BitmapPad(display),
1334 astrand 64 cx * bpp / 8);
1335 matty 29
1336 matty 31 if (ownbackstore)
1337     {
1338     XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
1339     XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
1340     }
1341     else
1342     {
1343     XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
1344     }
1345    
1346 matty 9 XFree(image);
1347     }

  ViewVC Help
Powered by ViewVC 1.1.26