/[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

Diff of /sourceforge.net/trunk/rdesktop/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 53 by matthewc, Tue May 28 11:48:55 2002 UTC revision 316 by jsorg71, Sun Feb 9 17:17:37 2003 UTC
# Line 1  Line 1 
1  /*  /*
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     User interface services - X Window System     User interface services - X Window System
4     Copyright (C) Matthew Chapman 1999-2001     Copyright (C) Matthew Chapman 1999-2002
5    
6     This program is free software; you can redistribute it and/or modify     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     it under the terms of the GNU General Public License as published by
# Line 20  Line 20 
20    
21  #include <X11/Xlib.h>  #include <X11/Xlib.h>
22  #include <X11/Xutil.h>  #include <X11/Xutil.h>
 #include <X11/XKBlib.h>  
23  #include <time.h>  #include <time.h>
24  #include <errno.h>  #include <errno.h>
25  #include "rdesktop.h"  #include "rdesktop.h"
26    
 extern char keymapname[16];  
 extern int keylayout;  
27  extern int width;  extern int width;
28  extern int height;  extern int height;
29  extern BOOL sendmotion;  extern BOOL sendmotion;
30  extern BOOL fullscreen;  extern BOOL fullscreen;
31    extern BOOL grab_keyboard;
32    extern BOOL hide_decorations;
33    extern char title[];
34    extern int server_bpp;
35    BOOL enable_compose = False;
36    BOOL focused;
37    BOOL mouse_in_wnd;
38    
39  Display *display;  Display *display;
 XkbDescPtr xkb;  
40  static int x_socket;  static int x_socket;
41    static Screen *screen;
42  static Window wnd;  static Window wnd;
43  static GC gc;  static GC gc;
44  static Visual *visual;  static Visual *visual;
45  static int depth;  static int depth;
46  static int bpp;  static int bpp;
47    static XIM IM;
48    static XIC IC;
49    static XModifierKeymap *mod_map;
50    static Cursor current_cursor;
51    static Atom protocol_atom, kill_atom;
52    
53  /* endianness */  /* endianness */
54  static BOOL host_be;  static BOOL host_be;
# Line 49  static BOOL xserver_be; Line 58  static BOOL xserver_be;
58  static BOOL ownbackstore;  static BOOL ownbackstore;
59  static Pixmap backstore;  static Pixmap backstore;
60    
61  /* needed to keep track of the modifiers */  /* MWM decorations */
62  static unsigned int key_modifier_state = 0;  #define MWM_HINTS_DECORATIONS   (1L << 1)
63  static unsigned int key_down_state = 0;  #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
64    typedef struct
65  #define DShift1Mask   (1<<0)  {
66  #define DShift2Mask   (1<<1)          uint32 flags;
67  #define DControl1Mask (1<<2)          uint32 functions;
68  #define DControl2Mask (1<<3)          uint32 decorations;
69  #define DMod1Mask     (1<<4)          sint32 inputMode;
70  #define DMod2Mask     (1<<5)          uint32 status;
71    }
72    PropMotifWmHints;
73    
74    typedef struct
75    {
76            uint32 red;
77            uint32 green;
78            uint32 blue;
79    }
80    PixelColour;
81    
82  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
83  { \  { \
# Line 67  static unsigned int key_down_state = 0; Line 86  static unsigned int key_down_state = 0;
86                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \
87  }  }
88    
89    #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\
90    { \
91            XFillRectangle(display, ownbackstore ? backstore : wnd, gc, x, y, cx, cy); \
92    }
93    
94  /* colour maps */  /* colour maps */
95  static BOOL owncolmap;  BOOL owncolmap = False;
96  static Colormap xcolmap;  static Colormap xcolmap;
 static uint32 white;  
97  static uint32 *colmap;  static uint32 *colmap;
98    
99  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )  #define TRANSLATE(col)          ( server_bpp != 8 ? translate_colour(col) : owncolmap ? col : translate_colour(colmap[col]) )
100  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));
101  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));
102    
# Line 99  static int rop2_map[] = { Line 122  static int rop2_map[] = {
122  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
123  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
124    
125  void xwin_release_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode);  void
126  void xwin_press_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode);  mwm_hide_decorations(void)
127    {
128            PropMotifWmHints motif_hints;
129            Atom hintsatom;
130    
131            /* setup the property */
132            motif_hints.flags = MWM_HINTS_DECORATIONS;
133            motif_hints.decorations = 0;
134    
135            /* get the atom for the property */
136            hintsatom = XInternAtom(display, "_MOTIF_WM_HINTS", False);
137            if (!hintsatom)
138            {
139                    warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");
140                    return;
141            }
142    
143            XChangeProperty(display, wnd, hintsatom, hintsatom, 32, PropModeReplace,
144                            (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
145    }
146    
147    PixelColour
148    split_colour15(uint32 colour)
149    {
150            PixelColour rv;
151            rv.red = (colour & 0x7c00) >> 10;
152            rv.red = (rv.red * 0xff) / 0x1f;
153            rv.green = (colour & 0x03e0) >> 5;
154            rv.green = (rv.green * 0xff) / 0x1f;
155            rv.blue = (colour & 0x1f);
156            rv.blue = (rv.blue * 0xff) / 0x1f;
157            return rv;
158    }
159    
160    PixelColour
161    split_colour16(uint32 colour)
162    {
163            PixelColour rv;
164            rv.red = (colour & 0xf800) >> 11;
165            rv.red = (rv.red * 0xff) / 0x1f;
166            rv.green = (colour & 0x07e0) >> 5;
167            rv.green = (rv.green * 0xff) / 0x3f;
168            rv.blue = (colour & 0x001f);
169            rv.blue = (rv.blue * 0xff) / 0x1f;
170            return rv;
171    }
172    
173    PixelColour
174    split_colour24(uint32 colour)
175    {
176            PixelColour rv;
177            rv.blue = (colour & 0xff0000) >> 16;
178            rv.green = (colour & 0xff00) >> 8;
179            rv.red = (colour & 0xff);
180            return rv;
181    }
182    
183    uint32 make_colour16(PixelColour pc)
184    {
185            pc.red = (pc.red * 0x1f) / 0xff;
186            pc.green = (pc.green * 0x3f) / 0xff;
187            pc.blue = (pc.blue * 0x1f) / 0xff;
188            return (pc.red << 11) | (pc.green << 5) | pc.blue;
189    }
190    
191    uint32 make_colour24(PixelColour pc)
192    {
193            return (pc.red << 16) | (pc.green << 8) | pc.blue;
194    }
195    
196    uint32 make_colour32(PixelColour pc)
197    {
198            return (pc.red << 16) | (pc.green << 8) | pc.blue;
199    }
200    
201    #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
202    #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }
203    #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
204                            x = (x << 16) | (x >> 16); }
205    
206    static uint32
207    translate_colour(uint32 colour)
208    {
209            switch (server_bpp)
210            {
211                    case 15:
212                            switch (bpp)
213                            {
214                                    case 16:
215                                            colour = make_colour16(split_colour15(colour));
216                                            break;
217                                    case 24:
218                                            colour = make_colour24(split_colour15(colour));
219                                            break;
220                                    case 32:
221                                            colour = make_colour32(split_colour15(colour));
222                                            break;
223                            }
224                            break;
225                    case 16:
226                            switch (bpp)
227                            {
228                                    case 16:
229                                            break;
230                                    case 24:
231                                            colour = make_colour24(split_colour16(colour));
232                                            break;
233                                    case 32:
234                                            colour = make_colour32(split_colour16(colour));
235                                            break;
236                            }
237                            break;
238                    case 24:
239                            switch (bpp)
240                            {
241                                    case 16:
242                                            colour = make_colour16(split_colour24(colour));
243                                            break;
244                                    case 24:
245                                            break;
246                                    case 32:
247                                            colour = make_colour32(split_colour24(colour));
248                                            break;
249                            }
250                            break;
251            }
252            switch (bpp)
253            {
254                    case 16:
255                            if (host_be != xserver_be)
256                                    BSWAP16(colour);
257                            break;
258    
259                    case 24:
260                            if (xserver_be)
261                                    BSWAP24(colour);
262                            break;
263    
264                    case 32:
265                            if (host_be != xserver_be)
266                                    BSWAP32(colour);
267                            break;
268            }
269    
270            return colour;
271    }
272    
273  static void  static void
274  translate8(uint8 *data, uint8 *out, uint8 *end)  translate8to8(uint8 * data, uint8 * out, uint8 * end)
275  {  {
276          while (out < end)          while (out < end)
277                  *(out++) = (uint8)colmap[*(data++)];                  *(out++) = (uint8) colmap[*(data++)];
278  }  }
279    
280  static void  static void
281  translate16(uint8 *data, uint16 *out, uint16 *end)  translate8to16(uint8 * data, uint16 * out, uint16 * end)
282  {  {
283          while (out < end)          while (out < end)
284                  *(out++) = (uint16)colmap[*(data++)];                  *(out++) = (uint16) colmap[*(data++)];
285  }  }
286    
287  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
288  static void  static void
289  translate24(uint8 *data, uint8 *out, uint8 *end)  translate8to24(uint8 * data, uint8 * out, uint8 * end)
290  {  {
291          uint32 value;          uint32 value;
292    
# Line 132  translate24(uint8 *data, uint8 *out, uin Line 300  translate24(uint8 *data, uint8 *out, uin
300  }  }
301    
302  static void  static void
303  translate32(uint8 *data, uint32 *out, uint32 *end)  translate8to32(uint8 * data, uint32 * out, uint32 * end)
304  {  {
305          while (out < end)          while (out < end)
306                  *(out++) = colmap[*(data++)];                  *(out++) = colmap[*(data++)];
307  }  }
308    
309  static uint8 *  /* todo the remaining translate function might need some big endian check ?? */
 translate_image(int width, int height, uint8 *data)  
 {  
         int size = width * height * bpp/8;  
         uint8 *out = xmalloc(size);  
         uint8 *end = out + size;  
310    
311          switch (bpp)  static void
312          {  translate15to16(uint16 * data, uint16 * out, uint16 * end)
313                  case 8:  {
314                          translate8(data, out, end);          while (out < end)
315                          break;                  *(out++) = (uint16) make_colour16(split_colour15(*(data++)));
316    }
                 case 16:  
                         translate16(data, (uint16 *)out, (uint16 *)end);  
                         break;  
317    
318                  case 24:  static void
319                          translate24(data, out, end);  translate15to24(uint16 * data, uint8 * out, uint8 * end)
320                          break;  {
321            uint32 value;
322    
323                  case 32:          while (out < end)
324                          translate32(data, (uint32 *)out, (uint32 *)end);          {
325                          break;                  value = make_colour24(split_colour15(*(data++)));
326                    *(out++) = value;
327                    *(out++) = value >> 8;
328                    *(out++) = value >> 16;
329          }          }
330    }
331    
332          return out;  static void
333    translate15to32(uint16 * data, uint32 * out, uint32 * end)
334    {
335            while (out < end)
336                    *(out++) = make_colour32(split_colour15(*(data++)));
337  }  }
338    
339  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }  static void
340  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }  translate16to16(uint16 * data, uint16 * out, uint16 * end)
341  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \  {
342                          x = (x << 16) | (x >> 16); }          while (out < end)
343                    *(out++) = (uint16) (*(data++));
344    }
345    
346  static uint32  
347  translate_colour(uint32 colour)  static void
348    translate16to24(uint16 * data, uint8 * out, uint8 * end)
349  {  {
350          switch (bpp)          uint32 value;
351    
352            while (out < end)
353          {          {
354                  case 16:                  value = make_colour24(split_colour16(*(data++)));
355                          if (host_be != xserver_be)                  *(out++) = value;
356                                  BSWAP16(colour);                  *(out++) = value >> 8;
357                          break;                  *(out++) = value >> 16;
358            }
359    }
360    
361                  case 24:  static void
362                          if (xserver_be)  translate16to32(uint16 * data, uint32 * out, uint32 * end)
363                                  BSWAP24(colour);  {
364                          break;          while (out < end)
365                    *(out++) = make_colour32(split_colour16(*(data++)));
366    }
367    
368                  case 32:  static void
369                          if (host_be != xserver_be)  translate24to16(uint8 * data, uint16 * out, uint16 * end)
370                                  BSWAP32(colour);  {
371                          break;          uint32 pixel = 0;
372            while (out < end)
373            {
374                    pixel = *(data++) << 16;
375                    pixel |= *(data++) << 8;
376                    pixel |= *(data++);
377                    *(out++) = (uint16) make_colour16(split_colour24(pixel));
378          }          }
379    }
380    
381          return colour;  static void
382    translate24to24(uint8 * data, uint8 * out, uint8 * end)
383    {
384            while (out < end)
385            {
386                    *(out++) = (*(data++));
387            }
388  }  }
389    
390  BOOL  static void
391  ui_create_window(char *title)  translate24to32(uint8 * data, uint32 * out, uint32 * end)
392  {  {
393          XSetWindowAttributes attribs;          uint32 pixel = 0;
394          XClassHint *classhints;          while (out < end)
         XSizeHints *sizehints;  
         unsigned long input_mask;  
         XPixmapFormatValues *pfm;  
         Screen *screen;  
         uint16 test;  
         int i;  
           
         int xkb_minor, xkb_major;  
         int xkb_event, xkb_error, xkb_reason;  
   
         /* compare compiletime libs with runtime libs. */  
         xkb_major = XkbMajorVersion;  
         xkb_minor = XkbMinorVersion;  
         if( XkbLibraryVersion( &xkb_major, &xkb_minor ) == False )  
395          {          {
396                  error("please re-compile rdesktop\ncompile time version of xkb is not compatible with\nyour runtime version of the library\n");                  memcpy(&pixel, data, 3);
397                  return False;                  data += 3;
398                    *(out++) = pixel;
399          }          }
400    }
401    
402    static uint8 *
403    translate_image(int width, int height, uint8 * data)
404    {
405            int size = width * height * bpp / 8;
406            uint8 *out = xmalloc(size);
407            uint8 *end = out + size;
408    
409          /* XKB is the 'new' keyboard handler in x.. ( the xkb code in Xfree86 originates from SGI, years 1993 and 1995 from what I could tell. )          switch (server_bpp)
          * it makes it possible for people with disabilities to use rdesktop, stickykeys, bouncekeys etc. VERY MUCH useful.  
          * XFree86 has had support for it since it's earliest incarnation. I believe it is a reasonable dependency.  
          */  
         display = XkbOpenDisplay( NULL, &xkb_event, &xkb_error, &xkb_major, &xkb_minor, &xkb_reason );  
         switch(xkb_reason)  
410          {          {
411                  case XkbOD_BadLibraryVersion:                  case 24:
412                          error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n");                          switch (bpp)
413                          break;                          {
414                  case XkbOD_ConnectionRefused:                                  case 32:
415                          error("XkbOD_ConnectionRefused\n");                                          translate24to32(data, (uint32 *) out, (uint32 *) end);
416                                            break;
417                                    case 24:
418                                            translate24to24(data, out, end);
419                                            break;
420                                    case 16:
421                                            translate24to16(data, (uint16 *) out, (uint16 *) end);
422                                            break;
423                            }
424                          break;                          break;
425                  case XkbOD_BadServerVersion:                  case 16:
426                          error("XkbOD_BadServerVersion\n");                          switch (bpp)
427                            {
428                                    case 32:
429                                            translate16to32((uint16 *) data, (uint32 *) out, (uint32 *) end);
430                                            break;
431                                    case 24:
432                                            translate16to24((uint16 *) data, out, end);
433                                            break;
434                                    case 16:
435                                            translate16to16((uint16 *) data, (uint16 *) out, (uint16 *) end);
436                                            break;
437                            }
438                          break;                          break;
439                  case XkbOD_NonXkbServer:                  case 15:
440                          error("XkbOD_NonXkbServer: XKB extension not present in server\nupdate your X server.\n");                          switch (bpp)
441                            {
442                                    case 32:
443                                            translate15to32((uint16 *) data, (uint32 *) out, (uint32 *) end);
444                                            break;
445                                    case 24:
446                                            translate15to24((uint16 *) data, out, end);
447                                            break;
448                                    case 16:
449                                            translate15to16((uint16 *) data, (uint16 *) out, (uint16 *) end);
450                                            break;
451                            }
452                          break;                          break;
453                  case XkbOD_Success:                  case 8:
454                          DEBUG("XkbOD_Success: Connection established with display\n");                          switch (bpp)
455                            {
456                                    case 8:
457                                            translate8to8(data, out, end);
458                                            break;
459                                    case 16:
460                                            translate8to16(data, (uint16 *) out, (uint16 *) end);
461                                            break;
462                                    case 24:
463                                            translate8to24(data, out, end);
464                                            break;
465                                    case 32:
466                                            translate8to32(data, (uint32 *) out, (uint32 *) end);
467                                            break;
468                            }
469                          break;                          break;
470          }          }
471            return out;
472    }
473    
474    BOOL
475    get_key_state(unsigned int state, uint32 keysym)
476    {
477            int modifierpos, key, keysymMask = 0;
478            int offset;
479    
480            KeyCode keycode = XKeysymToKeycode(display, keysym);
481    
482            if (keycode == NoSymbol)
483                    return False;
484    
485            for (modifierpos = 0; modifierpos < 8; modifierpos++)
486            {
487                    offset = mod_map->max_keypermod * modifierpos;
488    
489                    for (key = 0; key < mod_map->max_keypermod; key++)
490                    {
491                            if (mod_map->modifiermap[offset + key] == keycode)
492                                    keysymMask |= 1 << modifierpos;
493                    }
494            }
495    
496            return (state & keysymMask) ? True : False;
497    }
498    
499    BOOL
500    ui_init(void)
501    {
502            XPixmapFormatValues *pfm;
503            uint16 test;
504            int i;
505    
506            display = XOpenDisplay(NULL);
507          if (display == NULL)          if (display == NULL)
508          {          {
509                  error("Failed to open display\n");                  error("Failed to open display: %s\n", XDisplayName(NULL));
510                  return False;                  return False;
511          }          }
512    
# Line 255  ui_create_window(char *title) Line 514  ui_create_window(char *title)
514          screen = DefaultScreenOfDisplay(display);          screen = DefaultScreenOfDisplay(display);
515          visual = DefaultVisualOfScreen(screen);          visual = DefaultVisualOfScreen(screen);
516          depth = DefaultDepthOfScreen(screen);          depth = DefaultDepthOfScreen(screen);
517            
518          pfm = XListPixmapFormats(display, &i);          pfm = XListPixmapFormats(display, &i);
519          if (pfm != NULL)          if (pfm != NULL)
520          {          {
# Line 263  ui_create_window(char *title) Line 522  ui_create_window(char *title)
522                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
523                  while (i--)                  while (i--)
524                  {                  {
525                          if ((pfm[i].depth == depth)                          if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))
                             && (pfm[i].bits_per_pixel > bpp))  
526                          {                          {
527                                  bpp = pfm[i].bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
528                          }                          }
# Line 279  ui_create_window(char *title) Line 537  ui_create_window(char *title)
537                  return False;                  return False;
538          }          }
539    
540          if (depth <= 8)          if (owncolmap != True)
541                  owncolmap = True;          {
         else  
542                  xcolmap = DefaultColormapOfScreen(screen);                  xcolmap = DefaultColormapOfScreen(screen);
543                    if (depth <= 8)
544                            warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");
545            }
546    
547            gc = XCreateGC(display, RootWindowOfScreen(screen), 0, NULL);
548    
549            if (DoesBackingStore(screen) != Always)
550                    ownbackstore = True;
551    
552          test = 1;          test = 1;
553          host_be = !(BOOL)(*(uint8 *)(&test));          host_be = !(BOOL) (*(uint8 *) (&test));
554          xserver_be = (ImageByteOrder(display) == MSBFirst);          xserver_be = (ImageByteOrder(display) == MSBFirst);
555    
556          white = WhitePixelOfScreen(screen);          if ((width == 0) || (height == 0))
557          attribs.background_pixel = BlackPixelOfScreen(screen);          {
558          attribs.backing_store = DoesBackingStore(screen);                  /* Fetch geometry from _NET_WORKAREA */
559                    uint32 x, y, cx, cy;
560    
561          if (attribs.backing_store == NotUseful)                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)
562                  ownbackstore = True;                  {
563                            width = cx;
564                            height = cy;
565                    }
566                    else
567                    {
568                            warning("Failed to get workarea: probably your window manager does not support extended hints\n");
569                            width = 800;
570                            height = 600;
571                    }
572            }
573    
574          if (fullscreen)          if (fullscreen)
575          {          {
                 attribs.override_redirect = True;  
576                  width = WidthOfScreen(screen);                  width = WidthOfScreen(screen);
577                  height = HeightOfScreen(screen);                  height = HeightOfScreen(screen);
578          }          }
579          else  
580            /* make sure width is a multiple of 4 */
581            width = (width + 3) & ~3;
582    
583            if (ownbackstore)
584          {          {
585                  attribs.override_redirect = False;                  backstore =
586                            XCreatePixmap(display, RootWindowOfScreen(screen), width, height, depth);
587    
588                    /* clear to prevent rubbish being exposed at startup */
589                    XSetForeground(display, gc, BlackPixelOfScreen(screen));
590                    XFillRectangle(display, backstore, gc, 0, 0, width, height);
591          }          }
592    
593          width = (width + 3) & ~3; /* make width a multiple of 32 bits */          mod_map = XGetModifierMapping(display);
594    
595            if (enable_compose)
596                    IM = XOpenIM(display, NULL, NULL, NULL);
597    
598            xkeymap_init();
599    
600            /* todo take this out when high colour is done */
601            printf("server bpp %d client bpp %d depth %d\n", server_bpp, bpp, depth);
602    
603            return True;
604    }
605    
606    void
607    ui_deinit(void)
608    {
609            if (IM != NULL)
610                    XCloseIM(IM);
611    
612            XFreeModifiermap(mod_map);
613    
614            if (ownbackstore)
615                    XFreePixmap(display, backstore);
616    
617            XFreeGC(display, gc);
618            XCloseDisplay(display);
619            display = NULL;
620    }
621    
622          wnd = XCreateWindow(display, RootWindowOfScreen(screen),  BOOL
623                              0, 0, width, height, 0, CopyFromParent,  ui_create_window(void)
624                              InputOutput, CopyFromParent,  {
625                              CWBackingStore | CWBackPixel | CWOverrideRedirect,          XSetWindowAttributes attribs;
626                              &attribs);          XClassHint *classhints;
627            XSizeHints *sizehints;
628            int wndwidth, wndheight;
629            long input_mask, ic_input_mask;
630            XEvent xevent;
631    
632            wndwidth = fullscreen ? WidthOfScreen(screen) : width;
633            wndheight = fullscreen ? HeightOfScreen(screen) : height;
634    
635            attribs.background_pixel = BlackPixelOfScreen(screen);
636            attribs.backing_store = ownbackstore ? NotUseful : Always;
637            attribs.override_redirect = fullscreen;
638    
639            wnd = XCreateWindow(display, RootWindowOfScreen(screen), 0, 0, wndwidth, wndheight,
640                                0, CopyFromParent, InputOutput, CopyFromParent,
641                                CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);
642    
643          XStoreName(display, wnd, title);          XStoreName(display, wnd, title);
644    
645            if (hide_decorations)
646                    mwm_hide_decorations();
647    
648          classhints = XAllocClassHint();          classhints = XAllocClassHint();
649          if (classhints != NULL)          if (classhints != NULL)
650          {          {
# Line 334  ui_create_window(char *title) Line 663  ui_create_window(char *title)
663                  XFree(sizehints);                  XFree(sizehints);
664          }          }
665    
666          xkeymap_init();          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
667                    VisibilityChangeMask | FocusChangeMask;
668    
         input_mask = KeyPressMask | KeyReleaseMask |  
                          ButtonPressMask | ButtonReleaseMask |  
                          EnterWindowMask | LeaveWindowMask | KeymapStateMask;  
669          if (sendmotion)          if (sendmotion)
670                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
   
671          if (ownbackstore)          if (ownbackstore)
672                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
673            if (fullscreen || grab_keyboard)
674                    input_mask |= EnterWindowMask;
675            if (grab_keyboard)
676                    input_mask |= LeaveWindowMask;
677    
678            if (IM != NULL)
679            {
680                    IC = XCreateIC(IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
681                                   XNClientWindow, wnd, XNFocusWindow, wnd, NULL);
682    
683                    if ((IC != NULL)
684                        && (XGetICValues(IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
685                            input_mask |= ic_input_mask;
686            }
687    
688          XSelectInput(display, wnd, input_mask);          XSelectInput(display, wnd, input_mask);
         gc = XCreateGC(display, wnd, 0, NULL);  
   
         if (ownbackstore)  
                 backstore = XCreatePixmap(display, wnd, width, height, depth);  
   
689          XMapWindow(display, wnd);          XMapWindow(display, wnd);
690    
691          /* TODO: error texts... make them friendly. */          /* wait for VisibilityNotify */
692          xkb = XkbGetKeyboard(display, XkbAllComponentsMask, XkbUseCoreKbd);          do
         if ((int)xkb == BadAlloc || xkb == NULL)  
         {  
                         error( "XkbGetKeyboard failed.\n");  
                         exit(0);  
         }  
   
         /* TODO: error texts... make them friendly. */  
         if( XkbSelectEvents(display, xkb->device_spec, XkbAllEventsMask, XkbAllEventsMask) == False )  
693          {          {
694                          error( "XkbSelectEvents failed.\n");                  XMaskEvent(display, VisibilityChangeMask, &xevent);
                         exit(0);  
695          }          }
696            while (xevent.type != VisibilityNotify);
697    
698            focused = False;
699            mouse_in_wnd = False;
700    
701            /* handle the WM_DELETE_WINDOW protocol */
702            protocol_atom = XInternAtom(display, "WM_PROTOCOLS", True);
703            kill_atom = XInternAtom(display, "WM_DELETE_WINDOW", True);
704            XSetWMProtocols(display, wnd, &kill_atom, 1);
705    
706          return True;          return True;
707  }  }
708    
709  void  void
710  ui_destroy_window()  ui_destroy_window(void)
711  {  {
712          if( xkb != NULL )          if (IC != NULL)
713                  XkbFreeKeyboard(xkb, XkbAllControlsMask, True);                  XDestroyIC(IC);
   
         if (ownbackstore)  
                 XFreePixmap(display, backstore);  
714    
         XFreeGC(display, gc);  
715          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
         XCloseDisplay(display);  
         display = NULL;  
716  }  }
717    
718  static void  void
719  xwin_process_events()  xwin_toggle_fullscreen(void)
720  {  {
721          XkbEvent xkbevent;          Pixmap contents = 0;
722            
723            if (!ownbackstore)
724            {
725                    /* need to save contents of window */
726                    contents = XCreatePixmap(display, wnd, width, height, depth);
727                    XCopyArea(display, wnd, contents, gc, 0, 0, width, height, 0, 0);
728            }
729    
730            ui_destroy_window();
731            fullscreen = !fullscreen;
732            ui_create_window();
733    
734            XDefineCursor(display, wnd, current_cursor);
735    
736            if (!ownbackstore)
737            {
738                    XCopyArea(display, contents, wnd, gc, 0, 0, width, height, 0, 0);
739                    XFreePixmap(display, contents);
740            }
741    }
742    
743    /* Process all events in Xlib queue
744       Returns 0 after user quit, 1 otherwise */
745    static int
746    xwin_process_events(void)
747    {
748            XEvent xevent;
749          KeySym keysym;          KeySym keysym;
         uint8 scancode;  
750          uint16 button, flags;          uint16 button, flags;
751          uint32 ev_time;          uint32 ev_time;
752          uint32 tmpmods;          key_translation tr;
753            char str[256];
754            Status status;
755            unsigned int state;
756            Window wdummy;
757            int dummy;
758    
759          while (XCheckMaskEvent(display, ~0, &xkbevent.core))          while (XPending(display) > 0)
760          {          {
761                  ev_time = time(NULL);                  XNextEvent(display, &xevent);
762    
763                    if ((IC != NULL) && (XFilterEvent(&xevent, None) == True))
764                    {
765                            DEBUG_KBD(("Filtering event\n"));
766                            continue;
767                    }
768    
769                  flags = 0;                  flags = 0;
770    
771                  switch (xkbevent.type)                  switch (xevent.type)
772                  {                  {
773                          case KeymapNotify:                          case ClientMessage:
774                                  /* TODO:                                  /* the window manager told us to quit */
775                                   * read modifier status at focus in, and update the local masks, and the other end as well..                                  if ((xevent.xclient.message_type == protocol_atom)
776                                   * if not, we may get out of sync.                                      && (xevent.xclient.data.l[0] == kill_atom))
777                                   * xkbevent.core.xkeymap.key_vector                                          /* Quit */
778                                   * char key_vector[32];                                          return 0;
                                  */  
779                                  break;                                  break;
780    
                         case KeyRelease:  
                                 flags = KBD_FLAG_DOWN | KBD_FLAG_UP;  
                                 /* fall through */  
   
781                          case KeyPress:                          case KeyPress:
782                                  if( XkbTranslateKeyCode(xkb, xkbevent.core.xkey.keycode, xkbevent.core.xkey.state, &tmpmods, &keysym) == False )                                  if (IC != NULL)
783                                            /* Multi_key compatible version */
784                                    {
785                                            XmbLookupString(IC,
786                                                            (XKeyPressedEvent *) &
787                                                            xevent, str, sizeof(str), &keysym, &status);
788                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
789                                            {
790                                                    error("XmbLookupString failed with status 0x%x\n",
791                                                          status);
792                                                    break;
793                                            }
794                                    }
795                                    else
796                                    {
797                                            /* Plain old XLookupString */
798                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
799                                            XLookupString((XKeyEvent *) & xevent,
800                                                          str, sizeof(str), &keysym, NULL);
801                                    }
802    
803                                    DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
804                                               get_ksname(keysym)));
805    
806                                    ev_time = time(NULL);
807                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
808                                          break;                                          break;
                                 scancode = xkeymap_translate_key(keysym, xkbevent.core.xkey.keycode, &flags);  
809    
810                                  if (scancode == 0 )                                  tr = xkeymap_translate_key(keysym,
811                                                               xevent.xkey.keycode, xevent.xkey.state);
812    
813                                    if (tr.scancode == 0)
814                                          break;                                          break;
815    
816                                  /* keep track of the modifiers -- needed for stickykeys... */                                  ensure_remote_modifiers(ev_time, tr);
                                 if( xkbevent.type == KeyPress )  
                                         xwin_press_modifiers( &xkbevent.core.xkey, ev_time, scancode );  
817    
818                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, flags, scancode, 0);                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
819                                    break;
820    
821                                  if( xkbevent.type == KeyRelease )                          case KeyRelease:
822                                          xwin_release_modifiers( &xkbevent.core.xkey, ev_time, scancode );                                  XLookupString((XKeyEvent *) & xevent, str,
823                                                  sizeof(str), &keysym, NULL);
824    
825                                    DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
826                                               get_ksname(keysym)));
827    
828                                    ev_time = time(NULL);
829                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
830                                            break;
831    
832                                    tr = xkeymap_translate_key(keysym,
833                                                               xevent.xkey.keycode, xevent.xkey.state);
834    
835                                    if (tr.scancode == 0)
836                                            break;
837    
838                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
839                                  break;                                  break;
840    
841                          case ButtonPress:                          case ButtonPress:
# Line 441  xwin_process_events() Line 843  xwin_process_events()
843                                  /* fall through */                                  /* fall through */
844    
845                          case ButtonRelease:                          case ButtonRelease:
846                                  button = xkeymap_translate_button(xkbevent.core.xbutton.button);                                  button = xkeymap_translate_button(xevent.xbutton.button);
847                                  if (button == 0)                                  if (button == 0)
848                                          break;                                          break;
849    
850                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
851                                                 flags | button,                                                 flags | button, xevent.xbutton.x, xevent.xbutton.y);
                                                xkbevent.core.xbutton.x,  
                                                xkbevent.core.xbutton.y);  
852                                  break;                                  break;
853    
854                          case MotionNotify:                          case MotionNotify:
855                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  if (fullscreen && !focused)
856                                                 MOUSE_FLAG_MOVE,                                          XSetInputFocus(display, wnd, RevertToPointerRoot,
857                                                 xkbevent.core.xmotion.x,                                                         CurrentTime);
858                                                 xkbevent.core.xmotion.y);                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
859                                                   MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
860                                    break;
861    
862                            case FocusIn:
863                                    if (xevent.xfocus.mode == NotifyGrab)
864                                            break;
865                                    focused = True;
866                                    XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy,
867                                                  &dummy, &dummy, &state);
868                                    reset_modifier_keys(state);
869                                    if (grab_keyboard && mouse_in_wnd)
870                                            XGrabKeyboard(display, wnd, True,
871                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
872                                    break;
873    
874                            case FocusOut:
875                                    if (xevent.xfocus.mode == NotifyUngrab)
876                                            break;
877                                    focused = False;
878                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
879                                            XUngrabKeyboard(display, CurrentTime);
880                                  break;                                  break;
881    
882                          case EnterNotify:                          case EnterNotify:
883                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,                                  /* we only register for this event when in fullscreen mode */
884                                                GrabModeAsync, CurrentTime);                                  /* or grab_keyboard */
885                                    mouse_in_wnd = True;
886                                    if (fullscreen)
887                                    {
888                                            XSetInputFocus(display, wnd, RevertToPointerRoot,
889                                                           CurrentTime);
890                                            break;
891                                    }
892                                    if (focused)
893                                            XGrabKeyboard(display, wnd, True,
894                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
895                                  break;                                  break;
896    
897                          case LeaveNotify:                          case LeaveNotify:
898                                    /* we only register for this event when grab_keyboard */
899                                    mouse_in_wnd = False;
900                                  XUngrabKeyboard(display, CurrentTime);                                  XUngrabKeyboard(display, CurrentTime);
901                                  break;                                  break;
902    
903                          case Expose:                          case Expose:
904                                  XCopyArea(display, backstore, wnd, gc,                                  XCopyArea(display, backstore, wnd, gc,
905                                            xkbevent.core.xexpose.x, xkbevent.core.xexpose.y,                                            xevent.xexpose.x, xevent.xexpose.y,
906                                            xkbevent.core.xexpose.width, xkbevent.core.xexpose.height,                                            xevent.xexpose.width,
907                                            xkbevent.core.xexpose.x, xkbevent.core.xexpose.y);                                            xevent.xexpose.height,
908                                              xevent.xexpose.x, xevent.xexpose.y);
909                                  break;                                  break;
                 }  
         }  
 }  
   
 void  
 xwin_release_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode)  
 {  
         switch (scancode) {  
         case 0x2a:  
                 key_down_state &= ~DShift1Mask;  
                 break;  
         case 0x36:  
                 key_down_state &= ~DShift2Mask;  
                 break;  
         case 0x1d:  
                 key_down_state &= ~DControl1Mask;  
                 break;  
         case 0x9d:  
                 key_down_state &= ~DControl2Mask;  
                 break;  
         case 0x38:  
                 key_down_state &= ~DMod1Mask;  
                 break;  
         case 0xb8:  
                 key_down_state &= ~DMod2Mask;  
                 break;  
         }  
   
         if( !(ShiftMask & ev->state) && (key_down_state & DShift1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a, 0);  
                 key_down_state &= ~DShift1Mask;  
910    
911          }                          case MappingNotify:
912                                    /* Refresh keyboard mapping if it has changed. This is important for
913          if( !(ControlMask & ev->state) && (key_down_state & DControl1Mask))                                     Xvnc, since it allocates keycodes dynamically */
914          {                                  if (xevent.xmapping.request == MappingKeyboard
915                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d, 0);                                      || xevent.xmapping.request == MappingModifier)
916                  key_down_state &= ~DControl1Mask;                                          XRefreshKeyboardMapping(&xevent.xmapping);
917    
918          }                                  if (xevent.xmapping.request == MappingModifier)
919                                            {
920          if( !(Mod1Mask & ev->state) && (key_down_state & DMod1Mask))                                          XFreeModifiermap(mod_map);
921          {                                          mod_map = XGetModifierMapping(display);
922                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38, 0);                                  }
923                  key_down_state &= ~DMod1Mask;                                  break;
   
         }  
           
         if( !(Mod2Mask & ev->state) && (key_down_state & DMod2Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8, 0);  
                 key_down_state &= ~DMod2Mask;  
         }  
 }  
   
   
 void  
 xwin_press_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode)  
 {  
         key_modifier_state = ev->state;  
   
         switch (scancode) {  
         case 0x2a:  
                 key_down_state |= DShift1Mask;  
                 break;  
         case 0x36:  
                 key_down_state |= DShift2Mask;  
                 break;  
         case 0x1d:  
                 key_down_state |= DControl1Mask;  
                 break;  
         case 0x9d:  
                 key_down_state |= DControl2Mask;  
                 break;  
         case 0x38:  
                 key_down_state |= DMod1Mask;  
                 break;  
         case 0xb8:  
                 key_down_state |= DMod2Mask;  
                 break;  
         }  
   
         if( (ShiftMask & ev->state) && !((key_down_state & DShift1Mask) || (key_down_state & DShift2Mask)))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x2a, 0);  
                 key_down_state |= DShift1Mask;  
   
         }  
   
         if( (ControlMask & ev->state) && !((key_down_state & DControl1Mask) || (key_down_state & DControl2Mask)))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x1d, 0);  
                 key_down_state |= DControl1Mask;  
   
         }  
   
         if( (Mod1Mask & ev->state) && !(key_down_state & DMod1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x38, 0);  
                 key_down_state |= DMod1Mask;  
   
         }  
   
         if( (Mod2Mask & ev->state) && !(key_down_state & DMod2Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0xb8, 0);  
                 key_down_state |= DMod2Mask;  
924    
925                    }
926          }          }
927            /* Keep going */
928            return 1;
929  }  }
930    
931  void  /* Returns 0 after user quit, 1 otherwise */
932    int
933  ui_select(int rdp_socket)  ui_select(int rdp_socket)
934  {  {
935          int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
936          fd_set rfds;          fd_set rfds;
937    
938          FD_ZERO(&rfds);          FD_ZERO(&rfds);
939    
940          while (True)          while (True)
941          {          {
942                    /* Process any events already waiting */
943                    if (!xwin_process_events())
944                            /* User quit */
945                            return 0;
946    
947                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
948                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
949                  if (display != NULL)                  FD_SET(x_socket, &rfds);
                 {  
                         FD_SET(x_socket, &rfds);  
                         XFlush(display);  
                 }  
950    
951                  switch (select(n, &rfds, NULL, NULL, NULL))                  switch (select(n, &rfds, NULL, NULL, NULL))
952                  {                  {
# Line 612  ui_select(int rdp_socket) Line 957  ui_select(int rdp_socket)
957                                  continue;                                  continue;
958                  }                  }
959    
                 if (FD_ISSET(x_socket, &rfds))  
                         xwin_process_events();  
   
960                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
961                          return;                          return 1;
962          }          }
963  }  }
964    
# Line 627  ui_move_pointer(int x, int y) Line 969  ui_move_pointer(int x, int y)
969  }  }
970    
971  HBITMAP  HBITMAP
972  ui_create_bitmap(int width, int height, uint8 *data)  ui_create_bitmap(int width, int height, uint8 * data)
973  {  {
974          XImage *image;          XImage *image;
975          Pixmap bitmap;          Pixmap bitmap;
# Line 635  ui_create_bitmap(int width, int height, Line 977  ui_create_bitmap(int width, int height,
977    
978          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
979          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
980          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
981                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, server_bpp == 8 ? 8 : bpp, 0);
982    
983          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
984    
# Line 647  ui_create_bitmap(int width, int height, Line 989  ui_create_bitmap(int width, int height,
989  }  }
990    
991  void  void
992  ui_paint_bitmap(int x, int y, int cx, int cy,  ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 * data)
                 int width, int height, uint8 *data)  
993  {  {
994          XImage *image;          XImage *image;
995          uint8 *tdata;          uint8 *tdata;
   
996          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
997          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
998                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, server_bpp == 8 ? 8 : bpp, 0);
999    
1000          if (ownbackstore)          if (ownbackstore)
1001          {          {
# Line 675  ui_paint_bitmap(int x, int y, int cx, in Line 1015  ui_paint_bitmap(int x, int y, int cx, in
1015  void  void
1016  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
1017  {  {
1018          XFreePixmap(display, (Pixmap)bmp);          XFreePixmap(display, (Pixmap) bmp);
1019  }  }
1020    
1021  HGLYPH  HGLYPH
1022  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 * data)
1023  {  {
1024          XImage *image;          XImage *image;
1025          Pixmap bitmap;          Pixmap bitmap;
# Line 691  ui_create_glyph(int width, int height, u Line 1031  ui_create_glyph(int width, int height, u
1031          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
1032          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
1033    
1034          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
1035                               data, width, height, 8, scanline);                               width, height, 8, scanline);
1036          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
1037          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1038          XInitImage(image);          XInitImage(image);
# Line 701  ui_create_glyph(int width, int height, u Line 1041  ui_create_glyph(int width, int height, u
1041    
1042          XFree(image);          XFree(image);
1043          XFreeGC(display, gc);          XFreeGC(display, gc);
1044          return (HGLYPH)bitmap;          return (HGLYPH) bitmap;
1045  }  }
1046    
1047  void  void
1048  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
1049  {  {
1050          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(display, (Pixmap) glyph);
1051  }  }
1052    
1053  HCURSOR  HCURSOR
1054  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
1055                   int height, uint8 *andmask, uint8 *xormask)                   uint8 * andmask, uint8 * xormask)
1056  {  {
1057          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
1058          XColor bg, fg;          XColor bg, fg;
# Line 769  ui_create_cursor(unsigned int x, unsigne Line 1109  ui_create_cursor(unsigned int x, unsigne
1109    
1110          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
1111          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
1112            
1113          xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,          xcursor =
1114                                  (Pixmap)maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(display, (Pixmap) cursorglyph,
1115                                        (Pixmap) maskglyph, &fg, &bg, x, y);
1116    
1117          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
1118          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
1119          xfree(mask);          xfree(mask);
1120          xfree(cursor);          xfree(cursor);
1121          return (HCURSOR)xcursor;          return (HCURSOR) xcursor;
1122  }  }
1123    
1124  void  void
1125  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
1126  {  {
1127          XDefineCursor(display, wnd, (Cursor)cursor);          current_cursor = (Cursor) cursor;
1128            XDefineCursor(display, wnd, current_cursor);
1129  }  }
1130    
1131  void  void
1132  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
1133  {  {
1134          XFreeCursor(display, (Cursor)cursor);          XFreeCursor(display, (Cursor) cursor);
1135  }  }
1136    
1137  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 798  ui_destroy_cursor(HCURSOR cursor) Line 1140  ui_destroy_cursor(HCURSOR cursor)
1140                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
1141                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
1142    
1143    
1144  HCOLOURMAP  HCOLOURMAP
1145  ui_create_colourmap(COLOURMAP *colours)  ui_create_colourmap(COLOURMAP * colours)
1146  {  {
1147          COLOURENTRY *entry;          COLOURENTRY *entry;
1148          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
1149            if (!owncolmap)
1150            {
1151                    uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
1152                    XColor xentry;
1153                    XColor xc_cache[256];
1154                    uint32 colour;
1155                    int colLookup = 256;
1156                    for (i = 0; i < ncolours; i++)
1157                    {
1158                            entry = &colours->colours[i];
1159                            MAKE_XCOLOR(&xentry, entry);
1160    
1161                            if (XAllocColor(display, xcolmap, &xentry) == 0)
1162                            {
1163                                    /* Allocation failed, find closest match. */
1164                                    int j = 256;
1165                                    int nMinDist = 3 * 256 * 256;
1166                                    long nDist = nMinDist;
1167    
1168                                    /* only get the colors once */
1169                                    while (colLookup--)
1170                                    {
1171                                            xc_cache[colLookup].pixel = colLookup;
1172                                            xc_cache[colLookup].red = xc_cache[colLookup].green =
1173                                                    xc_cache[colLookup].blue = 0;
1174                                            xc_cache[colLookup].flags = 0;
1175                                            XQueryColor(display,
1176                                                        DefaultColormap(display,
1177                                                                        DefaultScreen(display)),
1178                                                        &xc_cache[colLookup]);
1179                                    }
1180                                    colLookup = 0;
1181    
1182                                    /* approximate the pixel */
1183                                    while (j--)
1184                                    {
1185                                            if (xc_cache[j].flags)
1186                                            {
1187                                                    nDist = ((long) (xc_cache[j].red >> 8) -
1188                                                             (long) (xentry.red >> 8)) *
1189                                                            ((long) (xc_cache[j].red >> 8) -
1190                                                             (long) (xentry.red >> 8)) +
1191                                                            ((long) (xc_cache[j].green >> 8) -
1192                                                             (long) (xentry.green >> 8)) *
1193                                                            ((long) (xc_cache[j].green >> 8) -
1194                                                             (long) (xentry.green >> 8)) +
1195                                                            ((long) (xc_cache[j].blue >> 8) -
1196                                                             (long) (xentry.blue >> 8)) *
1197                                                            ((long) (xc_cache[j].blue >> 8) -
1198                                                             (long) (xentry.blue >> 8));
1199                                            }
1200                                            if (nDist < nMinDist)
1201                                            {
1202                                                    nMinDist = nDist;
1203                                                    xentry.pixel = j;
1204                                            }
1205                                    }
1206                            }
1207                            colour = xentry.pixel;
1208    
1209          if (owncolmap)                          /* update our cache */
1210                            if (xentry.pixel < 256)
1211                            {
1212                                    xc_cache[xentry.pixel].red = xentry.red;
1213                                    xc_cache[xentry.pixel].green = xentry.green;
1214                                    xc_cache[xentry.pixel].blue = xentry.blue;
1215    
1216                            }
1217    
1218    
1219                            /* byte swap here to make translate_image faster */
1220                            map[i] = translate_colour(colour);
1221                    }
1222                    return map;
1223            }
1224            else
1225          {          {
1226                  XColor *xcolours, *xentry;                  XColor *xcolours, *xentry;
1227                  Colormap map;                  Colormap map;
# Line 822  ui_create_colourmap(COLOURMAP *colours) Line 1239  ui_create_colourmap(COLOURMAP *colours)
1239                  XStoreColors(display, map, xcolours, ncolours);                  XStoreColors(display, map, xcolours, ncolours);
1240    
1241                  xfree(xcolours);                  xfree(xcolours);
1242                  return (HCOLOURMAP)map;                  return (HCOLOURMAP) map;
         }  
         else  
         {  
                 uint32 *map = xmalloc(sizeof(*colmap) * ncolours);  
                 XColor xentry;  
                 uint32 colour;  
   
                 for (i = 0; i < ncolours; i++)  
                 {  
                         entry = &colours->colours[i];  
                         MAKE_XCOLOR(&xentry, entry);  
   
                         if (XAllocColor(display, xcolmap, &xentry) != 0)  
                                 colour = xentry.pixel;  
                         else  
                                 colour = white;  
   
                         /* byte swap here to make translate_image faster */  
                         map[i] = translate_colour(colour);  
                 }  
   
                 return map;  
1243          }          }
1244  }  }
1245    
1246  void  void
1247  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
1248  {  {
1249          if (owncolmap)          if (!owncolmap)
                 XFreeColormap(display, (Colormap)map);  
         else  
1250                  xfree(map);                  xfree(map);
1251            else
1252                    XFreeColormap(display, (Colormap) map);
1253  }  }
1254    
1255  void  void
1256  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
1257  {  {
1258          if (owncolmap)          if (!owncolmap)
                 XSetWindowColormap(display, wnd, (Colormap)map);  
         else  
1259                  colmap = map;                  colmap = map;
1260            else
1261                    XSetWindowColormap(display, wnd, (Colormap) map);
1262  }  }
1263    
1264  void  void
# Line 879  ui_set_clip(int x, int y, int cx, int cy Line 1274  ui_set_clip(int x, int y, int cx, int cy
1274  }  }
1275    
1276  void  void
1277  ui_reset_clip()  ui_reset_clip(void)
1278  {  {
1279          XRectangle rect;          XRectangle rect;
1280    
# Line 891  ui_reset_clip() Line 1286  ui_reset_clip()
1286  }  }
1287    
1288  void  void
1289  ui_bell()  ui_bell(void)
1290  {  {
1291          XBell(display, 0);          XBell(display, 0);
1292  }  }
# Line 908  ui_destblt(uint8 opcode, Line 1303  ui_destblt(uint8 opcode,
1303  void  void
1304  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
1305            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1306            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1307  {  {
1308          Pixmap fill;          Pixmap fill;
1309            uint8 i, ipattern[8];
1310    
1311          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1312    
# Line 922  ui_patblt(uint8 opcode, Line 1318  ui_patblt(uint8 opcode,
1318                          break;                          break;
1319    
1320                  case 3: /* Pattern */                  case 3: /* Pattern */
1321                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);                          for (i = 0; i != 8; i++)
1322                                    ipattern[7 - i] = brush->pattern[i];
1323                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
1324    
1325                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
1326                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
# Line 933  ui_patblt(uint8 opcode, Line 1331  ui_patblt(uint8 opcode,
1331                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1332    
1333                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
1334                          ui_destroy_glyph((HGLYPH)fill);                          XSetTSOrigin(display, gc, 0, 0);
1335                            ui_destroy_glyph((HGLYPH) fill);
1336                          break;                          break;
1337    
1338                  default:                  default:
# Line 951  ui_screenblt(uint8 opcode, Line 1350  ui_screenblt(uint8 opcode,
1350          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1351          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1352          if (ownbackstore)          if (ownbackstore)
1353                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1354          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1355  }  }
1356    
# Line 962  ui_memblt(uint8 opcode, Line 1360  ui_memblt(uint8 opcode,
1360            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1361  {  {
1362          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1363          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1364          if (ownbackstore)          if (ownbackstore)
1365                  XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1366          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1367  }  }
1368    
# Line 973  void Line 1370  void
1370  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
1371            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1372            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ HBITMAP src, int srcx, int srcy,
1373            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1374  {  {
1375          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
1376             comes up with a more efficient way of doing it I am using cases. */             comes up with a more efficient way of doing it I am using cases. */
# Line 982  ui_triblt(uint8 opcode, Line 1379  ui_triblt(uint8 opcode,
1379          {          {
1380                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1381                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1382                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1383                          break;                          break;
1384    
1385                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1386                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1387                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1388                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1389                          break;                          break;
1390    
1391                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1392                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1393                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1394                          break;                          break;
1395    
1396                  default:                  default:
# Line 1009  ui_triblt(uint8 opcode, Line 1402  ui_triblt(uint8 opcode,
1402  void  void
1403  ui_line(uint8 opcode,  ui_line(uint8 opcode,
1404          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
1405          /* pen */ PEN *pen)          /* pen */ PEN * pen)
1406  {  {
1407          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1408          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
# Line 1028  ui_rect( Line 1421  ui_rect(
1421          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
1422  }  }
1423    
1424    /* warning, this function only draws on wnd or backstore, not both */
1425  void  void
1426  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1427                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1428                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1429                int fgcolour)                int bgcolour, int fgcolour)
1430  {  {
1431          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1432          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1433    
1434          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(display, gc,
1435                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1436          XSetStipple(display, gc, (Pixmap)glyph);          XSetStipple(display, gc, (Pixmap) glyph);
1437          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
1438    
1439          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
1440    
1441          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(display, gc, FillSolid);
1442  }  }
# Line 1056  ui_draw_glyph(int mixmode, Line 1450  ui_draw_glyph(int mixmode,
1450        if ((xyoffset & 0x80))\        if ((xyoffset & 0x80))\
1451          {\          {\
1452            if (flags & TEXT2_VERTICAL) \            if (flags & TEXT2_VERTICAL) \
1453              y += ttext[++idx] | (ttext[++idx] << 8);\              y += ttext[idx+1] | (ttext[idx+2] << 8);\
1454            else\            else\
1455              x += ttext[++idx] | (ttext[++idx] << 8);\              x += ttext[idx+1] | (ttext[idx+2] << 8);\
1456              idx += 2;\
1457          }\          }\
1458        else\        else\
1459          {\          {\
# Line 1070  ui_draw_glyph(int mixmode, Line 1465  ui_draw_glyph(int mixmode,
1465      }\      }\
1466    if (glyph != NULL)\    if (glyph != NULL)\
1467      {\      {\
1468        ui_draw_glyph (mixmode, x + (short) glyph->offset,\        ui_draw_glyph (mixmode, x + glyph->offset,\
1469                       y + (short) glyph->baseline,\                       y + glyph->baseline,\
1470                       glyph->width, glyph->height,\                       glyph->width, glyph->height,\
1471                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1472        if (flags & TEXT2_IMPLICIT_X)\        if (flags & TEXT2_IMPLICIT_X)\
# Line 1081  ui_draw_glyph(int mixmode, Line 1476  ui_draw_glyph(int mixmode,
1476    
1477  void  void
1478  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
1479               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1480               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1481               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1482  {  {
1483          FONTGLYPH *glyph;          FONTGLYPH *glyph;
# Line 1093  ui_draw_text(uint8 font, uint8 flags, in Line 1488  ui_draw_text(uint8 font, uint8 flags, in
1488    
1489          if (boxcx > 1)          if (boxcx > 1)
1490          {          {
1491                  FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
1492          }          }
1493          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
1494          {          {
1495                  FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
1496          }          }
1497    
1498          /* Paint text, character by character */          /* Paint text, character by character */
1499          for (i = 0; i < length;) {          for (i = 0; i < length;)
1500                  switch (text[i]) {          {
1501                  case 0xff:                  switch (text[i])
1502                          if (i + 2 < length)                  {
1503                                  cache_put_text(text[i + 1], text, text[i + 2]);                          case 0xff:
1504                          else {                                  if (i + 2 < length)
1505                                  error("this shouldn't be happening\n");                                          cache_put_text(text[i + 1], text, text[i + 2]);
1506                                    else
1507                                    {
1508                                            error("this shouldn't be happening\n");
1509                                            exit(1);
1510                                    }
1511                                    /* this will move pointer from start to first character after FF command */
1512                                    length -= i + 3;
1513                                    text = &(text[i + 3]);
1514                                    i = 0;
1515                                  break;                                  break;
                         }  
                         /* this will move pointer from start to first character after FF command */  
                         length -= i + 3;  
                         text = &(text[i + 3]);  
                         i = 0;  
                         break;  
1516    
1517                  case 0xfe:                          case 0xfe:
1518                          entry = cache_get_text(text[i + 1]);                                  entry = cache_get_text(text[i + 1]);
1519                          if (entry != NULL) {                                  if (entry != NULL)
1520                                  if ((((uint8 *) (entry->data))[1] == 0)                                  {
1521                                      && (!(flags & TEXT2_IMPLICIT_X))) {                                          if ((((uint8 *) (entry->data))[1] ==
1522                                          if (flags & TEXT2_VERTICAL)                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
1523                                                  y += text[i + 2];                                          {
1524                                          else                                                  if (flags & TEXT2_VERTICAL)
1525                                                  x += text[i + 2];                                                          y += text[i + 2];
1526                                                    else
1527                                                            x += text[i + 2];
1528                                            }
1529                                            for (j = 0; j < entry->size; j++)
1530                                                    DO_GLYPH(((uint8 *) (entry->data)), j);
1531                                  }                                  }
1532                                  if (i + 2 < length)                                  if (i + 2 < length)
1533                                          i += 3;                                          i += 3;
1534                                  else                                  else
1535                                          i += 2;                                          i += 2;
1536                                  length -= i;                                  length -= i;
1537                                  /* this will move pointer from start to first character after FE command */                                  /* this will move pointer from start to first character after FE command */
1538                                  text = &(text[i]);                                  text = &(text[i]);
1539                                  i = 0;                                  i = 0;
1540                                  for (j = 0; j < entry->size; j++)                                  break;
                                         DO_GLYPH(((uint8 *) (entry->data)), j);  
                         }  
                         break;  
1541    
1542                  default:                          default:
1543                          DO_GLYPH(text, i);                                  DO_GLYPH(text, i);
1544                          i++;                                  i++;
1545                          break;                                  break;
1546                  }                  }
1547          }          }
1548            if (ownbackstore)
1549            {
1550                    if (boxcx > 1)
1551                            XCopyArea(display, backstore, wnd, gc, boxx,
1552                                      boxy, boxcx, boxcy, boxx, boxy);
1553                    else
1554                            XCopyArea(display, backstore, wnd, gc, clipx,
1555                                      clipy, clipcx, clipcy, clipx, clipy);
1556            }
1557  }  }
1558    
1559  void  void
# Line 1157  ui_desktop_save(uint32 offset, int x, in Line 1564  ui_desktop_save(uint32 offset, int x, in
1564    
1565          if (ownbackstore)          if (ownbackstore)
1566          {          {
1567                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1568          }          }
1569          else          else
1570          {          {
1571                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(display, wnd, cx, cy, depth);
1572                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1573                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1574                  XFreePixmap(display, pix);                  XFreePixmap(display, pix);
1575          }          }
1576    
1577          offset *= bpp/8;          offset *= bpp / 8;
1578          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line, bpp / 8, (uint8 *) image->data);
                           bpp/8, (uint8 *)image->data);  
1579    
1580          XDestroyImage(image);          XDestroyImage(image);
1581  }  }
# Line 1182  ui_desktop_restore(uint32 offset, int x, Line 1586  ui_desktop_restore(uint32 offset, int x,
1586          XImage *image;          XImage *image;
1587          uint8 *data;          uint8 *data;
1588    
1589          offset *= bpp/8;          offset *= bpp / 8;
1590          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp / 8);
1591          if (data == NULL)          if (data == NULL)
1592                  return;                  return;
1593    
1594          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1595                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);
                              cx * bpp/8);  
1596    
1597          if (ownbackstore)          if (ownbackstore)
1598          {          {

Legend:
Removed from v.53  
changed lines
  Added in v.316

  ViewVC Help
Powered by ViewVC 1.1.26