/[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 279 - (hide annotations)
Tue Nov 26 10:09:14 2002 UTC (21 years, 5 months ago) by n-ki
File MIME type: text/plain
File size: 30459 byte(s)
owncolmap reintroduced, basically the same code, but with a switch -C. didn't use the -v switch as in the patches. I believe it is confusing and should be reserved for -version information. Other than that I can say that the code does not work as it does in the patches... haven't found what's wrong with it. bit shifting?

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

  ViewVC Help
Powered by ViewVC 1.1.26