/[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 54 by n-ki, Fri Jun 7 07:49:59 2002 UTC revision 342 by astrand, Fri Mar 14 12:00:17 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    extern int win_button_size;
36    BOOL enable_compose = False;
37    BOOL focused;
38    BOOL mouse_in_wnd;
39    
40  Display *display;  Display *display;
 XkbDescPtr xkb;  
41  static int x_socket;  static int x_socket;
42    static Screen *screen;
43  static Window wnd;  static Window wnd;
44  static GC gc;  static GC gc;
45  static Visual *visual;  static Visual *visual;
46  static int depth;  static int depth;
47  static int bpp;  static int bpp;
48    static XIM IM;
49    static XIC IC;
50    static XModifierKeymap *mod_map;
51    static Cursor current_cursor;
52    static Atom protocol_atom, kill_atom;
53    
54  /* endianness */  /* endianness */
55  static BOOL host_be;  static BOOL host_be;
# Line 49  static BOOL xserver_be; Line 59  static BOOL xserver_be;
59  static BOOL ownbackstore;  static BOOL ownbackstore;
60  static Pixmap backstore;  static Pixmap backstore;
61    
62  /* needed to keep track of the modifiers */  /* Moving in single app mode */
63  static unsigned int numlock_modifier_mask = 0;  static BOOL moving_wnd;
64  static unsigned int key_down_state = 0;  static int move_x_offset = 0;
65    static int move_y_offset = 0;
66    
67  #define DShift1Mask   (1<<0)  /* MWM decorations */
68  #define DLockMask     (1<<1)  #define MWM_HINTS_DECORATIONS   (1L << 1)
69  #define DControl1Mask (1<<2)  #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
70  #define DMod1Mask     (1<<3)  typedef struct
71  #define DMod2Mask     (1<<4)  {
72  #define DMod3Mask     (1<<5)          uint32 flags;
73  #define DMod4Mask     (1<<6)          uint32 functions;
74  #define DMod5Mask     (1<<7)          uint32 decorations;
75  #define DShift2Mask   (1<<8)          sint32 inputMode;
76  #define DControl2Mask (1<<9)          uint32 status;
77  #define DNumLockMask  (1<<10)  }
78    PropMotifWmHints;
79    
80    typedef struct
81    {
82            uint32 red;
83            uint32 green;
84            uint32 blue;
85    }
86    PixelColour;
87    
88  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
89  { \  { \
# Line 73  static unsigned int key_down_state = 0; Line 92  static unsigned int key_down_state = 0;
92                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \
93  }  }
94    
95    #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\
96    { \
97            XFillRectangle(display, ownbackstore ? backstore : wnd, gc, x, y, cx, cy); \
98    }
99    
100  /* colour maps */  /* colour maps */
101  static BOOL owncolmap;  BOOL owncolmap = False;
102  static Colormap xcolmap;  static Colormap xcolmap;
 static uint32 white;  
103  static uint32 *colmap;  static uint32 *colmap;
104    
105  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )  #define TRANSLATE(col)          ( server_bpp != 8 ? translate_colour(col) : owncolmap ? col : translate_colour(colmap[col]) )
106  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));
107  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));
108    
# Line 105  static int rop2_map[] = { Line 128  static int rop2_map[] = {
128  #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]); }
129  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
130    
131  void xwin_get_numlock_mask();  static void
132  void xwin_mod_update(uint32 state, uint32 ev_time );  mwm_hide_decorations(void)
133  void xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode);  {
134  void xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode);          PropMotifWmHints motif_hints;
135            Atom hintsatom;
136    
137            /* setup the property */
138            motif_hints.flags = MWM_HINTS_DECORATIONS;
139            motif_hints.decorations = 0;
140    
141            /* get the atom for the property */
142            hintsatom = XInternAtom(display, "_MOTIF_WM_HINTS", False);
143            if (!hintsatom)
144            {
145                    warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");
146                    return;
147            }
148    
149            XChangeProperty(display, wnd, hintsatom, hintsatom, 32, PropModeReplace,
150                            (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
151    }
152    
153    static PixelColour
154    split_colour15(uint32 colour)
155    {
156            PixelColour rv;
157            rv.red = (colour & 0x7c00) >> 10;
158            rv.red = (rv.red * 0xff) / 0x1f;
159            rv.green = (colour & 0x03e0) >> 5;
160            rv.green = (rv.green * 0xff) / 0x1f;
161            rv.blue = (colour & 0x1f);
162            rv.blue = (rv.blue * 0xff) / 0x1f;
163            return rv;
164    }
165    
166    static PixelColour
167    split_colour16(uint32 colour)
168    {
169            PixelColour rv;
170            rv.red = (colour & 0xf800) >> 11;
171            rv.red = (rv.red * 0xff) / 0x1f;
172            rv.green = (colour & 0x07e0) >> 5;
173            rv.green = (rv.green * 0xff) / 0x3f;
174            rv.blue = (colour & 0x001f);
175            rv.blue = (rv.blue * 0xff) / 0x1f;
176            return rv;
177    }
178    
179    static PixelColour
180    split_colour24(uint32 colour)
181    {
182            PixelColour rv;
183            rv.blue = (colour & 0xff0000) >> 16;
184            rv.green = (colour & 0xff00) >> 8;
185            rv.red = (colour & 0xff);
186            return rv;
187    }
188    
189    static uint32
190    make_colour16(PixelColour pc)
191    {
192            pc.red = (pc.red * 0x1f) / 0xff;
193            pc.green = (pc.green * 0x3f) / 0xff;
194            pc.blue = (pc.blue * 0x1f) / 0xff;
195            return (pc.red << 11) | (pc.green << 5) | pc.blue;
196    }
197    
198    static uint32
199    make_colour24(PixelColour pc)
200    {
201            return (pc.red << 16) | (pc.green << 8) | pc.blue;
202    }
203    
204    static uint32
205    make_colour32(PixelColour pc)
206    {
207            return (pc.red << 16) | (pc.green << 8) | pc.blue;
208    }
209    
210    #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
211    #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }
212    #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
213                            x = (x << 16) | (x >> 16); }
214    
215    static uint32
216    translate_colour(uint32 colour)
217    {
218            switch (server_bpp)
219            {
220                    case 15:
221                            switch (bpp)
222                            {
223                                    case 16:
224                                            colour = make_colour16(split_colour15(colour));
225                                            break;
226                                    case 24:
227                                            colour = make_colour24(split_colour15(colour));
228                                            break;
229                                    case 32:
230                                            colour = make_colour32(split_colour15(colour));
231                                            break;
232                            }
233                            break;
234                    case 16:
235                            switch (bpp)
236                            {
237                                    case 16:
238                                            break;
239                                    case 24:
240                                            colour = make_colour24(split_colour16(colour));
241                                            break;
242                                    case 32:
243                                            colour = make_colour32(split_colour16(colour));
244                                            break;
245                            }
246                            break;
247                    case 24:
248                            switch (bpp)
249                            {
250                                    case 16:
251                                            colour = make_colour16(split_colour24(colour));
252                                            break;
253                                    case 24:
254                                            break;
255                                    case 32:
256                                            colour = make_colour32(split_colour24(colour));
257                                            break;
258                            }
259                            break;
260            }
261            switch (bpp)
262            {
263                    case 16:
264                            if (host_be != xserver_be)
265                                    BSWAP16(colour);
266                            break;
267    
268                    case 24:
269                            if (xserver_be)
270                                    BSWAP24(colour);
271                            break;
272    
273                    case 32:
274                            if (host_be != xserver_be)
275                                    BSWAP32(colour);
276                            break;
277            }
278    
279            return colour;
280    }
281    
282  static void  static void
283  translate8(uint8 *data, uint8 *out, uint8 *end)  translate8to8(uint8 * data, uint8 * out, uint8 * end)
284  {  {
285          while (out < end)          while (out < end)
286                  *(out++) = (uint8)colmap[*(data++)];                  *(out++) = (uint8) colmap[*(data++)];
287  }  }
288    
289  static void  static void
290  translate16(uint8 *data, uint16 *out, uint16 *end)  translate8to16(uint8 * data, uint16 * out, uint16 * end)
291  {  {
292          while (out < end)          while (out < end)
293                  *(out++) = (uint16)colmap[*(data++)];                  *(out++) = (uint16) colmap[*(data++)];
294  }  }
295    
296  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
297  static void  static void
298  translate24(uint8 *data, uint8 *out, uint8 *end)  translate8to24(uint8 * data, uint8 * out, uint8 * end)
299  {  {
300          uint32 value;          uint32 value;
301    
# Line 140  translate24(uint8 *data, uint8 *out, uin Line 309  translate24(uint8 *data, uint8 *out, uin
309  }  }
310    
311  static void  static void
312  translate32(uint8 *data, uint32 *out, uint32 *end)  translate8to32(uint8 * data, uint32 * out, uint32 * end)
313  {  {
314          while (out < end)          while (out < end)
315                  *(out++) = colmap[*(data++)];                  *(out++) = colmap[*(data++)];
316  }  }
317    
318  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;  
   
         switch (bpp)  
         {  
                 case 8:  
                         translate8(data, out, end);  
                         break;  
319    
320                  case 16:  static void
321                          translate16(data, (uint16 *)out, (uint16 *)end);  translate15to16(uint16 * data, uint16 * out, uint16 * end)
322                          break;  {
323            while (out < end)
324                    *(out++) = (uint16) make_colour16(split_colour15(*(data++)));
325    }
326    
327                  case 24:  static void
328                          translate24(data, out, end);  translate15to24(uint16 * data, uint8 * out, uint8 * end)
329                          break;  {
330            uint32 value;
331    
332                  case 32:          while (out < end)
333                          translate32(data, (uint32 *)out, (uint32 *)end);          {
334                          break;                  value = make_colour24(split_colour15(*(data++)));
335                    *(out++) = value;
336                    *(out++) = value >> 8;
337                    *(out++) = value >> 16;
338          }          }
339    }
340    
341          return out;  static void
342    translate15to32(uint16 * data, uint32 * out, uint32 * end)
343    {
344            while (out < end)
345                    *(out++) = make_colour32(split_colour15(*(data++)));
346  }  }
347    
348  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }  static void
349  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }  translate16to16(uint16 * data, uint16 * out, uint16 * end)
350  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \  {
351                          x = (x << 16) | (x >> 16); }          while (out < end)
352                    *(out++) = (uint16) (*(data++));
353    }
354    
355  static uint32  
356  translate_colour(uint32 colour)  static void
357    translate16to24(uint16 * data, uint8 * out, uint8 * end)
358  {  {
359          switch (bpp)          uint32 value;
360    
361            while (out < end)
362          {          {
363                  case 16:                  value = make_colour24(split_colour16(*(data++)));
364                          if (host_be != xserver_be)                  *(out++) = value;
365                                  BSWAP16(colour);                  *(out++) = value >> 8;
366                          break;                  *(out++) = value >> 16;
367            }
368    }
369    
370                  case 24:  static void
371                          if (xserver_be)  translate16to32(uint16 * data, uint32 * out, uint32 * end)
372                                  BSWAP24(colour);  {
373                          break;          while (out < end)
374                    *(out++) = make_colour32(split_colour16(*(data++)));
375    }
376    
377                  case 32:  static void
378                          if (host_be != xserver_be)  translate24to16(uint8 * data, uint16 * out, uint16 * end)
379                                  BSWAP32(colour);  {
380                          break;          uint32 pixel = 0;
381            while (out < end)
382            {
383                    pixel = *(data++) << 16;
384                    pixel |= *(data++) << 8;
385                    pixel |= *(data++);
386                    *(out++) = (uint16) make_colour16(split_colour24(pixel));
387          }          }
388    }
389    
390          return colour;  static void
391    translate24to24(uint8 * data, uint8 * out, uint8 * end)
392    {
393            while (out < end)
394            {
395                    *(out++) = (*(data++));
396            }
397  }  }
398    
399  BOOL  static void
400  ui_create_window(char *title)  translate24to32(uint8 * data, uint32 * out, uint32 * end)
401  {  {
402          XSetWindowAttributes attribs;          uint32 pixel = 0;
403          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 )  
404          {          {
405                  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);
406                  return False;                  data += 3;
407                    *(out++) = pixel;
408          }          }
409    }
410    
411    static uint8 *
412    translate_image(int width, int height, uint8 * data)
413    {
414            int size = width * height * bpp / 8;
415            uint8 *out = xmalloc(size);
416            uint8 *end = out + size;
417    
418          display = XkbOpenDisplay( NULL, &xkb_event, &xkb_error, &xkb_major, &xkb_minor, &xkb_reason );          switch (server_bpp)
         switch(xkb_reason)  
419          {          {
420                  case XkbOD_BadLibraryVersion:                  case 24:
421                          error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n");                          switch (bpp)
422                          break;                          {
423                  case XkbOD_ConnectionRefused:                                  case 32:
424                          error("XkbOD_ConnectionRefused\n");                                          translate24to32(data, (uint32 *) out, (uint32 *) end);
425                                            break;
426                                    case 24:
427                                            translate24to24(data, out, end);
428                                            break;
429                                    case 16:
430                                            translate24to16(data, (uint16 *) out, (uint16 *) end);
431                                            break;
432                            }
433                          break;                          break;
434                  case XkbOD_BadServerVersion:                  case 16:
435                          error("XkbOD_BadServerVersion\n");                          switch (bpp)
436                            {
437                                    case 32:
438                                            translate16to32((uint16 *) data, (uint32 *) out,
439                                                            (uint32 *) end);
440                                            break;
441                                    case 24:
442                                            translate16to24((uint16 *) data, out, end);
443                                            break;
444                                    case 16:
445                                            translate16to16((uint16 *) data, (uint16 *) out,
446                                                            (uint16 *) end);
447                                            break;
448                            }
449                          break;                          break;
450                  case XkbOD_NonXkbServer:                  case 15:
451                          error("XkbOD_NonXkbServer: XKB extension not present in server\nupdate your X server.\n");                          switch (bpp)
452                            {
453                                    case 32:
454                                            translate15to32((uint16 *) data, (uint32 *) out,
455                                                            (uint32 *) end);
456                                            break;
457                                    case 24:
458                                            translate15to24((uint16 *) data, out, end);
459                                            break;
460                                    case 16:
461                                            translate15to16((uint16 *) data, (uint16 *) out,
462                                                            (uint16 *) end);
463                                            break;
464                            }
465                          break;                          break;
466                  case XkbOD_Success:                  case 8:
467                          DEBUG("XkbOD_Success: Connection established with display\n");                          switch (bpp)
468                            {
469                                    case 8:
470                                            translate8to8(data, out, end);
471                                            break;
472                                    case 16:
473                                            translate8to16(data, (uint16 *) out, (uint16 *) end);
474                                            break;
475                                    case 24:
476                                            translate8to24(data, out, end);
477                                            break;
478                                    case 32:
479                                            translate8to32(data, (uint32 *) out, (uint32 *) end);
480                                            break;
481                            }
482                          break;                          break;
483          }          }
484            return out;
485    }
486    
487    BOOL
488    get_key_state(unsigned int state, uint32 keysym)
489    {
490            int modifierpos, key, keysymMask = 0;
491            int offset;
492    
493            KeyCode keycode = XKeysymToKeycode(display, keysym);
494    
495            if (keycode == NoSymbol)
496                    return False;
497    
498            for (modifierpos = 0; modifierpos < 8; modifierpos++)
499            {
500                    offset = mod_map->max_keypermod * modifierpos;
501    
502                    for (key = 0; key < mod_map->max_keypermod; key++)
503                    {
504                            if (mod_map->modifiermap[offset + key] == keycode)
505                                    keysymMask |= 1 << modifierpos;
506                    }
507            }
508    
509            return (state & keysymMask) ? True : False;
510    }
511    
512    BOOL
513    ui_init(void)
514    {
515            XPixmapFormatValues *pfm;
516            uint16 test;
517            int i;
518    
519            display = XOpenDisplay(NULL);
520          if (display == NULL)          if (display == NULL)
521          {          {
522                  error("Failed to open display\n");                  error("Failed to open display: %s\n", XDisplayName(NULL));
523                  return False;                  return False;
524          }          }
525    
# Line 259  ui_create_window(char *title) Line 527  ui_create_window(char *title)
527          screen = DefaultScreenOfDisplay(display);          screen = DefaultScreenOfDisplay(display);
528          visual = DefaultVisualOfScreen(screen);          visual = DefaultVisualOfScreen(screen);
529          depth = DefaultDepthOfScreen(screen);          depth = DefaultDepthOfScreen(screen);
530            
531          pfm = XListPixmapFormats(display, &i);          pfm = XListPixmapFormats(display, &i);
532          if (pfm != NULL)          if (pfm != NULL)
533          {          {
# Line 267  ui_create_window(char *title) Line 535  ui_create_window(char *title)
535                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
536                  while (i--)                  while (i--)
537                  {                  {
538                          if ((pfm[i].depth == depth)                          if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))
                             && (pfm[i].bits_per_pixel > bpp))  
539                          {                          {
540                                  bpp = pfm[i].bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
541                          }                          }
# Line 283  ui_create_window(char *title) Line 550  ui_create_window(char *title)
550                  return False;                  return False;
551          }          }
552    
553          if (depth <= 8)          if (owncolmap != True)
554                  owncolmap = True;          {
         else  
555                  xcolmap = DefaultColormapOfScreen(screen);                  xcolmap = DefaultColormapOfScreen(screen);
556                    if (depth <= 8)
557                            warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");
558            }
559    
560            gc = XCreateGC(display, RootWindowOfScreen(screen), 0, NULL);
561    
562            if (DoesBackingStore(screen) != Always)
563                    ownbackstore = True;
564    
565          test = 1;          test = 1;
566          host_be = !(BOOL)(*(uint8 *)(&test));          host_be = !(BOOL) (*(uint8 *) (&test));
567          xserver_be = (ImageByteOrder(display) == MSBFirst);          xserver_be = (ImageByteOrder(display) == MSBFirst);
568    
569          white = WhitePixelOfScreen(screen);          if ((width == 0) || (height == 0))
570          attribs.background_pixel = BlackPixelOfScreen(screen);          {
571          attribs.backing_store = DoesBackingStore(screen);                  /* Fetch geometry from _NET_WORKAREA */
572                    uint32 x, y, cx, cy;
573    
574          if (attribs.backing_store == NotUseful)                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)
575                  ownbackstore = True;                  {
576                            width = cx;
577                            height = cy;
578                    }
579                    else
580                    {
581                            warning("Failed to get workarea: probably your window manager does not support extended hints\n");
582                            width = 800;
583                            height = 600;
584                    }
585            }
586    
587          if (fullscreen)          if (fullscreen)
588          {          {
                 attribs.override_redirect = True;  
589                  width = WidthOfScreen(screen);                  width = WidthOfScreen(screen);
590                  height = HeightOfScreen(screen);                  height = HeightOfScreen(screen);
591          }          }
592          else  
593            /* make sure width is a multiple of 4 */
594            width = (width + 3) & ~3;
595    
596            if (ownbackstore)
597          {          {
598                  attribs.override_redirect = False;                  backstore =
599                            XCreatePixmap(display, RootWindowOfScreen(screen), width, height, depth);
600    
601                    /* clear to prevent rubbish being exposed at startup */
602                    XSetForeground(display, gc, BlackPixelOfScreen(screen));
603                    XFillRectangle(display, backstore, gc, 0, 0, width, height);
604          }          }
605    
606          width = (width + 3) & ~3; /* make width a multiple of 32 bits */          mod_map = XGetModifierMapping(display);
607    
608            if (enable_compose)
609                    IM = XOpenIM(display, NULL, NULL, NULL);
610    
611            xkeymap_init();
612    
613            /* todo take this out when high colour is done */
614            printf("server bpp %d client bpp %d depth %d\n", server_bpp, bpp, depth);
615    
616            return True;
617    }
618    
619    void
620    ui_deinit(void)
621    {
622            if (IM != NULL)
623                    XCloseIM(IM);
624    
625            XFreeModifiermap(mod_map);
626    
627            if (ownbackstore)
628                    XFreePixmap(display, backstore);
629    
630            XFreeGC(display, gc);
631            XCloseDisplay(display);
632            display = NULL;
633    }
634    
635    BOOL
636    ui_create_window(void)
637    {
638            XSetWindowAttributes attribs;
639            XClassHint *classhints;
640            XSizeHints *sizehints;
641            int wndwidth, wndheight;
642            long input_mask, ic_input_mask;
643            XEvent xevent;
644    
645            wndwidth = fullscreen ? WidthOfScreen(screen) : width;
646            wndheight = fullscreen ? HeightOfScreen(screen) : height;
647    
648            attribs.background_pixel = BlackPixelOfScreen(screen);
649            attribs.backing_store = ownbackstore ? NotUseful : Always;
650            attribs.override_redirect = fullscreen;
651    
652          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          wnd = XCreateWindow(display, RootWindowOfScreen(screen), 0, 0, wndwidth, wndheight,
653                              0, 0, width, height, 0, CopyFromParent,                              0, CopyFromParent, InputOutput, CopyFromParent,
654                              InputOutput, CopyFromParent,                              CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);
                             CWBackingStore | CWBackPixel | CWOverrideRedirect,  
                             &attribs);  
655    
656          XStoreName(display, wnd, title);          XStoreName(display, wnd, title);
657    
658            if (hide_decorations)
659                    mwm_hide_decorations();
660    
661          classhints = XAllocClassHint();          classhints = XAllocClassHint();
662          if (classhints != NULL)          if (classhints != NULL)
663          {          {
# Line 338  ui_create_window(char *title) Line 676  ui_create_window(char *title)
676                  XFree(sizehints);                  XFree(sizehints);
677          }          }
678    
679          xkeymap_init();          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
680                    VisibilityChangeMask | FocusChangeMask;
681    
         input_mask = KeyPressMask | KeyReleaseMask |  
                          ButtonPressMask | ButtonReleaseMask |  
                          EnterWindowMask | LeaveWindowMask;  
682          if (sendmotion)          if (sendmotion)
683                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
   
684          if (ownbackstore)          if (ownbackstore)
685                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
686            if (fullscreen || grab_keyboard)
687                    input_mask |= EnterWindowMask;
688            if (grab_keyboard)
689                    input_mask |= LeaveWindowMask;
690    
691            if (IM != NULL)
692            {
693                    IC = XCreateIC(IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
694                                   XNClientWindow, wnd, XNFocusWindow, wnd, NULL);
695    
696                    if ((IC != NULL)
697                        && (XGetICValues(IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
698                            input_mask |= ic_input_mask;
699            }
700    
701          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);  
   
702          XMapWindow(display, wnd);          XMapWindow(display, wnd);
703    
704          /* TODO: error texts... make them friendly. */          /* wait for VisibilityNotify */
705          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 )  
706          {          {
707                          error( "XkbSelectEvents failed.\n");                  XMaskEvent(display, VisibilityChangeMask, &xevent);
                         exit(0);  
708          }          }
709                    while (xevent.type != VisibilityNotify);
710          xwin_get_numlock_mask();  
711            focused = False;
712            mouse_in_wnd = False;
713    
714            /* handle the WM_DELETE_WINDOW protocol */
715            protocol_atom = XInternAtom(display, "WM_PROTOCOLS", True);
716            kill_atom = XInternAtom(display, "WM_DELETE_WINDOW", True);
717            XSetWMProtocols(display, wnd, &kill_atom, 1);
718    
719          return True;          return True;
720  }  }
721    
722  void  void
723  xwin_get_numlock_mask()  ui_destroy_window(void)
724  {  {
725          KeyCode numlockcode;          if (IC != NULL)
726          KeyCode* keycode;                  XDestroyIC(IC);
         XModifierKeymap *modmap;  
         int i,j;  
   
         /* Find out if numlock is already defined as a modifier key, and if so where */  
         numlockcode = XKeysymToKeycode(display, 0xFF7F);        /* XF_Num_Lock = 0xFF7F */  
         if (numlockcode) {  
                 modmap = XGetModifierMapping(display);  
                 if (modmap) {  
                         keycode = modmap->modifiermap;  
                         for (i = 0; i < 8; i++)  
                                 for (j = modmap->max_keypermod; j--;) {  
                                         if (*keycode == numlockcode) {  
                                                 numlock_modifier_mask = (1 << i);  
                                                 i = 8;  
                                                 break;  
                                         }  
                                         keycode++;  
                                 }  
                 if (!numlock_modifier_mask) {  
                                 modmap->modifiermap[7 * modmap->max_keypermod] = numlockcode;  
                                 if (XSetModifierMapping(display, modmap) == MappingSuccess)  
                                         numlock_modifier_mask = (1 << 7);  
                                 else  
                                         printf("XSetModifierMapping failed!\n");  
                         }  
                         XFreeModifiermap(modmap);  
                 }  
         }  
727    
728          if (!numlock_modifier_mask)          XDestroyWindow(display, wnd);
                 printf("WARNING: Failed to get a numlock modifier mapping.\n");  
                   
729  }  }
730    
731  void  void
732  ui_destroy_window()  xwin_toggle_fullscreen(void)
733  {  {
734          if( xkb != NULL )          Pixmap contents = 0;
                 XkbFreeKeyboard(xkb, XkbAllControlsMask, True);  
735    
736          if (ownbackstore)          if (!ownbackstore)
737                  XFreePixmap(display, backstore);          {
738                    /* need to save contents of window */
739                    contents = XCreatePixmap(display, wnd, width, height, depth);
740                    XCopyArea(display, wnd, contents, gc, 0, 0, width, height, 0, 0);
741            }
742    
743          XFreeGC(display, gc);          ui_destroy_window();
744          XDestroyWindow(display, wnd);          fullscreen = !fullscreen;
745          XCloseDisplay(display);          ui_create_window();
746          display = NULL;  
747            XDefineCursor(display, wnd, current_cursor);
748    
749            if (!ownbackstore)
750            {
751                    XCopyArea(display, contents, wnd, gc, 0, 0, width, height, 0, 0);
752                    XFreePixmap(display, contents);
753            }
754  }  }
755    
756  static void  /* Process all events in Xlib queue
757  xwin_process_events()     Returns 0 after user quit, 1 otherwise */
758    static int
759    xwin_process_events(void)
760  {  {
761          XEvent xevent;          XEvent xevent;
   
762          KeySym keysym;          KeySym keysym;
         uint8 scancode;  
763          uint16 button, flags;          uint16 button, flags;
764          uint32 ev_time;          uint32 ev_time;
765          uint32 tmpmods;          key_translation tr;
766            char str[256];
767            Status status;
768            unsigned int state;
769            Window wdummy;
770            int dummy;
771    
772          while (XCheckMaskEvent(display, ~0, &xevent))          while (XPending(display) > 0)
773          {          {
774                  ev_time = time(NULL);                  XNextEvent(display, &xevent);
775    
776                    if ((IC != NULL) && (XFilterEvent(&xevent, None) == True))
777                    {
778                            DEBUG_KBD(("Filtering event\n"));
779                            continue;
780                    }
781    
782                  flags = 0;                  flags = 0;
783    
784                  switch (xevent.type)                  switch (xevent.type)
785                  {                  {
786                          case KeyRelease:                          case ClientMessage:
787                                  flags = KBD_FLAG_DOWN | KBD_FLAG_UP;                                  /* the window manager told us to quit */
788                                  /* fall through */                                  if ((xevent.xclient.message_type == protocol_atom)
789                                        && (xevent.xclient.data.l[0] == kill_atom))
790                                            /* Quit */
791                                            return 0;
792                                    break;
793    
794                          case KeyPress:                          case KeyPress:
795                                  if( XkbTranslateKeyCode(xkb, xevent.xkey.keycode, xevent.xkey.state, &tmpmods, &keysym) == False )                                  if (IC != NULL)
796                                            /* Multi_key compatible version */
797                                    {
798                                            XmbLookupString(IC,
799                                                            (XKeyPressedEvent *) &
800                                                            xevent, str, sizeof(str), &keysym, &status);
801                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
802                                            {
803                                                    error("XmbLookupString failed with status 0x%x\n",
804                                                          status);
805                                                    break;
806                                            }
807                                    }
808                                    else
809                                    {
810                                            /* Plain old XLookupString */
811                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
812                                            XLookupString((XKeyEvent *) & xevent,
813                                                          str, sizeof(str), &keysym, NULL);
814                                    }
815    
816                                    DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
817                                               get_ksname(keysym)));
818    
819                                    ev_time = time(NULL);
820                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
821                                          break;                                          break;
                                 scancode = xkeymap_translate_key(keysym, xevent.xkey.keycode, &flags);  
822    
823                                  if (scancode == 0 )                                  tr = xkeymap_translate_key(keysym,
824                                                               xevent.xkey.keycode, xevent.xkey.state);
825    
826                                    if (tr.scancode == 0)
827                                          break;                                          break;
828    
829                                  /* keep track of the modifiers -- needed for stickykeys... */                                  ensure_remote_modifiers(ev_time, tr);
830                                  if( xevent.type == KeyPress )  
831                                          xwin_mod_press( xevent.xkey.state, ev_time, scancode );                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
832                                    break;
833    
834                            case KeyRelease:
835                                    XLookupString((XKeyEvent *) & xevent, str,
836                                                  sizeof(str), &keysym, NULL);
837    
838                                    DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
839                                               get_ksname(keysym)));
840    
841                                    ev_time = time(NULL);
842                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
843                                            break;
844    
845                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, flags, scancode, 0);                                  tr = xkeymap_translate_key(keysym,
846                                                               xevent.xkey.keycode, xevent.xkey.state);
847    
848                                  if( xevent.type == KeyRelease )                                  if (tr.scancode == 0)
849                                          xwin_mod_release( xevent.xkey.state, ev_time, scancode );                                          break;
850    
851                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
852                                  break;                                  break;
853    
854                          case ButtonPress:                          case ButtonPress:
# Line 480  xwin_process_events() Line 860  xwin_process_events()
860                                  if (button == 0)                                  if (button == 0)
861                                          break;                                          break;
862    
863                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  /* If win_button_size is nonzero, enable single app mode */
864                                                 flags | button,                                  if (xevent.xbutton.y < win_button_size)
865                                                 xevent.xbutton.x,                                  {
866                                                 xevent.xbutton.y);                                          /* Stop moving window when button is released, regardless of cursor position */
867                                            if (moving_wnd && (xevent.type == ButtonRelease))
868                                                    moving_wnd = False;
869    
870                                            /*  Check from right to left: */
871    
872                                            if (xevent.xbutton.x >= width - win_button_size)
873                                            {
874                                                    /* The close button, continue */
875                                                    ;
876                                            }
877                                            else if (xevent.xbutton.x >= width - win_button_size * 2)
878                                            {
879                                                    /* The maximize/restore button. Do not send to
880                                                       server.  It might be a good idea to change the
881                                                       cursor or give some other visible indication
882                                                       that rdesktop inhibited this click */
883                                                    break;
884                                            }
885                                            else if (xevent.xbutton.x >= width - win_button_size * 3)
886                                            {
887                                                    /* The minimize button. Iconify window. */
888                                                    XIconifyWindow(display, wnd,
889                                                                   DefaultScreen(display));
890                                                    break;
891                                            }
892                                            else if (xevent.xbutton.x <= win_button_size)
893                                            {
894                                                    /* The system menu. Ignore. */
895                                                    break;
896                                            }
897                                            else
898                                            {
899                                                    /* The title bar. */
900                                                    if ((xevent.type == ButtonPress) && !fullscreen
901                                                        && hide_decorations)
902                                                    {
903                                                            moving_wnd = True;
904                                                            move_x_offset = xevent.xbutton.x;
905                                                            move_y_offset = xevent.xbutton.y;
906                                                    }
907                                                    break;
908    
909                                            }
910                                    }
911    
912                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
913                                                   flags | button, xevent.xbutton.x, xevent.xbutton.y);
914                                  break;                                  break;
915    
916                          case MotionNotify:                          case MotionNotify:
917                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  if (moving_wnd)
918                                                 MOUSE_FLAG_MOVE,                                  {
919                                                 xevent.xmotion.x,                                          XMoveWindow(display, wnd,
920                                                 xevent.xmotion.y);                                                      xevent.xmotion.x_root - move_x_offset,
921                                                        xevent.xmotion.y_root - move_y_offset);
922                                            break;
923                                    }
924    
925                                    if (fullscreen && !focused)
926                                            XSetInputFocus(display, wnd, RevertToPointerRoot,
927                                                           CurrentTime);
928                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
929                                                   MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
930                                  break;                                  break;
931    
932                          case EnterNotify:                          case FocusIn:
933                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,                                  if (xevent.xfocus.mode == NotifyGrab)
934                                                GrabModeAsync, CurrentTime);                                          break;
935                                    focused = True;
936                                    XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy,
937                                                  &dummy, &dummy, &state);
938                                    reset_modifier_keys(state);
939                                    if (grab_keyboard && mouse_in_wnd)
940                                            XGrabKeyboard(display, wnd, True,
941                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
942                                    break;
943    
944                                   xwin_mod_update( xevent.xcrossing.state, ev_time );                          case FocusOut:
945                                    if (xevent.xfocus.mode == NotifyUngrab)
946                                            break;
947                                    focused = False;
948                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
949                                            XUngrabKeyboard(display, CurrentTime);
950                                    break;
951    
952                            case EnterNotify:
953                                    /* we only register for this event when in fullscreen mode */
954                                    /* or grab_keyboard */
955                                    mouse_in_wnd = True;
956                                    if (fullscreen)
957                                    {
958                                            XSetInputFocus(display, wnd, RevertToPointerRoot,
959                                                           CurrentTime);
960                                            break;
961                                    }
962                                    if (focused)
963                                            XGrabKeyboard(display, wnd, True,
964                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
965                                  break;                                  break;
966    
967                          case LeaveNotify:                          case LeaveNotify:
968                                    /* we only register for this event when grab_keyboard */
969                                    mouse_in_wnd = False;
970                                  XUngrabKeyboard(display, CurrentTime);                                  XUngrabKeyboard(display, CurrentTime);
971                                  break;                                  break;
972    
973                          case Expose:                          case Expose:
974                                  XCopyArea(display, backstore, wnd, gc,                                  XCopyArea(display, backstore, wnd, gc,
975                                            xevent.xexpose.x, xevent.xexpose.y,                                            xevent.xexpose.x, xevent.xexpose.y,
976                                            xevent.xexpose.width, xevent.xexpose.height,                                            xevent.xexpose.width,
977                                              xevent.xexpose.height,
978                                            xevent.xexpose.x, xevent.xexpose.y);                                            xevent.xexpose.x, xevent.xexpose.y);
979                                  break;                                  break;
                 }  
         }  
 }  
   
 void  
 xwin_mod_update(uint32 state, uint32 ev_time )  
 {  
         xwin_mod_press(state, ev_time, 0);  
         xwin_mod_release(state, ev_time, 0);  
 }  
   
 void  
 xwin_mod_release(uint32 state, 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( !(numlock_modifier_mask & state) && (key_down_state & DNumLockMask) )  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);  
                 key_down_state &= ~DNumLockMask;  
         }  
   
         if( !(LockMask & state) && (key_down_state & DLockMask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);  
                 key_down_state &= ~DLockMask;  
   
         }  
   
   
         if( !(ShiftMask & state) && (key_down_state & DShift1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a, 0);  
                 key_down_state &= ~DShift1Mask;  
   
         }  
   
         if( !(ControlMask & state) && (key_down_state & DControl1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d, 0);  
                 key_down_state &= ~DControl1Mask;  
980    
981          }                          case MappingNotify:
982                                    /* Refresh keyboard mapping if it has changed. This is important for
983          if( !(Mod1Mask & state) && (key_down_state & DMod1Mask))                                     Xvnc, since it allocates keycodes dynamically */
984          {                                  if (xevent.xmapping.request == MappingKeyboard
985                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38, 0);                                      || xevent.xmapping.request == MappingModifier)
986                  key_down_state &= ~DMod1Mask;                                          XRefreshKeyboardMapping(&xevent.xmapping);
   
         }  
   
         if( !(Mod2Mask & state) && (key_down_state & DMod2Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8, 0);  
                 key_down_state &= ~DMod2Mask;  
         }  
 }  
   
   
 void  
 xwin_mod_press(uint32 state, 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 0x3a:  
                 key_down_state ^= DLockMask;  
                 break;  
         case 0x45:  
                 key_down_state ^= DNumLockMask;  
                 break;  
         case 0x38:  
                 key_down_state |= DMod1Mask;  
                 break;  
         case 0xb8:  
                 key_down_state |= DMod2Mask;  
                 break;  
         }  
   
         if( (numlock_modifier_mask && state) && !(key_down_state & DNumLockMask) )  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);  
                 key_down_state |= DNumLockMask;  
         }  
   
         if( (LockMask & state) && !(key_down_state & DLockMask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);  
                 key_down_state |= DLockMask;  
   
         }  
   
   
         if( (ShiftMask & 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 & 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 & state) && !(key_down_state & DMod1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x38, 0);  
                 key_down_state |= DMod1Mask;  
   
         }  
987    
988          if( (Mod2Mask & state) && !(key_down_state & DMod2Mask))                                  if (xevent.xmapping.request == MappingModifier)
989          {                                  {
990                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0xb8, 0);                                          XFreeModifiermap(mod_map);
991                  key_down_state |= DMod2Mask;                                          mod_map = XGetModifierMapping(display);
992                                    }
993                                    break;
994    
995                    }
996          }          }
997            /* Keep going */
998            return 1;
999  }  }
1000    
1001  void  /* Returns 0 after user quit, 1 otherwise */
1002    int
1003  ui_select(int rdp_socket)  ui_select(int rdp_socket)
1004  {  {
1005          int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
1006          fd_set rfds;          fd_set rfds;
1007    
1008          FD_ZERO(&rfds);          FD_ZERO(&rfds);
1009    
1010          while (True)          while (True)
1011          {          {
1012                    /* Process any events already waiting */
1013                    if (!xwin_process_events())
1014                            /* User quit */
1015                            return 0;
1016    
1017                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
1018                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
1019                  if (display != NULL)                  FD_SET(x_socket, &rfds);
                 {  
                         FD_SET(x_socket, &rfds);  
                         XFlush(display);  
                 }  
1020    
1021                  switch (select(n, &rfds, NULL, NULL, NULL))                  switch (select(n, &rfds, NULL, NULL, NULL))
1022                  {                  {
# Line 693  ui_select(int rdp_socket) Line 1027  ui_select(int rdp_socket)
1027                                  continue;                                  continue;
1028                  }                  }
1029    
                 if (FD_ISSET(x_socket, &rfds))  
                         xwin_process_events();  
   
1030                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
1031                          return;                          return 1;
1032          }          }
1033  }  }
1034    
# Line 708  ui_move_pointer(int x, int y) Line 1039  ui_move_pointer(int x, int y)
1039  }  }
1040    
1041  HBITMAP  HBITMAP
1042  ui_create_bitmap(int width, int height, uint8 *data)  ui_create_bitmap(int width, int height, uint8 * data)
1043  {  {
1044          XImage *image;          XImage *image;
1045          Pixmap bitmap;          Pixmap bitmap;
# Line 716  ui_create_bitmap(int width, int height, Line 1047  ui_create_bitmap(int width, int height,
1047    
1048          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
1049          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
1050          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1051                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, server_bpp == 8 ? 8 : bpp, 0);
1052    
1053          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
1054    
# Line 728  ui_create_bitmap(int width, int height, Line 1059  ui_create_bitmap(int width, int height,
1059  }  }
1060    
1061  void  void
1062  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)  
1063  {  {
1064          XImage *image;          XImage *image;
1065          uint8 *tdata;          uint8 *tdata;
   
1066          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
1067          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1068                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, server_bpp == 8 ? 8 : bpp, 0);
1069    
1070          if (ownbackstore)          if (ownbackstore)
1071          {          {
# Line 756  ui_paint_bitmap(int x, int y, int cx, in Line 1085  ui_paint_bitmap(int x, int y, int cx, in
1085  void  void
1086  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
1087  {  {
1088          XFreePixmap(display, (Pixmap)bmp);          XFreePixmap(display, (Pixmap) bmp);
1089  }  }
1090    
1091  HGLYPH  HGLYPH
1092  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 * data)
1093  {  {
1094          XImage *image;          XImage *image;
1095          Pixmap bitmap;          Pixmap bitmap;
# Line 772  ui_create_glyph(int width, int height, u Line 1101  ui_create_glyph(int width, int height, u
1101          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
1102          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
1103    
1104          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
1105                               data, width, height, 8, scanline);                               width, height, 8, scanline);
1106          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
1107          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1108          XInitImage(image);          XInitImage(image);
# Line 782  ui_create_glyph(int width, int height, u Line 1111  ui_create_glyph(int width, int height, u
1111    
1112          XFree(image);          XFree(image);
1113          XFreeGC(display, gc);          XFreeGC(display, gc);
1114          return (HGLYPH)bitmap;          return (HGLYPH) bitmap;
1115  }  }
1116    
1117  void  void
1118  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
1119  {  {
1120          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(display, (Pixmap) glyph);
1121  }  }
1122    
1123  HCURSOR  HCURSOR
1124  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
1125                   int height, uint8 *andmask, uint8 *xormask)                   uint8 * andmask, uint8 * xormask)
1126  {  {
1127          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
1128          XColor bg, fg;          XColor bg, fg;
# Line 850  ui_create_cursor(unsigned int x, unsigne Line 1179  ui_create_cursor(unsigned int x, unsigne
1179    
1180          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
1181          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
1182            
1183          xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,          xcursor =
1184                                  (Pixmap)maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(display, (Pixmap) cursorglyph,
1185                                        (Pixmap) maskglyph, &fg, &bg, x, y);
1186    
1187          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
1188          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
1189          xfree(mask);          xfree(mask);
1190          xfree(cursor);          xfree(cursor);
1191          return (HCURSOR)xcursor;          return (HCURSOR) xcursor;
1192  }  }
1193    
1194  void  void
1195  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
1196  {  {
1197          XDefineCursor(display, wnd, (Cursor)cursor);          current_cursor = (Cursor) cursor;
1198            XDefineCursor(display, wnd, current_cursor);
1199  }  }
1200    
1201  void  void
1202  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
1203  {  {
1204          XFreeCursor(display, (Cursor)cursor);          XFreeCursor(display, (Cursor) cursor);
1205  }  }
1206    
1207  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 879  ui_destroy_cursor(HCURSOR cursor) Line 1210  ui_destroy_cursor(HCURSOR cursor)
1210                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
1211                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
1212    
1213    
1214  HCOLOURMAP  HCOLOURMAP
1215  ui_create_colourmap(COLOURMAP *colours)  ui_create_colourmap(COLOURMAP * colours)
1216  {  {
1217          COLOURENTRY *entry;          COLOURENTRY *entry;
1218          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
1219            if (!owncolmap)
1220            {
1221                    uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
1222                    XColor xentry;
1223                    XColor xc_cache[256];
1224                    uint32 colour;
1225                    int colLookup = 256;
1226                    for (i = 0; i < ncolours; i++)
1227                    {
1228                            entry = &colours->colours[i];
1229                            MAKE_XCOLOR(&xentry, entry);
1230    
1231                            if (XAllocColor(display, xcolmap, &xentry) == 0)
1232                            {
1233                                    /* Allocation failed, find closest match. */
1234                                    int j = 256;
1235                                    int nMinDist = 3 * 256 * 256;
1236                                    long nDist = nMinDist;
1237    
1238                                    /* only get the colors once */
1239                                    while (colLookup--)
1240                                    {
1241                                            xc_cache[colLookup].pixel = colLookup;
1242                                            xc_cache[colLookup].red = xc_cache[colLookup].green =
1243                                                    xc_cache[colLookup].blue = 0;
1244                                            xc_cache[colLookup].flags = 0;
1245                                            XQueryColor(display,
1246                                                        DefaultColormap(display,
1247                                                                        DefaultScreen(display)),
1248                                                        &xc_cache[colLookup]);
1249                                    }
1250                                    colLookup = 0;
1251    
1252          if (owncolmap)                                  /* approximate the pixel */
1253                                    while (j--)
1254                                    {
1255                                            if (xc_cache[j].flags)
1256                                            {
1257                                                    nDist = ((long) (xc_cache[j].red >> 8) -
1258                                                             (long) (xentry.red >> 8)) *
1259                                                            ((long) (xc_cache[j].red >> 8) -
1260                                                             (long) (xentry.red >> 8)) +
1261                                                            ((long) (xc_cache[j].green >> 8) -
1262                                                             (long) (xentry.green >> 8)) *
1263                                                            ((long) (xc_cache[j].green >> 8) -
1264                                                             (long) (xentry.green >> 8)) +
1265                                                            ((long) (xc_cache[j].blue >> 8) -
1266                                                             (long) (xentry.blue >> 8)) *
1267                                                            ((long) (xc_cache[j].blue >> 8) -
1268                                                             (long) (xentry.blue >> 8));
1269                                            }
1270                                            if (nDist < nMinDist)
1271                                            {
1272                                                    nMinDist = nDist;
1273                                                    xentry.pixel = j;
1274                                            }
1275                                    }
1276                            }
1277                            colour = xentry.pixel;
1278    
1279                            /* update our cache */
1280                            if (xentry.pixel < 256)
1281                            {
1282                                    xc_cache[xentry.pixel].red = xentry.red;
1283                                    xc_cache[xentry.pixel].green = xentry.green;
1284                                    xc_cache[xentry.pixel].blue = xentry.blue;
1285    
1286                            }
1287    
1288    
1289                            /* byte swap here to make translate_image faster */
1290                            map[i] = translate_colour(colour);
1291                    }
1292                    return map;
1293            }
1294            else
1295          {          {
1296                  XColor *xcolours, *xentry;                  XColor *xcolours, *xentry;
1297                  Colormap map;                  Colormap map;
# Line 903  ui_create_colourmap(COLOURMAP *colours) Line 1309  ui_create_colourmap(COLOURMAP *colours)
1309                  XStoreColors(display, map, xcolours, ncolours);                  XStoreColors(display, map, xcolours, ncolours);
1310    
1311                  xfree(xcolours);                  xfree(xcolours);
1312                  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;  
1313          }          }
1314  }  }
1315    
1316  void  void
1317  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
1318  {  {
1319          if (owncolmap)          if (!owncolmap)
                 XFreeColormap(display, (Colormap)map);  
         else  
1320                  xfree(map);                  xfree(map);
1321            else
1322                    XFreeColormap(display, (Colormap) map);
1323  }  }
1324    
1325  void  void
1326  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
1327  {  {
1328          if (owncolmap)          if (!owncolmap)
                 XSetWindowColormap(display, wnd, (Colormap)map);  
         else  
1329                  colmap = map;                  colmap = map;
1330            else
1331                    XSetWindowColormap(display, wnd, (Colormap) map);
1332  }  }
1333    
1334  void  void
# Line 960  ui_set_clip(int x, int y, int cx, int cy Line 1344  ui_set_clip(int x, int y, int cx, int cy
1344  }  }
1345    
1346  void  void
1347  ui_reset_clip()  ui_reset_clip(void)
1348  {  {
1349          XRectangle rect;          XRectangle rect;
1350    
# Line 972  ui_reset_clip() Line 1356  ui_reset_clip()
1356  }  }
1357    
1358  void  void
1359  ui_bell()  ui_bell(void)
1360  {  {
1361          XBell(display, 0);          XBell(display, 0);
1362  }  }
# Line 989  ui_destblt(uint8 opcode, Line 1373  ui_destblt(uint8 opcode,
1373  void  void
1374  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
1375            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1376            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1377  {  {
1378          Pixmap fill;          Pixmap fill;
1379            uint8 i, ipattern[8];
1380    
1381          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1382    
# Line 1003  ui_patblt(uint8 opcode, Line 1388  ui_patblt(uint8 opcode,
1388                          break;                          break;
1389    
1390                  case 3: /* Pattern */                  case 3: /* Pattern */
1391                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);                          for (i = 0; i != 8; i++)
1392                                    ipattern[7 - i] = brush->pattern[i];
1393                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
1394    
1395                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
1396                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
# Line 1014  ui_patblt(uint8 opcode, Line 1401  ui_patblt(uint8 opcode,
1401                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1402    
1403                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
1404                          ui_destroy_glyph((HGLYPH)fill);                          XSetTSOrigin(display, gc, 0, 0);
1405                            ui_destroy_glyph((HGLYPH) fill);
1406                          break;                          break;
1407    
1408                  default:                  default:
# Line 1032  ui_screenblt(uint8 opcode, Line 1420  ui_screenblt(uint8 opcode,
1420          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1421          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1422          if (ownbackstore)          if (ownbackstore)
1423                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1424          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1425  }  }
1426    
# Line 1043  ui_memblt(uint8 opcode, Line 1430  ui_memblt(uint8 opcode,
1430            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1431  {  {
1432          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1433          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1434          if (ownbackstore)          if (ownbackstore)
1435                  XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1436          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1437  }  }
1438    
# Line 1054  void Line 1440  void
1440  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
1441            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1442            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ HBITMAP src, int srcx, int srcy,
1443            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1444  {  {
1445          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
1446             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 1063  ui_triblt(uint8 opcode, Line 1449  ui_triblt(uint8 opcode,
1449          {          {
1450                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1451                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1452                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1453                          break;                          break;
1454    
1455                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1456                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1457                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1458                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1459                          break;                          break;
1460    
1461                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1462                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1463                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1464                          break;                          break;
1465    
1466                  default:                  default:
# Line 1090  ui_triblt(uint8 opcode, Line 1472  ui_triblt(uint8 opcode,
1472  void  void
1473  ui_line(uint8 opcode,  ui_line(uint8 opcode,
1474          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
1475          /* pen */ PEN *pen)          /* pen */ PEN * pen)
1476  {  {
1477          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1478          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
# Line 1109  ui_rect( Line 1491  ui_rect(
1491          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
1492  }  }
1493    
1494    /* warning, this function only draws on wnd or backstore, not both */
1495  void  void
1496  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1497                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1498                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1499                int fgcolour)                int bgcolour, int fgcolour)
1500  {  {
1501          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1502          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1503    
1504          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(display, gc,
1505                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1506          XSetStipple(display, gc, (Pixmap)glyph);          XSetStipple(display, gc, (Pixmap) glyph);
1507          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
1508    
1509          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
1510    
1511          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(display, gc, FillSolid);
1512  }  }
# Line 1137  ui_draw_glyph(int mixmode, Line 1520  ui_draw_glyph(int mixmode,
1520        if ((xyoffset & 0x80))\        if ((xyoffset & 0x80))\
1521          {\          {\
1522            if (flags & TEXT2_VERTICAL) \            if (flags & TEXT2_VERTICAL) \
1523              y += ttext[++idx] | (ttext[++idx] << 8);\              y += ttext[idx+1] | (ttext[idx+2] << 8);\
1524            else\            else\
1525              x += ttext[++idx] | (ttext[++idx] << 8);\              x += ttext[idx+1] | (ttext[idx+2] << 8);\
1526              idx += 2;\
1527          }\          }\
1528        else\        else\
1529          {\          {\
# Line 1151  ui_draw_glyph(int mixmode, Line 1535  ui_draw_glyph(int mixmode,
1535      }\      }\
1536    if (glyph != NULL)\    if (glyph != NULL)\
1537      {\      {\
1538        ui_draw_glyph (mixmode, x + (short) glyph->offset,\        ui_draw_glyph (mixmode, x + glyph->offset,\
1539                       y + (short) glyph->baseline,\                       y + glyph->baseline,\
1540                       glyph->width, glyph->height,\                       glyph->width, glyph->height,\
1541                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1542        if (flags & TEXT2_IMPLICIT_X)\        if (flags & TEXT2_IMPLICIT_X)\
# Line 1162  ui_draw_glyph(int mixmode, Line 1546  ui_draw_glyph(int mixmode,
1546    
1547  void  void
1548  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,
1549               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1550               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1551               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1552  {  {
1553          FONTGLYPH *glyph;          FONTGLYPH *glyph;
# Line 1174  ui_draw_text(uint8 font, uint8 flags, in Line 1558  ui_draw_text(uint8 font, uint8 flags, in
1558    
1559          if (boxcx > 1)          if (boxcx > 1)
1560          {          {
1561                  FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
1562          }          }
1563          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
1564          {          {
1565                  FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
1566          }          }
1567    
1568          /* Paint text, character by character */          /* Paint text, character by character */
1569          for (i = 0; i < length;) {          for (i = 0; i < length;)
1570                  switch (text[i]) {          {
1571                  case 0xff:                  switch (text[i])
1572                          if (i + 2 < length)                  {
1573                                  cache_put_text(text[i + 1], text, text[i + 2]);                          case 0xff:
1574                          else {                                  if (i + 2 < length)
1575                                  error("this shouldn't be happening\n");                                          cache_put_text(text[i + 1], text, text[i + 2]);
1576                                    else
1577                                    {
1578                                            error("this shouldn't be happening\n");
1579                                            exit(1);
1580                                    }
1581                                    /* this will move pointer from start to first character after FF command */
1582                                    length -= i + 3;
1583                                    text = &(text[i + 3]);
1584                                    i = 0;
1585                                  break;                                  break;
                         }  
                         /* this will move pointer from start to first character after FF command */  
                         length -= i + 3;  
                         text = &(text[i + 3]);  
                         i = 0;  
                         break;  
1586    
1587                  case 0xfe:                          case 0xfe:
1588                          entry = cache_get_text(text[i + 1]);                                  entry = cache_get_text(text[i + 1]);
1589                          if (entry != NULL) {                                  if (entry != NULL)
1590                                  if ((((uint8 *) (entry->data))[1] == 0)                                  {
1591                                      && (!(flags & TEXT2_IMPLICIT_X))) {                                          if ((((uint8 *) (entry->data))[1] ==
1592                                          if (flags & TEXT2_VERTICAL)                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
1593                                                  y += text[i + 2];                                          {
1594                                          else                                                  if (flags & TEXT2_VERTICAL)
1595                                                  x += text[i + 2];                                                          y += text[i + 2];
1596                                                    else
1597                                                            x += text[i + 2];
1598                                            }
1599                                            for (j = 0; j < entry->size; j++)
1600                                                    DO_GLYPH(((uint8 *) (entry->data)), j);
1601                                  }                                  }
1602                                  if (i + 2 < length)                                  if (i + 2 < length)
1603                                          i += 3;                                          i += 3;
1604                                  else                                  else
1605                                          i += 2;                                          i += 2;
1606                                  length -= i;                                  length -= i;
1607                                  /* this will move pointer from start to first character after FE command */                                  /* this will move pointer from start to first character after FE command */
1608                                  text = &(text[i]);                                  text = &(text[i]);
1609                                  i = 0;                                  i = 0;
1610                                  for (j = 0; j < entry->size; j++)                                  break;
                                         DO_GLYPH(((uint8 *) (entry->data)), j);  
                         }  
                         break;  
1611    
1612                  default:                          default:
1613                          DO_GLYPH(text, i);                                  DO_GLYPH(text, i);
1614                          i++;                                  i++;
1615                          break;                                  break;
1616                  }                  }
1617          }          }
1618            if (ownbackstore)
1619            {
1620                    if (boxcx > 1)
1621                            XCopyArea(display, backstore, wnd, gc, boxx,
1622                                      boxy, boxcx, boxcy, boxx, boxy);
1623                    else
1624                            XCopyArea(display, backstore, wnd, gc, clipx,
1625                                      clipy, clipcx, clipcy, clipx, clipy);
1626            }
1627  }  }
1628    
1629  void  void
# Line 1238  ui_desktop_save(uint32 offset, int x, in Line 1634  ui_desktop_save(uint32 offset, int x, in
1634    
1635          if (ownbackstore)          if (ownbackstore)
1636          {          {
1637                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1638          }          }
1639          else          else
1640          {          {
1641                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(display, wnd, cx, cy, depth);
1642                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1643                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1644                  XFreePixmap(display, pix);                  XFreePixmap(display, pix);
1645          }          }
1646    
1647          offset *= bpp/8;          offset *= bpp / 8;
1648          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);  
1649    
1650          XDestroyImage(image);          XDestroyImage(image);
1651  }  }
# Line 1263  ui_desktop_restore(uint32 offset, int x, Line 1656  ui_desktop_restore(uint32 offset, int x,
1656          XImage *image;          XImage *image;
1657          uint8 *data;          uint8 *data;
1658    
1659          offset *= bpp/8;          offset *= bpp / 8;
1660          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp / 8);
1661          if (data == NULL)          if (data == NULL)
1662                  return;                  return;
1663    
1664          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1665                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);
                              cx * bpp/8);  
1666    
1667          if (ownbackstore)          if (ownbackstore)
1668          {          {

Legend:
Removed from v.54  
changed lines
  Added in v.342

  ViewVC Help
Powered by ViewVC 1.1.26