/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 299 - (hide annotations)
Thu Jan 30 11:15:00 2003 UTC (21 years, 3 months ago) by matthewc
Original Path: sourceforge.net/trunk/rdesktop/xwin.c
File MIME type: text/plain
File size: 30584 byte(s)
Add some signed types and use them in the places we have silly casts now.

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 matthewc 296 #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\
82 jsorg71 281 { \
83     XFillRectangle(display, ownbackstore ? backstore : wnd, gc, x, y, cx, cy); \
84     }
85    
86 matty 33 /* colour maps */
87 n-ki 279 BOOL owncolmap = False;
88 matty 29 static Colormap xcolmap;
89 matty 28 static uint32 *colmap;
90 matty 10
91 n-ki 279 #define TRANSLATE(col) ( owncolmap ? col : translate_colour(colmap[col]) )
92     #define SET_FOREGROUND(col) XSetForeground(display, gc, TRANSLATE(col));
93     #define SET_BACKGROUND(col) XSetBackground(display, gc, TRANSLATE(col));
94 matty 28
95     static int rop2_map[] = {
96     GXclear, /* 0 */
97     GXnor, /* DPon */
98     GXandInverted, /* DPna */
99     GXcopyInverted, /* Pn */
100     GXandReverse, /* PDna */
101     GXinvert, /* Dn */
102     GXxor, /* DPx */
103     GXnand, /* DPan */
104     GXand, /* DPa */
105     GXequiv, /* DPxn */
106     GXnoop, /* D */
107     GXorInverted, /* DPno */
108     GXcopy, /* P */
109     GXorReverse, /* PDno */
110     GXor, /* DPo */
111     GXset /* 1 */
112     };
113    
114 matty 29 #define SET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
115     #define RESET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
116    
117 astrand 262 void
118     mwm_hide_decorations(void)
119     {
120     PropMotifWmHints motif_hints;
121     Atom hintsatom;
122    
123     /* setup the property */
124     motif_hints.flags = MWM_HINTS_DECORATIONS;
125     motif_hints.decorations = 0;
126    
127     /* get the atom for the property */
128     hintsatom = XInternAtom(display, "_MOTIF_WM_HINTS", False);
129     if (!hintsatom)
130     {
131 matthewc 297 warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");
132 astrand 262 return;
133     }
134    
135     XChangeProperty(display, wnd, hintsatom, hintsatom, 32, PropModeReplace,
136     (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
137     }
138    
139 matty 28 static void
140 astrand 64 translate8(uint8 * data, uint8 * out, uint8 * end)
141 matty 28 {
142 matty 29 while (out < end)
143 astrand 64 *(out++) = (uint8) colmap[*(data++)];
144 matty 29 }
145 matty 28
146 matty 29 static void
147 astrand 64 translate16(uint8 * data, uint16 * out, uint16 * end)
148 matty 29 {
149     while (out < end)
150 astrand 64 *(out++) = (uint16) colmap[*(data++)];
151 matty 29 }
152    
153 matty 33 /* little endian - conversion happens when colourmap is built */
154 matty 29 static void
155 astrand 64 translate24(uint8 * data, uint8 * out, uint8 * end)
156 matty 29 {
157     uint32 value;
158    
159     while (out < end)
160 matty 28 {
161 matty 29 value = colmap[*(data++)];
162     *(out++) = value;
163     *(out++) = value >> 8;
164     *(out++) = value >> 16;
165 matty 28 }
166     }
167    
168     static void
169 astrand 64 translate32(uint8 * data, uint32 * out, uint32 * end)
170 matty 28 {
171 matty 29 while (out < end)
172     *(out++) = colmap[*(data++)];
173 matty 28 }
174    
175 matty 29 static uint8 *
176 astrand 64 translate_image(int width, int height, uint8 * data)
177 matty 28 {
178 astrand 64 int size = width * height * bpp / 8;
179 matty 29 uint8 *out = xmalloc(size);
180     uint8 *end = out + size;
181    
182     switch (bpp)
183     {
184     case 8:
185     translate8(data, out, end);
186     break;
187    
188     case 16:
189 astrand 64 translate16(data, (uint16 *) out, (uint16 *) end);
190 matty 29 break;
191    
192     case 24:
193     translate24(data, out, end);
194     break;
195    
196     case 32:
197 astrand 64 translate32(data, (uint32 *) out, (uint32 *) end);
198 matty 29 break;
199     }
200    
201     return out;
202 matty 28 }
203    
204 matty 35 #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
205     #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }
206     #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
207     x = (x << 16) | (x >> 16); }
208 matty 29
209 matty 33 static uint32
210     translate_colour(uint32 colour)
211     {
212     switch (bpp)
213     {
214     case 16:
215     if (host_be != xserver_be)
216     BSWAP16(colour);
217     break;
218 matty 29
219 matty 33 case 24:
220     if (xserver_be)
221     BSWAP24(colour);
222     break;
223    
224     case 32:
225     if (host_be != xserver_be)
226     BSWAP32(colour);
227     break;
228     }
229    
230     return colour;
231     }
232    
233 astrand 118 BOOL
234 matthewc 209 get_key_state(unsigned int state, uint32 keysym)
235 astrand 102 {
236 matthewc 203 int modifierpos, key, keysymMask = 0;
237 astrand 102 int offset;
238    
239     KeyCode keycode = XKeysymToKeycode(display, keysym);
240    
241     if (keycode == NoSymbol)
242     return False;
243    
244     for (modifierpos = 0; modifierpos < 8; modifierpos++)
245     {
246 matthewc 203 offset = mod_map->max_keypermod * modifierpos;
247 astrand 102
248 matthewc 203 for (key = 0; key < mod_map->max_keypermod; key++)
249 astrand 102 {
250 matthewc 203 if (mod_map->modifiermap[offset + key] == keycode)
251     keysymMask |= 1 << modifierpos;
252 astrand 102 }
253     }
254    
255 matthewc 203 return (state & keysymMask) ? True : False;
256 astrand 102 }
257    
258 jsorg71 81 BOOL
259 matthewc 192 ui_init(void)
260 jsorg71 81 {
261 matthewc 121 XPixmapFormatValues *pfm;
262     uint16 test;
263     int i;
264    
265 jsorg71 81 display = XOpenDisplay(NULL);
266     if (display == NULL)
267     {
268 matthewc 210 error("Failed to open display: %s\n", XDisplayName(NULL));
269 jsorg71 81 return False;
270     }
271 matthewc 121
272     x_socket = ConnectionNumber(display);
273     screen = DefaultScreenOfDisplay(display);
274     visual = DefaultVisualOfScreen(screen);
275     depth = DefaultDepthOfScreen(screen);
276    
277     pfm = XListPixmapFormats(display, &i);
278     if (pfm != NULL)
279     {
280     /* Use maximum bpp for this depth - this is generally
281     desirable, e.g. 24 bits->32 bits. */
282     while (i--)
283     {
284     if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))
285     {
286     bpp = pfm[i].bits_per_pixel;
287     }
288     }
289     XFree(pfm);
290     }
291    
292     if (bpp < 8)
293     {
294     error("Less than 8 bpp not currently supported.\n");
295     XCloseDisplay(display);
296     return False;
297     }
298    
299 n-ki 279 if (owncolmap != True)
300     {
301     xcolmap = DefaultColormapOfScreen(screen);
302     if (depth <= 8)
303 matthewc 297 warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");
304 n-ki 279 }
305    
306 matthewc 188 gc = XCreateGC(display, RootWindowOfScreen(screen), 0, NULL);
307 matthewc 121
308 matthewc 188 if (DoesBackingStore(screen) != Always)
309 matthewc 121 ownbackstore = True;
310    
311     test = 1;
312     host_be = !(BOOL) (*(uint8 *) (&test));
313     xserver_be = (ImageByteOrder(display) == MSBFirst);
314    
315 astrand 263 if ((width == 0) || (height == 0))
316     {
317     /* Fetch geometry from _NET_WORKAREA */
318     uint32 xpos, ypos;
319    
320     if (get_current_workarea(&xpos, &ypos, &width, &height) < 0)
321     {
322 matthewc 297 warning("Failed to get workarea: probably your window manager does not support extended hints\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 jsorg71 288 if (fullscreen && !focused)
606     XSetInputFocus(display, wnd, RevertToPointerRoot,
607     CurrentTime);
608 matthewc 203 rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
609 astrand 82 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
610 matty 28 break;
611    
612 matthewc 194 case FocusIn:
613 jsorg71 257 if (xevent.xfocus.mode == NotifyGrab)
614     break;
615     focused = True;
616 astrand 261 XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy,
617     &dummy, &dummy, &state);
618 matthewc 203 reset_modifier_keys(state);
619 jsorg71 257 if (grab_keyboard && mouse_in_wnd)
620 astrand 76 XGrabKeyboard(display, wnd, True,
621 astrand 82 GrabModeAsync, GrabModeAsync, CurrentTime);
622 matty 28 break;
623    
624 matthewc 194 case FocusOut:
625 jsorg71 257 if (xevent.xfocus.mode == NotifyUngrab)
626     break;
627     focused = False;
628 matthewc 201 if (xevent.xfocus.mode == NotifyWhileGrabbed)
629 astrand 76 XUngrabKeyboard(display, CurrentTime);
630 matty 28 break;
631 matty 31
632 matthewc 250 case EnterNotify:
633     /* we only register for this event when in fullscreen mode */
634 jsorg71 257 /* or grab_keyboard */
635     mouse_in_wnd = True;
636     if (fullscreen)
637     {
638 astrand 261 XSetInputFocus(display, wnd, RevertToPointerRoot,
639     CurrentTime);
640 jsorg71 257 break;
641     }
642     if (focused)
643     XGrabKeyboard(display, wnd, True,
644     GrabModeAsync, GrabModeAsync, CurrentTime);
645 matthewc 250 break;
646    
647 matthewc 253 case LeaveNotify:
648 jsorg71 257 /* we only register for this event when grab_keyboard */
649     mouse_in_wnd = False;
650 matthewc 253 XUngrabKeyboard(display, CurrentTime);
651     break;
652    
653 matty 31 case Expose:
654     XCopyArea(display, backstore, wnd, gc,
655 n-ki 54 xevent.xexpose.x, xevent.xexpose.y,
656 astrand 64 xevent.xexpose.width,
657     xevent.xexpose.height,
658 n-ki 54 xevent.xexpose.x, xevent.xexpose.y);
659 matty 31 break;
660 astrand 119
661     case MappingNotify:
662     /* Refresh keyboard mapping if it has changed. This is important for
663     Xvnc, since it allocates keycodes dynamically */
664     if (xevent.xmapping.request == MappingKeyboard
665     || xevent.xmapping.request == MappingModifier)
666     XRefreshKeyboardMapping(&xevent.xmapping);
667 matthewc 203
668     if (xevent.xmapping.request == MappingModifier)
669     {
670 matthewc 204 XFreeModifiermap(mod_map);
671 matthewc 203 mod_map = XGetModifierMapping(display);
672     }
673 astrand 119 break;
674    
675 matty 9 }
676     }
677 astrand 275 /* Keep going */
678     return 1;
679 matty 9 }
680    
681 astrand 275 /* Returns 0 after user quit, 1 otherwise */
682     int
683 matty 33 ui_select(int rdp_socket)
684     {
685 astrand 64 int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
686 matty 33 fd_set rfds;
687    
688     FD_ZERO(&rfds);
689    
690     while (True)
691     {
692 matthewc 121 /* Process any events already waiting */
693 astrand 275 if (!xwin_process_events())
694     /* User quit */
695     return 0;
696 astrand 119
697 matty 33 FD_ZERO(&rfds);
698     FD_SET(rdp_socket, &rfds);
699 matthewc 121 FD_SET(x_socket, &rfds);
700 matty 33
701     switch (select(n, &rfds, NULL, NULL, NULL))
702     {
703     case -1:
704     error("select: %s\n", strerror(errno));
705    
706     case 0:
707     continue;
708     }
709    
710     if (FD_ISSET(rdp_socket, &rfds))
711 astrand 275 return 1;
712 matty 33 }
713     }
714    
715     void
716 matty 25 ui_move_pointer(int x, int y)
717 matty 9 {
718 matty 10 XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
719 matty 9 }
720    
721 matty 25 HBITMAP
722 astrand 64 ui_create_bitmap(int width, int height, uint8 * data)
723 matty 6 {
724     XImage *image;
725 matty 9 Pixmap bitmap;
726 matty 28 uint8 *tdata;
727 matty 29
728 n-ki 279 tdata = (owncolmap ? data : translate_image(width, height, data));
729 matty 28 bitmap = XCreatePixmap(display, wnd, width, height, depth);
730 astrand 77 image = XCreateImage(display, visual, depth, ZPixmap, 0,
731     (char *) tdata, width, height, 8, 0);
732 matty 6
733 matty 28 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
734 matty 9
735     XFree(image);
736 n-ki 279 if (!owncolmap)
737     xfree(tdata);
738 matty 24 return (HBITMAP) bitmap;
739 matty 6 }
740    
741 matty 25 void
742 astrand 82 ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 * data)
743 matty 6 {
744 matty 10 XImage *image;
745 matty 29 uint8 *tdata;
746 matty 10
747 n-ki 279 tdata = (owncolmap ? data : translate_image(width, height, data));
748 astrand 77 image = XCreateImage(display, visual, depth, ZPixmap, 0,
749     (char *) tdata, width, height, 8, 0);
750 matty 28
751 matty 31 if (ownbackstore)
752     {
753     XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
754     XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
755     }
756     else
757     {
758     XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
759     }
760 matty 29
761 matty 24 XFree(image);
762 n-ki 279 if (!owncolmap)
763     xfree(tdata);
764 matty 6 }
765    
766 matty 25 void
767     ui_destroy_bitmap(HBITMAP bmp)
768 matty 6 {
769 astrand 64 XFreePixmap(display, (Pixmap) bmp);
770 matty 10 }
771    
772 matty 25 HGLYPH
773 astrand 64 ui_create_glyph(int width, int height, uint8 * data)
774 matty 10 {
775 matty 9 XImage *image;
776     Pixmap bitmap;
777     int scanline;
778     GC gc;
779 matty 6
780 matty 9 scanline = (width + 7) / 8;
781 matty 6
782 matty 10 bitmap = XCreatePixmap(display, wnd, width, height, 1);
783     gc = XCreateGC(display, bitmap, 0, NULL);
784 matty 9
785 astrand 77 image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
786 astrand 73 width, height, 8, scanline);
787 matty 23 image->byte_order = MSBFirst;
788     image->bitmap_bit_order = MSBFirst;
789     XInitImage(image);
790    
791 matty 10 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
792 matty 29
793 matty 9 XFree(image);
794 matty 10 XFreeGC(display, gc);
795 astrand 64 return (HGLYPH) bitmap;
796 matty 6 }
797 matty 7
798 matty 25 void
799     ui_destroy_glyph(HGLYPH glyph)
800 matty 7 {
801 astrand 64 XFreePixmap(display, (Pixmap) glyph);
802 matty 9 }
803    
804 matty 29 HCURSOR
805 astrand 66 ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
806     uint8 * andmask, uint8 * xormask)
807 matty 9 {
808 matty 29 HGLYPH maskglyph, cursorglyph;
809     XColor bg, fg;
810     Cursor xcursor;
811     uint8 *cursor, *pcursor;
812     uint8 *mask, *pmask;
813     uint8 nextbit;
814     int scanline, offset;
815     int i, j;
816    
817     scanline = (width + 7) / 8;
818     offset = scanline * height;
819    
820     cursor = xmalloc(offset);
821     memset(cursor, 0, offset);
822    
823     mask = xmalloc(offset);
824     memset(mask, 0, offset);
825    
826     /* approximate AND and XOR masks with a monochrome X pointer */
827     for (i = 0; i < height; i++)
828 matty 7 {
829 matty 29 offset -= scanline;
830     pcursor = &cursor[offset];
831     pmask = &mask[offset];
832    
833     for (j = 0; j < scanline; j++)
834 matty 28 {
835 matty 29 for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
836     {
837     if (xormask[0] || xormask[1] || xormask[2])
838     {
839     *pcursor |= (~(*andmask) & nextbit);
840     *pmask |= nextbit;
841     }
842     else
843     {
844     *pcursor |= ((*andmask) & nextbit);
845     *pmask |= (~(*andmask) & nextbit);
846     }
847    
848     xormask += 3;
849     }
850    
851     andmask++;
852     pcursor++;
853     pmask++;
854 matty 28 }
855 matty 7 }
856 matty 29
857     fg.red = fg.blue = fg.green = 0xffff;
858     bg.red = bg.blue = bg.green = 0x0000;
859     fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
860    
861     cursorglyph = ui_create_glyph(width, height, cursor);
862     maskglyph = ui_create_glyph(width, height, mask);
863    
864 astrand 66 xcursor =
865     XCreatePixmapCursor(display, (Pixmap) cursorglyph,
866     (Pixmap) maskglyph, &fg, &bg, x, y);
867 astrand 64
868 matty 29 ui_destroy_glyph(maskglyph);
869     ui_destroy_glyph(cursorglyph);
870     xfree(mask);
871     xfree(cursor);
872 astrand 64 return (HCURSOR) xcursor;
873 matty 29 }
874    
875     void
876     ui_set_cursor(HCURSOR cursor)
877     {
878 matthewc 188 current_cursor = (Cursor) cursor;
879     XDefineCursor(display, wnd, current_cursor);
880 matty 29 }
881    
882     void
883     ui_destroy_cursor(HCURSOR cursor)
884     {
885 astrand 64 XFreeCursor(display, (Cursor) cursor);
886 matty 29 }
887    
888     #define MAKE_XCOLOR(xc,c) \
889     (xc)->red = ((c)->red << 8) | (c)->red; \
890     (xc)->green = ((c)->green << 8) | (c)->green; \
891     (xc)->blue = ((c)->blue << 8) | (c)->blue; \
892     (xc)->flags = DoRed | DoGreen | DoBlue;
893    
894 n-ki 279
895 matty 29 HCOLOURMAP
896 astrand 64 ui_create_colourmap(COLOURMAP * colours)
897 matty 29 {
898     COLOURENTRY *entry;
899     int i, ncolours = colours->ncolours;
900 n-ki 279 if (!owncolmap)
901 matty 28 {
902 n-ki 279 uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
903     XColor xentry;
904     XColor xc_cache[256];
905     uint32 colour;
906     int colLookup = 256;
907     for (i = 0; i < ncolours; i++)
908 matty 28 {
909 n-ki 279 entry = &colours->colours[i];
910     MAKE_XCOLOR(&xentry, entry);
911 matty 7
912 n-ki 279 if (XAllocColor(display, xcolmap, &xentry) == 0)
913 astrand 196 {
914 n-ki 279 /* Allocation failed, find closest match. */
915     int j = 256;
916     int nMinDist = 3 * 256 * 256;
917     long nDist = nMinDist;
918 matty 28
919 n-ki 279 /* only get the colors once */
920     while (colLookup--)
921 astrand 196 {
922 n-ki 279 xc_cache[colLookup].pixel = colLookup;
923     xc_cache[colLookup].red = xc_cache[colLookup].green =
924     xc_cache[colLookup].blue = 0;
925     xc_cache[colLookup].flags = 0;
926     XQueryColor(display,
927     DefaultColormap(display,
928     DefaultScreen(display)),
929     &xc_cache[colLookup]);
930 n-ki 185 }
931 n-ki 279 colLookup = 0;
932    
933     /* approximate the pixel */
934     while (j--)
935 astrand 196 {
936 n-ki 279 if (xc_cache[j].flags)
937     {
938     nDist = ((long) (xc_cache[j].red >> 8) -
939     (long) (xentry.red >> 8)) *
940     ((long) (xc_cache[j].red >> 8) -
941     (long) (xentry.red >> 8)) +
942     ((long) (xc_cache[j].green >> 8) -
943     (long) (xentry.green >> 8)) *
944     ((long) (xc_cache[j].green >> 8) -
945     (long) (xentry.green >> 8)) +
946     ((long) (xc_cache[j].blue >> 8) -
947     (long) (xentry.blue >> 8)) *
948     ((long) (xc_cache[j].blue >> 8) -
949     (long) (xentry.blue >> 8));
950     }
951     if (nDist < nMinDist)
952     {
953     nMinDist = nDist;
954     xentry.pixel = j;
955     }
956 n-ki 185 }
957     }
958 n-ki 279 colour = xentry.pixel;
959    
960     /* update our cache */
961     if (xentry.pixel < 256)
962     {
963     xc_cache[xentry.pixel].red = xentry.red;
964     xc_cache[xentry.pixel].green = xentry.green;
965     xc_cache[xentry.pixel].blue = xentry.blue;
966    
967     }
968    
969    
970     /* byte swap here to make translate_image faster */
971     map[i] = translate_colour(colour);
972 n-ki 185 }
973 n-ki 279 return map;
974     }
975     else
976     {
977     XColor *xcolours, *xentry;
978     Colormap map;
979 matty 29
980 n-ki 279 xcolours = xmalloc(sizeof(XColor) * ncolours);
981     for (i = 0; i < ncolours; i++)
982 astrand 196 {
983 n-ki 279 entry = &colours->colours[i];
984     xentry = &xcolours[i];
985     xentry->pixel = i;
986     MAKE_XCOLOR(xentry, entry);
987 matty 29 }
988    
989 n-ki 279 map = XCreateColormap(display, wnd, visual, AllocAll);
990     XStoreColors(display, map, xcolours, ncolours);
991 n-ki 185
992 n-ki 279 xfree(xcolours);
993     return (HCOLOURMAP) map;
994 matty 29 }
995 matty 7 }
996    
997 matty 25 void
998     ui_destroy_colourmap(HCOLOURMAP map)
999 matty 7 {
1000 n-ki 279 if (!owncolmap)
1001     xfree(map);
1002     else
1003     XFreeColormap(display, (Colormap) map);
1004 matty 7 }
1005    
1006 matty 25 void
1007     ui_set_colourmap(HCOLOURMAP map)
1008 matty 7 {
1009 n-ki 279 if (!owncolmap)
1010     colmap = map;
1011     else
1012     XSetWindowColormap(display, wnd, (Colormap) map);
1013 matty 7 }
1014    
1015 matty 25 void
1016     ui_set_clip(int x, int y, int cx, int cy)
1017 matty 7 {
1018 matty 9 XRectangle rect;
1019 matty 7
1020 matty 9 rect.x = x;
1021     rect.y = y;
1022     rect.width = cx;
1023     rect.height = cy;
1024 matty 10 XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
1025 matty 9 }
1026 matty 7
1027 matty 25 void
1028 matthewc 192 ui_reset_clip(void)
1029 matty 9 {
1030     XRectangle rect;
1031    
1032     rect.x = 0;
1033     rect.y = 0;
1034 matty 10 rect.width = width;
1035     rect.height = height;
1036     XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
1037 matty 7 }
1038    
1039 matty 25 void
1040 matthewc 192 ui_bell(void)
1041 matty 10 {
1042     XBell(display, 0);
1043     }
1044    
1045 matty 25 void
1046     ui_destblt(uint8 opcode,
1047     /* dest */ int x, int y, int cx, int cy)
1048 matty 9 {
1049 matty 29 SET_FUNCTION(opcode);
1050 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1051 matty 29 RESET_FUNCTION(opcode);
1052 matty 9 }
1053    
1054 matty 25 void
1055     ui_patblt(uint8 opcode,
1056     /* dest */ int x, int y, int cx, int cy,
1057 astrand 64 /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1058 matty 9 {
1059     Pixmap fill;
1060 jsorg71 59 uint8 i, ipattern[8];
1061 matty 9
1062 matty 29 SET_FUNCTION(opcode);
1063 matty 9
1064     switch (brush->style)
1065     {
1066 matty 24 case 0: /* Solid */
1067 matty 29 SET_FOREGROUND(fgcolour);
1068 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1069 matty 9 break;
1070    
1071 matty 24 case 3: /* Pattern */
1072 jsorg71 59 for (i = 0; i != 8; i++)
1073     ipattern[7 - i] = brush->pattern[i];
1074     fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
1075 matty 9
1076 matty 29 SET_FOREGROUND(bgcolour);
1077     SET_BACKGROUND(fgcolour);
1078     XSetFillStyle(display, gc, FillOpaqueStippled);
1079     XSetStipple(display, gc, fill);
1080 astrand 82 XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
1081 matty 9
1082 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1083 matty 9
1084 matty 29 XSetFillStyle(display, gc, FillSolid);
1085 jsorg71 80 XSetTSOrigin(display, gc, 0, 0);
1086 astrand 64 ui_destroy_glyph((HGLYPH) fill);
1087 matty 9 break;
1088    
1089     default:
1090 matty 30 unimpl("brush %d\n", brush->style);
1091 matty 9 }
1092 matty 29
1093     RESET_FUNCTION(opcode);
1094 matty 9 }
1095    
1096 matty 25 void
1097     ui_screenblt(uint8 opcode,
1098     /* dest */ int x, int y, int cx, int cy,
1099     /* src */ int srcx, int srcy)
1100 matty 9 {
1101 matty 29 SET_FUNCTION(opcode);
1102 matty 24 XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1103 matty 31 if (ownbackstore)
1104 astrand 82 XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
1105 matty 29 RESET_FUNCTION(opcode);
1106 matty 9 }
1107    
1108 matty 25 void
1109     ui_memblt(uint8 opcode,
1110     /* dest */ int x, int y, int cx, int cy,
1111     /* src */ HBITMAP src, int srcx, int srcy)
1112 matty 9 {
1113 matty 29 SET_FUNCTION(opcode);
1114 astrand 64 XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1115 matty 31 if (ownbackstore)
1116 astrand 82 XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
1117 matty 29 RESET_FUNCTION(opcode);
1118 matty 9 }
1119    
1120 matty 25 void
1121     ui_triblt(uint8 opcode,
1122     /* dest */ int x, int y, int cx, int cy,
1123     /* src */ HBITMAP src, int srcx, int srcy,
1124 astrand 64 /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1125 matty 9 {
1126     /* This is potentially difficult to do in general. Until someone
1127 matty 10 comes up with a more efficient way of doing it I am using cases. */
1128 matty 9
1129     switch (opcode)
1130     {
1131 matty 24 case 0x69: /* PDSxxn */
1132 matty 16 ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1133 astrand 82 ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
1134 matty 16 break;
1135    
1136 matty 24 case 0xb8: /* PSDPxax */
1137 astrand 82 ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
1138 matty 16 ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1139 astrand 82 ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
1140 matty 9 break;
1141    
1142 matty 29 case 0xc0: /* PSa */
1143 matty 28 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1144 astrand 82 ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
1145 matty 28 break;
1146    
1147 matty 9 default:
1148 matty 30 unimpl("triblt 0x%x\n", opcode);
1149 matty 16 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1150 matty 9 }
1151     }
1152    
1153 matty 25 void
1154     ui_line(uint8 opcode,
1155     /* dest */ int startx, int starty, int endx, int endy,
1156 astrand 64 /* pen */ PEN * pen)
1157 matty 9 {
1158 matty 29 SET_FUNCTION(opcode);
1159     SET_FOREGROUND(pen->colour);
1160 matty 10 XDrawLine(display, wnd, gc, startx, starty, endx, endy);
1161 matty 31 if (ownbackstore)
1162     XDrawLine(display, backstore, gc, startx, starty, endx, endy);
1163 matty 29 RESET_FUNCTION(opcode);
1164 matty 9 }
1165    
1166 matty 25 void
1167     ui_rect(
1168     /* dest */ int x, int y, int cx, int cy,
1169     /* brush */ int colour)
1170 matty 9 {
1171 matty 29 SET_FOREGROUND(colour);
1172 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1173 matty 9 }
1174    
1175 jsorg71 278 /* warning, this function only draws on wnd or backstore, not both */
1176 matty 25 void
1177     ui_draw_glyph(int mixmode,
1178     /* dest */ int x, int y, int cx, int cy,
1179 astrand 66 /* src */ HGLYPH glyph, int srcx, int srcy,
1180     int bgcolour, int fgcolour)
1181 matty 9 {
1182 matty 29 SET_FOREGROUND(fgcolour);
1183     SET_BACKGROUND(bgcolour);
1184 matty 9
1185 astrand 66 XSetFillStyle(display, gc,
1186 astrand 82 (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1187 astrand 64 XSetStipple(display, gc, (Pixmap) glyph);
1188 matty 29 XSetTSOrigin(display, gc, x, y);
1189 matty 9
1190 matthewc 296 FILL_RECTANGLE_BACKSTORE(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 matthewc 299 ui_draw_glyph (mixmode, x + glyph->offset,\
1220     y + glyph->baseline,\
1221 mmihalik 49 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 matthewc 296 FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
1243 matty 31 }
1244 matty 17 else if (mixmode == MIX_OPAQUE)
1245 matty 31 {
1246 matthewc 296 FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
1247 matty 31 }
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     for (j = 0; j < entry->size; j++)
1281 astrand 82 DO_GLYPH(((uint8 *) (entry->data)), j);
1282 matthewc 44 }
1283 jsorg71 286 if (i + 2 < length)
1284     i += 3;
1285     else
1286     i += 2;
1287     length -= i;
1288     /* this will move pointer from start to first character after FE command */
1289     text = &(text[i]);
1290     i = 0;
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