/[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 278 - (hide annotations)
Mon Nov 25 18:23:44 2002 UTC (21 years, 5 months ago) by jsorg71
File MIME type: text/plain
File size: 29473 byte(s)
ui_draw_text optimization from unified patches

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

  ViewVC Help
Powered by ViewVC 1.1.26