/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/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/branches/seamlessrdp-branch/rdesktop/xwin.c

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

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

Legend:
Removed from v.64  
changed lines
  Added in v.432

  ViewVC Help
Powered by ViewVC 1.1.26