/[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 301 - (hide annotations)
Thu Jan 30 11:28:50 2003 UTC (21 years, 3 months ago) by matthewc
File MIME type: text/plain
File size: 30594 byte(s)
unsigned long != uint32 on a 64-bit machine.

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

  ViewVC Help
Powered by ViewVC 1.1.26