/[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 677 by n-ki, Mon Apr 26 13:48:39 2004 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>
23  #include <X11/XKBlib.h>  #include <unistd.h>
24    #include <sys/time.h>
25  #include <time.h>  #include <time.h>
26  #include <errno.h>  #include <errno.h>
27    #include <strings.h>
28  #include "rdesktop.h"  #include "rdesktop.h"
29    #include "xproto.h"
30    
31  extern char keymapname[16];  extern int g_width;
32  extern int keylayout;  extern int g_height;
33  extern int width;  extern BOOL g_sendmotion;
34  extern int height;  extern BOOL g_fullscreen;
35  extern BOOL sendmotion;  extern BOOL g_grab_keyboard;
36  extern BOOL fullscreen;  extern BOOL g_hide_decorations;
37    extern char g_title[];
38  Display *display;  extern int g_server_bpp;
39  XkbDescPtr xkb;  extern int g_win_button_size;
40  static int x_socket;  
41  static Window wnd;  Display *g_display;
42  static GC gc;  Time g_last_gesturetime;
43  static Visual *visual;  static int g_x_socket;
44  static int depth;  static Screen *g_screen;
45  static int bpp;  Window g_wnd;
46    extern uint32 g_embed_wnd;
47    BOOL g_enable_compose = False;
48    static GC g_gc = NULL;
49    static Visual *g_visual;
50    static int g_depth;
51    static int g_bpp;
52    static XIM g_IM;
53    static XIC g_IC;
54    static XModifierKeymap *g_mod_map;
55    static Cursor g_current_cursor;
56    static HCURSOR g_null_cursor = NULL;
57    static Atom g_protocol_atom, g_kill_atom;
58    static BOOL g_focused;
59    static BOOL g_mouse_in_wnd;
60    static BOOL g_arch_match = False;       /* set to True if RGB XServer and little endian */
61    
62  /* endianness */  /* endianness */
63  static BOOL host_be;  static BOOL g_host_be;
64  static BOOL xserver_be;  static BOOL g_xserver_be;
65    static int g_red_shift_r, g_blue_shift_r, g_green_shift_r;
66    static int g_red_shift_l, g_blue_shift_l, g_green_shift_l;
67    
68  /* software backing store */  /* software backing store */
69  static BOOL ownbackstore;  extern BOOL g_ownbackstore;
70  static Pixmap backstore;  static Pixmap g_backstore = 0;
71    
72    /* Moving in single app mode */
73    static BOOL g_moving_wnd;
74    static int g_move_x_offset = 0;
75    static int g_move_y_offset = 0;
76    
77    #ifdef WITH_RDPSND
78    extern int g_dsp_fd;
79    extern BOOL g_dsp_busy;
80    extern BOOL g_rdpsnd;
81    #endif
82    
83    /* MWM decorations */
84    #define MWM_HINTS_DECORATIONS   (1L << 1)
85    #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
86    typedef struct
87    {
88            uint32 flags;
89            uint32 functions;
90            uint32 decorations;
91            sint32 inputMode;
92            uint32 status;
93    }
94    PropMotifWmHints;
95    
96    typedef struct
97    {
98            uint32 red;
99            uint32 green;
100            uint32 blue;
101    }
102    PixelColour;
103    
 /* needed to keep track of the modifiers */  
 static unsigned int numlock_modifier_mask = 0;  
 static unsigned int key_down_state = 0;  
   
   
 #define DShift1Mask   (1<<0)  
 #define DLockMask     (1<<1)  
 #define DControl1Mask (1<<2)  
 #define DMod1Mask     (1<<3)  
 #define DMod2Mask     (1<<4)  
 #define DMod3Mask     (1<<5)  
 #define DMod4Mask     (1<<6)  
 #define DMod5Mask     (1<<7)  
 #define DShift2Mask   (1<<8)  
 #define DControl2Mask (1<<9)  
 #define DNumLockMask  (1<<10)  
104    
105  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
106  { \  { \
107          XFillRectangle(display, wnd, gc, x, y, cx, cy); \          XFillRectangle(g_display, g_wnd, g_gc, x, y, cx, cy); \
108          if (ownbackstore) \          if (g_ownbackstore) \
109                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \                  XFillRectangle(g_display, g_backstore, g_gc, x, y, cx, cy); \
110    }
111    
112    #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\
113    { \
114            XFillRectangle(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, cx, cy); \
115  }  }
116    
117  /* colour maps */  /* colour maps */
118  static BOOL owncolmap;  extern BOOL g_owncolmap;
119  static Colormap xcolmap;  static Colormap g_xcolmap;
120  static uint32 white;  static uint32 *g_colmap = NULL;
121  static uint32 *colmap;  
122    #define TRANSLATE(col)          ( g_server_bpp != 8 ? translate_colour(col) : g_owncolmap ? col : g_colmap[col] )
123  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )  #define SET_FOREGROUND(col)     XSetForeground(g_display, g_gc, TRANSLATE(col));
124  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(g_display, g_gc, TRANSLATE(col));
 #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  
125    
126  static int rop2_map[] = {  static int rop2_map[] = {
127          GXclear,                /* 0 */          GXclear,                /* 0 */
# Line 102  static int rop2_map[] = { Line 142  static int rop2_map[] = {
142          GXset                   /* 1 */          GXset                   /* 1 */
143  };  };
144    
145  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, rop2_map[rop2]); }
146  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); }
147    
148    static void
149    mwm_hide_decorations(void)
150    {
151            PropMotifWmHints motif_hints;
152            Atom hintsatom;
153    
154            /* setup the property */
155            motif_hints.flags = MWM_HINTS_DECORATIONS;
156            motif_hints.decorations = 0;
157    
158            /* get the atom for the property */
159            hintsatom = XInternAtom(g_display, "_MOTIF_WM_HINTS", False);
160            if (!hintsatom)
161            {
162                    warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");
163                    return;
164            }
165    
166            XChangeProperty(g_display, g_wnd, hintsatom, hintsatom, 32, PropModeReplace,
167                            (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
168    }
169    
170    static PixelColour
171    split_colour15(uint32 colour)
172    {
173            PixelColour rv;
174            rv.red = (colour & 0x7c00) >> 7;
175            rv.green = (colour & 0x03e0) >> 2;
176            rv.blue = (colour & 0x001f) << 3;
177            return rv;
178    }
179    
180    static PixelColour
181    split_colour16(uint32 colour)
182    {
183            PixelColour rv;
184            rv.red = (colour & 0xf800) >> 8;
185            rv.green = (colour & 0x07e0) >> 3;
186            rv.blue = (colour & 0x001f) << 3;
187            return rv;
188    }
189    
190    static PixelColour
191    split_colour24(uint32 colour)
192    {
193            PixelColour rv;
194            rv.blue = (colour & 0xff0000) >> 16;
195            rv.green = (colour & 0x00ff00) >> 8;
196            rv.red = (colour & 0x0000ff);
197            return rv;
198    }
199    
200    static uint32
201    make_colour(PixelColour pc)
202    {
203            return (((pc.red >> g_red_shift_r) << g_red_shift_l)
204                    | ((pc.green >> g_green_shift_r) << g_green_shift_l)
205                    | ((pc.blue >> g_blue_shift_r) << g_blue_shift_l));
206    }
207    
208    #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
209    #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | (x & 0xff00)); }
210    #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
211                            x = (x << 16) | (x >> 16); }
212    
213  void xwin_get_numlock_mask();  static uint32
214  void xwin_mod_update(uint32 state, uint32 ev_time);  translate_colour(uint32 colour)
215  void xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode);  {
216  void xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode);          PixelColour pc;
217            switch (g_server_bpp)
218            {
219                    case 15:
220                            pc = split_colour15(colour);
221                            break;
222                    case 16:
223                            pc = split_colour16(colour);
224                            break;
225                    case 24:
226                            pc = split_colour24(colour);
227                            break;
228            }
229            return make_colour(pc);
230    }
231    
232  static void  static void
233  translate8(uint8 * data, uint8 * out, uint8 * end)  translate8to8(uint8 * data, uint8 * out, uint8 * end)
234  {  {
235          while (out < end)          while (out < end)
236                  *(out++) = (uint8) colmap[*(data++)];                  *(out++) = (uint8) g_colmap[*(data++)];
237  }  }
238    
239  static void  static void
240  translate16(uint8 * data, uint16 * out, uint16 * end)  translate8to16(uint8 * data, uint8 * out, uint8 * end)
241  {  {
242          while (out < end)          uint16 value;
243                  *(out++) = (uint16) colmap[*(data++)];  
244            if (g_xserver_be)
245            {
246                    while (out < end)
247                    {
248                            value = (uint16) g_colmap[*(data++)];
249                            *(out++) = value >> 8;
250                            *(out++) = value;
251                    }
252            }
253            else
254            {
255                    while (out < end)
256                    {
257                            value = (uint16) g_colmap[*(data++)];
258                            *(out++) = value;
259                            *(out++) = value >> 8;
260                    }
261            }
262  }  }
263    
264  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
265  static void  static void
266  translate24(uint8 * data, uint8 * out, uint8 * end)  translate8to24(uint8 * data, uint8 * out, uint8 * end)
267    {
268            uint32 value;
269    
270            if (g_xserver_be)
271            {
272                    while (out < end)
273                    {
274                            value = g_colmap[*(data++)];
275                            *(out++) = value >> 16;
276                            *(out++) = value >> 8;
277                            *(out++) = value;
278                    }
279            }
280            else
281            {
282                    while (out < end)
283                    {
284                            value = g_colmap[*(data++)];
285                            *(out++) = value;
286                            *(out++) = value >> 8;
287                            *(out++) = value >> 16;
288                    }
289            }
290    }
291    
292    static void
293    translate8to32(uint8 * data, uint8 * out, uint8 * end)
294  {  {
295          uint32 value;          uint32 value;
296    
297            if (g_xserver_be)
298            {
299                    while (out < end)
300                    {
301                            value = g_colmap[*(data++)];
302                            *(out++) = value >> 24;
303                            *(out++) = value >> 16;
304                            *(out++) = value >> 8;
305                            *(out++) = value;
306                    }
307            }
308            else
309            {
310                    while (out < end)
311                    {
312                            value = g_colmap[*(data++)];
313                            *(out++) = value;
314                            *(out++) = value >> 8;
315                            *(out++) = value >> 16;
316                            *(out++) = value >> 24;
317                    }
318            }
319    }
320    
321    static void
322    translate15to16(uint16 * data, uint8 * out, uint8 * end)
323    {
324            uint16 pixel;
325            uint16 value;
326    
327          while (out < end)          while (out < end)
328          {          {
329                  value = colmap[*(data++)];                  pixel = *(data++);
330                  *(out++) = value;  
331                  *(out++) = value >> 8;                  if (g_host_be)
332                  *(out++) = value >> 16;                  {
333                            BSWAP16(pixel);
334                    }
335    
336                    value = make_colour(split_colour15(pixel));
337    
338                    if (g_xserver_be)
339                    {
340                            *(out++) = value >> 8;
341                            *(out++) = value;
342                    }
343                    else
344                    {
345                            *(out++) = value;
346                            *(out++) = value >> 8;
347                    }
348          }          }
349  }  }
350    
351  static void  static void
352  translate32(uint8 * data, uint32 * out, uint32 * end)  translate15to24(uint16 * data, uint8 * out, uint8 * end)
353  {  {
354            uint32 value;
355            uint16 pixel;
356    
357          while (out < end)          while (out < end)
358                  *(out++) = colmap[*(data++)];          {
359                    pixel = *(data++);
360    
361                    if (g_host_be)
362                    {
363                            BSWAP16(pixel);
364                    }
365    
366                    value = make_colour(split_colour15(pixel));
367                    if (g_xserver_be)
368                    {
369                            *(out++) = value >> 16;
370                            *(out++) = value >> 8;
371                            *(out++) = value;
372                    }
373                    else
374                    {
375                            *(out++) = value;
376                            *(out++) = value >> 8;
377                            *(out++) = value >> 16;
378                    }
379            }
380  }  }
381    
382  static uint8 *  static void
383  translate_image(int width, int height, uint8 * data)  translate15to32(uint16 * data, uint8 * out, uint8 * end)
384  {  {
385          int size = width * height * bpp / 8;          uint16 pixel;
386          uint8 *out = xmalloc(size);          uint32 value;
         uint8 *end = out + size;  
387    
388          switch (bpp)          while (out < end)
389          {          {
390                  case 8:                  pixel = *(data++);
                         translate8(data, out, end);  
                         break;  
391    
392                  case 16:                  if (g_host_be)
393                          translate16(data, (uint16 *) out, (uint16 *) end);                  {
394                          break;                          BSWAP16(pixel);
395                    }
396    
397                  case 24:                  value = make_colour(split_colour15(pixel));
                         translate24(data, out, end);  
                         break;  
398    
399                  case 32:                  if (g_xserver_be)
400                          translate32(data, (uint32 *) out, (uint32 *) end);                  {
401                          break;                          *(out++) = value >> 24;
402                            *(out++) = value >> 16;
403                            *(out++) = value >> 8;
404                            *(out++) = value;
405                    }
406                    else
407                    {
408                            *(out++) = value;
409                            *(out++) = value >> 8;
410                            *(out++) = value >> 16;
411                            *(out++) = value >> 24;
412                    }
413          }          }
414    }
415    
416          return out;  static void
417    translate16to16(uint16 * data, uint8 * out, uint8 * end)
418    {
419            uint16 pixel;
420            uint16 value;
421    
422            while (out < end)
423            {
424                    pixel = *(data++);
425    
426                    if (g_host_be)
427                    {
428                            BSWAP16(pixel);
429                    }
430    
431                    value = make_colour(split_colour16(pixel));
432    
433                    if (g_xserver_be)
434                    {
435                            *(out++) = value >> 8;
436                            *(out++) = value;
437                    }
438                    else
439                    {
440                            *(out++) = value;
441                            *(out++) = value >> 8;
442                    }
443            }
444  }  }
445    
446  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }  static void
447  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }  translate16to24(uint16 * data, uint8 * out, uint8 * end)
448  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \  {
449                          x = (x << 16) | (x >> 16); }          uint32 value;
450            uint16 pixel;
451    
452  static uint32          while (out < end)
453  translate_colour(uint32 colour)          {
454                    pixel = *(data++);
455    
456                    if (g_host_be)
457                    {
458                            BSWAP16(pixel);
459                    }
460    
461                    value = make_colour(split_colour16(pixel));
462    
463                    if (g_xserver_be)
464                    {
465                            *(out++) = value >> 16;
466                            *(out++) = value >> 8;
467                            *(out++) = value;
468                    }
469                    else
470                    {
471                            *(out++) = value;
472                            *(out++) = value >> 8;
473                            *(out++) = value >> 16;
474                    }
475            }
476    }
477    
478    static void
479    translate16to32(uint16 * data, uint8 * out, uint8 * end)
480  {  {
481          switch (bpp)          uint16 pixel;
482            uint32 value;
483    
484            while (out < end)
485          {          {
486                  case 16:                  pixel = *(data++);
                         if (host_be != xserver_be)  
                                 BSWAP16(colour);  
                         break;  
487    
488                  case 24:                  if (g_host_be)
489                          if (xserver_be)                  {
490                                  BSWAP24(colour);                          BSWAP16(pixel);
491                          break;                  }
492    
493                  case 32:                  value = make_colour(split_colour16(pixel));
494                          if (host_be != xserver_be)  
495                                  BSWAP32(colour);                  if (g_xserver_be)
496                          break;                  {
497                            *(out++) = value >> 24;
498                            *(out++) = value >> 16;
499                            *(out++) = value >> 8;
500                            *(out++) = value;
501                    }
502                    else
503                    {
504                            *(out++) = value;
505                            *(out++) = value >> 8;
506                            *(out++) = value >> 16;
507                            *(out++) = value >> 24;
508                    }
509          }          }
510    }
511    
512    static void
513    translate24to16(uint8 * data, uint8 * out, uint8 * end)
514    {
515            uint32 pixel = 0;
516            uint16 value;
517            while (out < end)
518            {
519                    pixel = *(data++) << 16;
520                    pixel |= *(data++) << 8;
521                    pixel |= *(data++);
522    
523                    value = (uint16) make_colour(split_colour24(pixel));
524    
525          return colour;                  if (g_xserver_be)
526                    {
527                            *(out++) = value >> 8;
528                            *(out++) = value;
529                    }
530                    else
531                    {
532                            *(out++) = value;
533                            *(out++) = value >> 8;
534                    }
535            }
536  }  }
537    
538  BOOL  static void
539  ui_create_window(char *title)  translate24to24(uint8 * data, uint8 * out, uint8 * end)
540  {  {
541          XSetWindowAttributes attribs;          uint32 pixel;
542          XClassHint *classhints;          uint32 value;
         XSizeHints *sizehints;  
         unsigned long input_mask;  
         XPixmapFormatValues *pfm;  
         Screen *screen;  
         uint16 test;  
         int i;  
543    
544          int xkb_minor, xkb_major;          while (out < end)
545          int xkb_event, xkb_error, xkb_reason;          {
546                    pixel = *(data++) << 16;
547                    pixel |= *(data++) << 8;
548                    pixel |= *(data++);
549    
550          /* compare compiletime libs with runtime libs. */                  value = make_colour(split_colour24(pixel));
551          xkb_major = XkbMajorVersion;  
552          xkb_minor = XkbMinorVersion;                  if (g_xserver_be)
553          if (XkbLibraryVersion(&xkb_major, &xkb_minor) == False)                  {
554                            *(out++) = value >> 16;
555                            *(out++) = value >> 8;
556                            *(out++) = value;
557                    }
558                    else
559                    {
560                            *(out++) = value;
561                            *(out++) = value >> 8;
562                            *(out++) = value >> 16;
563                    }
564            }
565    }
566    
567    static void
568    translate24to32(uint8 * data, uint8 * out, uint8 * end)
569    {
570            uint32 pixel;
571            uint32 value;
572    
573            while (out < end)
574          {          {
575                  error("please re-compile rdesktop\ncompile time version of xkb is not compatible with\nyour runtime version of the library\n");                  pixel = *(data++) << 16;
576                  return False;                  pixel |= *(data++) << 8;
577                    pixel |= *(data++);
578    
579                    value = make_colour(split_colour24(pixel));
580    
581                    if (g_xserver_be)
582                    {
583                            *(out++) = value >> 24;
584                            *(out++) = value >> 16;
585                            *(out++) = value >> 8;
586                            *(out++) = value;
587                    }
588                    else
589                    {
590                            *(out++) = value;
591                            *(out++) = value >> 8;
592                            *(out++) = value >> 16;
593                            *(out++) = value >> 24;
594                    }
595          }          }
596    }
597    
598    static uint8 *
599    translate_image(int width, int height, uint8 * data)
600    {
601            int size;
602            uint8 *out;
603            uint8 *end;
604    
605            /* if server and xserver bpp match, */
606            /* and arch(endian) matches, no need to translate */
607            /* just return data */
608            if (g_arch_match)
609            {
610                    if (g_depth == 15 && g_server_bpp == 15)
611                            return data;
612                    if (g_depth == 16 && g_server_bpp == 16)
613                            return data;
614            }
615    
616            size = width * height * (g_bpp / 8);
617            out = (uint8 *) xmalloc(size);
618            end = out + size;
619    
620          display =          switch (g_server_bpp)
                 XkbOpenDisplay(NULL, &xkb_event, &xkb_error, &xkb_major,  
                                &xkb_minor, &xkb_reason);  
         switch (xkb_reason)  
621          {          {
622                  case XkbOD_BadLibraryVersion:                  case 24:
623                          error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n");                          switch (g_bpp)
624                          break;                          {
625                  case XkbOD_ConnectionRefused:                                  case 32:
626                          error("XkbOD_ConnectionRefused\n");                                          translate24to32(data, out, end);
627                                            break;
628                                    case 24:
629                                            translate24to24(data, out, end);
630                                            break;
631                                    case 16:
632                                            translate24to16(data, out, end);
633                                            break;
634                            }
635                          break;                          break;
636                  case XkbOD_BadServerVersion:                  case 16:
637                          error("XkbOD_BadServerVersion\n");                          switch (g_bpp)
638                            {
639                                    case 32:
640                                            translate16to32((uint16 *) data, out, end);
641                                            break;
642                                    case 24:
643                                            translate16to24((uint16 *) data, out, end);
644                                            break;
645                                    case 16:
646                                            translate16to16((uint16 *) data, out, end);
647                                            break;
648                            }
649                          break;                          break;
650                  case XkbOD_NonXkbServer:                  case 15:
651                          error("XkbOD_NonXkbServer: XKB extension not present in server\nupdate your X server.\n");                          switch (g_bpp)
652                            {
653                                    case 32:
654                                            translate15to32((uint16 *) data, out, end);
655                                            break;
656                                    case 24:
657                                            translate15to24((uint16 *) data, out, end);
658                                            break;
659                                    case 16:
660                                            translate15to16((uint16 *) data, out, end);
661                                            break;
662                            }
663                          break;                          break;
664                  case XkbOD_Success:                  case 8:
665                          DEBUG("XkbOD_Success: Connection established with display\n");                          switch (g_bpp)
666                            {
667                                    case 8:
668                                            translate8to8(data, out, end);
669                                            break;
670                                    case 16:
671                                            translate8to16(data, out, end);
672                                            break;
673                                    case 24:
674                                            translate8to24(data, out, end);
675                                            break;
676                                    case 32:
677                                            translate8to32(data, out, end);
678                                            break;
679                            }
680                          break;                          break;
681          }          }
682            return out;
683    }
684    
685    BOOL
686    get_key_state(unsigned int state, uint32 keysym)
687    {
688            int modifierpos, key, keysymMask = 0;
689            int offset;
690    
691            KeyCode keycode = XKeysymToKeycode(g_display, keysym);
692    
693            if (keycode == NoSymbol)
694                    return False;
695    
696            for (modifierpos = 0; modifierpos < 8; modifierpos++)
697            {
698                    offset = g_mod_map->max_keypermod * modifierpos;
699    
700                    for (key = 0; key < g_mod_map->max_keypermod; key++)
701                    {
702                            if (g_mod_map->modifiermap[offset + key] == keycode)
703                                    keysymMask |= 1 << modifierpos;
704                    }
705            }
706    
707            return (state & keysymMask) ? True : False;
708    }
709    
710    static void
711    calculate_shifts(uint32 mask, int *shift_r, int *shift_l)
712    {
713            *shift_l = ffs(mask) - 1;
714            mask >>= *shift_l;
715            *shift_r = 8 - ffs(mask & ~(mask >> 1));
716    }
717    
718          if (display == NULL)  BOOL
719    ui_init(void)
720    {
721            XVisualInfo vi;
722            XPixmapFormatValues *pfm;
723            uint16 test;
724            int i, screen_num, nvisuals;
725            XVisualInfo *vmatches = NULL;
726            XVisualInfo template;
727            Bool TrueColorVisual = False;
728    
729            g_display = XOpenDisplay(NULL);
730            if (g_display == NULL)
731          {          {
732                  error("Failed to open display\n");                  error("Failed to open display: %s\n", XDisplayName(NULL));
733                  return False;                  return False;
734          }          }
735    
736          x_socket = ConnectionNumber(display);          screen_num = DefaultScreen(g_display);
737          screen = DefaultScreenOfDisplay(display);          g_x_socket = ConnectionNumber(g_display);
738          visual = DefaultVisualOfScreen(screen);          g_screen = ScreenOfDisplay(g_display, screen_num);
739          depth = DefaultDepthOfScreen(screen);          g_depth = DefaultDepthOfScreen(g_screen);
740    
741            /* Search for best TrueColor depth */
742            template.class = TrueColor;
743            vmatches = XGetVisualInfo(g_display, VisualClassMask, &template, &nvisuals);
744    
745            nvisuals--;
746            while (nvisuals >= 0)
747            {
748                    if ((vmatches + nvisuals)->depth > g_depth)
749                    {
750                            g_depth = (vmatches + nvisuals)->depth;
751                    }
752                    nvisuals--;
753                    TrueColorVisual = True;
754            }
755    
756          pfm = XListPixmapFormats(display, &i);          test = 1;
757            g_host_be = !(BOOL) (*(uint8 *) (&test));
758            g_xserver_be = (ImageByteOrder(g_display) == MSBFirst);
759    
760            if ((g_server_bpp == 8) && ((!TrueColorVisual) || (g_depth <= 8)))
761            {
762                    /* we use a colourmap, so the default visual should do */
763                    g_visual = DefaultVisualOfScreen(g_screen);
764                    g_depth = DefaultDepthOfScreen(g_screen);
765    
766                    /* Do not allocate colours on a TrueColor visual */
767                    if (g_visual->class == TrueColor)
768                    {
769                            g_owncolmap = False;
770                    }
771            }
772            else
773            {
774                    /* need a truecolour visual */
775                    if (!XMatchVisualInfo(g_display, screen_num, g_depth, TrueColor, &vi))
776                    {
777                            error("The display does not support true colour - high colour support unavailable.\n");
778                            return False;
779                    }
780    
781                    g_visual = vi.visual;
782                    g_owncolmap = False;
783                    calculate_shifts(vi.red_mask, &g_red_shift_r, &g_red_shift_l);
784                    calculate_shifts(vi.blue_mask, &g_blue_shift_r, &g_blue_shift_l);
785                    calculate_shifts(vi.green_mask, &g_green_shift_r, &g_green_shift_l);
786    
787                    /* if RGB video and averything is little endian */
788                    if (vi.red_mask > vi.green_mask && vi.green_mask > vi.blue_mask)
789                            if (!g_xserver_be && !g_host_be)
790                                    g_arch_match = True;
791            }
792    
793            pfm = XListPixmapFormats(g_display, &i);
794          if (pfm != NULL)          if (pfm != NULL)
795          {          {
796                  /* Use maximum bpp for this depth - this is generally                  /* Use maximum bpp for this depth - this is generally
797                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
798                  while (i--)                  while (i--)
799                  {                  {
800                          if ((pfm[i].depth == depth)                          if ((pfm[i].depth == g_depth) && (pfm[i].bits_per_pixel > g_bpp))
                             && (pfm[i].bits_per_pixel > bpp))  
801                          {                          {
802                                  bpp = pfm[i].bits_per_pixel;                                  g_bpp = pfm[i].bits_per_pixel;
803                          }                          }
804                  }                  }
805                  XFree(pfm);                  XFree(pfm);
806          }          }
807    
808          if (bpp < 8)          if (g_bpp < 8)
809          {          {
810                  error("Less than 8 bpp not currently supported.\n");                  error("Less than 8 bpp not currently supported.\n");
811                  XCloseDisplay(display);                  XCloseDisplay(g_display);
812                  return False;                  return False;
813          }          }
814    
815          if (depth <= 8)          if (!g_owncolmap)
816                  owncolmap = True;          {
817          else                  g_xcolmap =
818                  xcolmap = DefaultColormapOfScreen(screen);                          XCreateColormap(g_display, RootWindowOfScreen(g_screen), g_visual,
819                                            AllocNone);
820          test = 1;                  if (g_depth <= 8)
821          host_be = !(BOOL) (*(uint8 *) (&test));                          warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");
822          xserver_be = (ImageByteOrder(display) == MSBFirst);          }
   
         white = WhitePixelOfScreen(screen);  
         attribs.background_pixel = BlackPixelOfScreen(screen);  
         attribs.backing_store = DoesBackingStore(screen);  
823    
824          if (attribs.backing_store == NotUseful)          if ((!g_ownbackstore) && (DoesBackingStore(g_screen) != Always))
825                  ownbackstore = True;          {
826                    warning("External BackingStore not available, using internal\n");
827                    g_ownbackstore = True;
828            }
829    
830          if (fullscreen)          /*
831             * Determine desktop size
832             */
833            if (g_fullscreen)
834          {          {
835                  attribs.override_redirect = True;                  g_width = WidthOfScreen(g_screen);
836                  width = WidthOfScreen(screen);                  g_height = HeightOfScreen(g_screen);
                 height = HeightOfScreen(screen);  
837          }          }
838          else          else if (g_width < 0)
839            {
840                    /* Percent of screen */
841                    g_height = HeightOfScreen(g_screen) * (-g_width) / 100;
842                    g_width = WidthOfScreen(g_screen) * (-g_width) / 100;
843            }
844            else if (g_width == 0)
845          {          {
846                  attribs.override_redirect = False;                  /* Fetch geometry from _NET_WORKAREA */
847                    uint32 x, y, cx, cy;
848    
849                    if (get_current_workarea(&x, &y, &cx, &cy) == 0)
850                    {
851                            g_width = cx;
852                            g_height = cy;
853                    }
854                    else
855                    {
856                            warning("Failed to get workarea: probably your window manager does not support extended hints\n");
857                            g_width = 800;
858                            g_height = 600;
859                    }
860          }          }
861    
862          width = (width + 3) & ~3;       /* make width a multiple of 32 bits */          /* make sure width is a multiple of 4 */
863            g_width = (g_width + 3) & ~3;
864    
865            g_mod_map = XGetModifierMapping(g_display);
866    
867            xkeymap_init();
868    
869            if (g_enable_compose)
870                    g_IM = XOpenIM(g_display, NULL, NULL, NULL);
871    
872            xclip_init();
873    
874            DEBUG_RDP5(("server bpp %d client bpp %d depth %d\n", g_server_bpp, g_bpp, g_depth));
875    
876            return True;
877    }
878    
879    void
880    ui_deinit(void)
881    {
882            if (g_IM != NULL)
883                    XCloseIM(g_IM);
884    
885            if (g_null_cursor != NULL)
886                    ui_destroy_cursor(g_null_cursor);
887    
888            XFreeModifiermap(g_mod_map);
889    
890            if (g_ownbackstore)
891                    XFreePixmap(g_display, g_backstore);
892    
893            XFreeGC(g_display, g_gc);
894            XCloseDisplay(g_display);
895            g_display = NULL;
896    }
897    
898    BOOL
899    ui_create_window(void)
900    {
901            uint8 null_pointer_mask[1] = { 0x80 };
902            uint8 null_pointer_data[4] = { 0x00, 0x00, 0x00, 0x00 };
903            XSetWindowAttributes attribs;
904            XClassHint *classhints;
905            XSizeHints *sizehints;
906            int wndwidth, wndheight;
907            long input_mask, ic_input_mask;
908            XEvent xevent;
909    
910            wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;
911            wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;
912    
913            attribs.background_pixel = BlackPixelOfScreen(g_screen);
914            attribs.border_pixel = WhitePixelOfScreen(g_screen);
915            attribs.backing_store = g_ownbackstore ? NotUseful : Always;
916            attribs.override_redirect = g_fullscreen;
917            attribs.colormap = g_xcolmap;
918    
919            g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), 0, 0, wndwidth, wndheight,
920                                  0, g_depth, InputOutput, g_visual,
921                                  CWBackPixel | CWBackingStore | CWOverrideRedirect |
922                                  CWColormap | CWBorderPixel, &attribs);
923    
924            if (g_gc == NULL)
925                    g_gc = XCreateGC(g_display, g_wnd, 0, NULL);
926    
927            if ((g_ownbackstore) && (g_backstore == 0))
928            {
929                    g_backstore = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
930    
931                    /* clear to prevent rubbish being exposed at startup */
932                    XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));
933                    XFillRectangle(g_display, g_backstore, g_gc, 0, 0, g_width, g_height);
934            }
935    
936          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          XStoreName(g_display, g_wnd, g_title);
                             0, 0, width, height, 0, CopyFromParent,  
                             InputOutput, CopyFromParent,  
                             CWBackingStore | CWBackPixel | CWOverrideRedirect,  
                             &attribs);  
937    
938          XStoreName(display, wnd, title);          if (g_hide_decorations)
939                    mwm_hide_decorations();
940    
941          classhints = XAllocClassHint();          classhints = XAllocClassHint();
942          if (classhints != NULL)          if (classhints != NULL)
943          {          {
944                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = classhints->res_class = "rdesktop";
945                  XSetClassHint(display, wnd, classhints);                  XSetClassHint(g_display, g_wnd, classhints);
946                  XFree(classhints);                  XFree(classhints);
947          }          }
948    
# Line 334  ui_create_window(char *title) Line 950  ui_create_window(char *title)
950          if (sizehints)          if (sizehints)
951          {          {
952                  sizehints->flags = PMinSize | PMaxSize;                  sizehints->flags = PMinSize | PMaxSize;
953                  sizehints->min_width = sizehints->max_width = width;                  sizehints->min_width = sizehints->max_width = g_width;
954                  sizehints->min_height = sizehints->max_height = height;                  sizehints->min_height = sizehints->max_height = g_height;
955                  XSetWMNormalHints(display, wnd, sizehints);                  XSetWMNormalHints(g_display, g_wnd, sizehints);
956                  XFree(sizehints);                  XFree(sizehints);
957          }          }
958    
959          xkeymap_init();          if (g_embed_wnd)
960            {
961                    XReparentWindow(g_display, g_wnd, (Window) g_embed_wnd, 0, 0);
962            }
963    
964          input_mask = KeyPressMask | KeyReleaseMask |          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
965                  ButtonPressMask | ButtonReleaseMask |                  VisibilityChangeMask | FocusChangeMask;
                 EnterWindowMask | LeaveWindowMask;  
         if (sendmotion)  
                 input_mask |= PointerMotionMask;  
966    
967          if (ownbackstore)          if (g_sendmotion)
968                    input_mask |= PointerMotionMask;
969            if (g_ownbackstore)
970                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
971            if (g_fullscreen || g_grab_keyboard)
972                    input_mask |= EnterWindowMask;
973            if (g_grab_keyboard)
974                    input_mask |= LeaveWindowMask;
975    
976          XSelectInput(display, wnd, input_mask);          if (g_IM != NULL)
977          gc = XCreateGC(display, wnd, 0, NULL);          {
978                    g_IC = XCreateIC(g_IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
979                                     XNClientWindow, g_wnd, XNFocusWindow, g_wnd, NULL);
980    
981          if (ownbackstore)                  if ((g_IC != NULL)
982                  backstore = XCreatePixmap(display, wnd, width, height, depth);                      && (XGetICValues(g_IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
983                            input_mask |= ic_input_mask;
984            }
985    
986          XMapWindow(display, wnd);          XSelectInput(g_display, g_wnd, input_mask);
987            XMapWindow(g_display, g_wnd);
988    
989          /* TODO: error texts... make them friendly. */          /* wait for VisibilityNotify */
990          xkb = XkbGetKeyboard(display, XkbAllComponentsMask, XkbUseCoreKbd);          do
         if ((int) xkb == BadAlloc || xkb == NULL)  
991          {          {
992                  error("XkbGetKeyboard failed.\n");                  XMaskEvent(g_display, VisibilityChangeMask, &xevent);
                 exit(0);  
993          }          }
994            while (xevent.type != VisibilityNotify);
995    
996          /* TODO: error texts... make them friendly. */          g_focused = False;
997          if (XkbSelectEvents          g_mouse_in_wnd = False;
998              (display, xkb->device_spec, XkbAllEventsMask,  
999               XkbAllEventsMask) == False)          /* handle the WM_DELETE_WINDOW protocol */
1000          {          g_protocol_atom = XInternAtom(g_display, "WM_PROTOCOLS", True);
1001                  error("XkbSelectEvents failed.\n");          g_kill_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", True);
1002                  exit(0);          XSetWMProtocols(g_display, g_wnd, &g_kill_atom, 1);
         }  
1003    
1004          xwin_get_numlock_mask();          /* create invisible 1x1 cursor to be used as null cursor */
1005            if (g_null_cursor == NULL)
1006                    g_null_cursor = ui_create_cursor(0, 0, 1, 1, null_pointer_mask, null_pointer_data);
1007    
1008          return True;          return True;
1009  }  }
1010    
1011  void  void
1012  xwin_get_numlock_mask()  ui_resize_window()
1013  {  {
1014          KeyCode numlockcode;          XSizeHints *sizehints;
         KeyCode *keycode;  
         XModifierKeymap *modmap;  
         int i, j;  
1015    
1016          /* Find out if numlock is already defined as a modifier key, and if so where */          sizehints = XAllocSizeHints();
1017          numlockcode = XKeysymToKeycode(display, 0xFF7F);        /* XF_Num_Lock = 0xFF7F */          if (sizehints)
1018          if (numlockcode)          {
1019          {                  sizehints->flags = PMinSize | PMaxSize;
1020                  modmap = XGetModifierMapping(display);                  sizehints->min_width = sizehints->max_width = g_width;
1021                  if (modmap)                  sizehints->min_height = sizehints->max_height = g_height;
1022                  {                  XSetWMNormalHints(g_display, g_wnd, sizehints);
1023                          keycode = modmap->modifiermap;                  XFree(sizehints);
1024                          for (i = 0; i < 8; i++)          }
1025                                  for (j = modmap->max_keypermod; j--;)  
1026                                  {          if (!(g_fullscreen || g_embed_wnd))
1027                                          if (*keycode == numlockcode)          {
1028                                          {                  XResizeWindow(g_display, g_wnd, g_width, g_height);
                                                 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);  
                 }  
1029          }          }
1030    }
1031    
1032          if (!numlock_modifier_mask)  void
1033                  printf("WARNING: Failed to get a numlock modifier mapping.\n");  ui_destroy_window(void)
1034    {
1035            if (g_IC != NULL)
1036                    XDestroyIC(g_IC);
1037    
1038            XDestroyWindow(g_display, g_wnd);
1039  }  }
1040    
1041  void  void
1042  ui_destroy_window()  xwin_toggle_fullscreen(void)
1043  {  {
1044          if (xkb != NULL)          Pixmap contents = 0;
                 XkbFreeKeyboard(xkb, XkbAllControlsMask, True);  
1045    
1046          if (ownbackstore)          if (!g_ownbackstore)
1047                  XFreePixmap(display, backstore);          {
1048                    /* need to save contents of window */
1049                    contents = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
1050                    XCopyArea(g_display, g_wnd, contents, g_gc, 0, 0, g_width, g_height, 0, 0);
1051            }
1052    
1053            ui_destroy_window();
1054            g_fullscreen = !g_fullscreen;
1055            ui_create_window();
1056    
1057          XFreeGC(display, gc);          XDefineCursor(g_display, g_wnd, g_current_cursor);
1058          XDestroyWindow(display, wnd);  
1059          XCloseDisplay(display);          if (!g_ownbackstore)
1060          display = NULL;          {
1061                    XCopyArea(g_display, contents, g_wnd, g_gc, 0, 0, g_width, g_height, 0, 0);
1062                    XFreePixmap(g_display, contents);
1063            }
1064  }  }
1065    
1066  static void  /* Process all events in Xlib queue
1067  xwin_process_events()     Returns 0 after user quit, 1 otherwise */
1068    static int
1069    xwin_process_events(void)
1070  {  {
1071          XEvent xevent;          XEvent xevent;
   
1072          KeySym keysym;          KeySym keysym;
         uint8 scancode;  
1073          uint16 button, flags;          uint16 button, flags;
1074          uint32 ev_time;          uint32 ev_time;
1075          uint32 tmpmods;          key_translation tr;
1076            char str[256];
1077            Status status;
1078    
1079          while (XCheckMaskEvent(display, ~0, &xevent))          while (XPending(g_display) > 0)
1080          {          {
1081                  ev_time = time(NULL);                  XNextEvent(g_display, &xevent);
1082    
1083                    if ((g_IC != NULL) && (XFilterEvent(&xevent, None) == True))
1084                    {
1085                            DEBUG_KBD(("Filtering event\n"));
1086                            continue;
1087                    }
1088    
1089                  flags = 0;                  flags = 0;
1090    
1091                  switch (xevent.type)                  switch (xevent.type)
1092                  {                  {
1093                          case KeyRelease:                          case ClientMessage:
1094                                  flags = KBD_FLAG_DOWN | KBD_FLAG_UP;                                  /* the window manager told us to quit */
1095                                  /* fall through */                                  if ((xevent.xclient.message_type == g_protocol_atom)
1096                          case KeyPress:                                      && ((Atom) xevent.xclient.data.l[0] == g_kill_atom))
1097                                  if (XkbTranslateKeyCode                                          /* Quit */
1098                                      (xkb, xevent.xkey.keycode,                                          return 0;
                                      xevent.xkey.state, &tmpmods,  
                                      &keysym) == False)  
                                         break;  
                                 scancode =  
                                         xkeymap_translate_key(keysym,  
                                                               xevent.xkey.  
                                                               keycode,  
                                                               &flags);  
   
                                 if (scancode == 0)  
                                         break;  
   
                                 /* keep track of the modifiers -- needed for stickykeys... */  
                                 if (xevent.type == KeyPress)  
                                         xwin_mod_press(xevent.xkey.state,  
                                                        ev_time, scancode);  
   
                                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                                flags, scancode, 0);  
   
                                 if (xevent.type == KeyRelease)  
                                         xwin_mod_release(xevent.xkey.state,  
                                                          ev_time, scancode);  
   
1099                                  break;                                  break;
1100    
1101                          case ButtonPress:                          case KeyPress:
1102                                  flags = MOUSE_FLAG_DOWN;                                  g_last_gesturetime = xevent.xkey.time;
1103                                  /* fall through */                                  if (g_IC != NULL)
1104                                            /* Multi_key compatible version */
1105                          case ButtonRelease:                                  {
1106                                  button = xkeymap_translate_button(xevent.                                          XmbLookupString(g_IC,
1107                                                                    xbutton.                                                          &xevent.xkey, str, sizeof(str), &keysym,
1108                                                                    button);                                                          &status);
1109                                  if (button == 0)                                          if (!((status == XLookupKeySym) || (status == XLookupBoth)))
1110                                          break;                                          {
1111                                                    error("XmbLookupString failed with status 0x%x\n",
1112                                                          status);
1113                                                    break;
1114                                            }
1115                                    }
1116                                    else
1117                                    {
1118                                            /* Plain old XLookupString */
1119                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
1120                                            XLookupString((XKeyEvent *) & xevent,
1121                                                          str, sizeof(str), &keysym, NULL);
1122                                    }
1123    
1124                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
1125                                                 flags | button,                                             get_ksname(keysym)));
                                                xevent.xbutton.x,  
                                                xevent.xbutton.y);  
                                 break;  
1126    
1127                          case MotionNotify:                                  ev_time = time(NULL);
1128                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
1129                                                 MOUSE_FLAG_MOVE,                                          break;
                                                xevent.xmotion.x,  
                                                xevent.xmotion.y);  
                                 break;  
1130    
1131                          case EnterNotify:                                  tr = xkeymap_translate_key(keysym,
1132                                  XGrabKeyboard(display, wnd, True,                                                             xevent.xkey.keycode, xevent.xkey.state);
                                               GrabModeAsync, GrabModeAsync,  
                                               CurrentTime);  
1133    
1134                                  xwin_mod_update(xevent.xcrossing.state,                                  if (tr.scancode == 0)
1135                                                  ev_time);                                          break;
                                 break;  
1136    
1137                          case LeaveNotify:                                  save_remote_modifiers(tr.scancode);
1138                                  XUngrabKeyboard(display, CurrentTime);                                  ensure_remote_modifiers(ev_time, tr);
1139                                  break;                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
1140                                    restore_remote_modifiers(ev_time, tr.scancode);
1141    
                         case Expose:  
                                 XCopyArea(display, backstore, wnd, gc,  
                                           xevent.xexpose.x, xevent.xexpose.y,  
                                           xevent.xexpose.width,  
                                           xevent.xexpose.height,  
                                           xevent.xexpose.x, xevent.xexpose.y);  
1142                                  break;                                  break;
                 }  
         }  
 }  
   
 void  
 xwin_mod_update(uint32 state, uint32 ev_time)  
 {  
         xwin_mod_press(state, ev_time, 0);  
         xwin_mod_release(state, ev_time, 0);  
 }  
   
 void  
 xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode)  
 {  
         switch (scancode)  
         {  
                 case 0x2a:  
                         key_down_state &= ~DShift1Mask;  
                         break;  
                 case 0x36:  
                         key_down_state &= ~DShift2Mask;  
                         break;  
                 case 0x1d:  
                         key_down_state &= ~DControl1Mask;  
                         break;  
                 case 0x9d:  
                         key_down_state &= ~DControl2Mask;  
                         break;  
                 case 0x38:  
                         key_down_state &= ~DMod1Mask;  
                         break;  
                 case 0xb8:  
                         key_down_state &= ~DMod2Mask;  
                         break;  
         }  
   
         if (!(numlock_modifier_mask & state)  
             && (key_down_state & DNumLockMask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);  
                 key_down_state &= ~DNumLockMask;  
         }  
   
         if (!(LockMask & state) && (key_down_state & DLockMask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);  
                 key_down_state &= ~DLockMask;  
   
         }  
1143    
1144                            case KeyRelease:
1145                                    g_last_gesturetime = xevent.xkey.time;
1146                                    XLookupString((XKeyEvent *) & xevent, str,
1147                                                  sizeof(str), &keysym, NULL);
1148    
1149          if (!(ShiftMask & state) && (key_down_state & DShift1Mask))                                  DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
1150          {                                             get_ksname(keysym)));
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a,  
                                0);  
                 key_down_state &= ~DShift1Mask;  
1151    
1152          }                                  ev_time = time(NULL);
1153                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
1154                                            break;
1155    
1156          if (!(ControlMask & state) && (key_down_state & DControl1Mask))                                  tr = xkeymap_translate_key(keysym,
1157          {                                                             xevent.xkey.keycode, xevent.xkey.state);
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d,  
                                0);  
                 key_down_state &= ~DControl1Mask;  
1158    
1159          }                                  if (tr.scancode == 0)
1160                                            break;
1161    
1162          if (!(Mod1Mask & state) && (key_down_state & DMod1Mask))                                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
1163          {                                  break;
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38,  
                                0);  
                 key_down_state &= ~DMod1Mask;  
1164    
1165          }                          case ButtonPress:
1166                                    flags = MOUSE_FLAG_DOWN;
1167                                    /* fall through */
1168    
1169          if (!(Mod2Mask & state) && (key_down_state & DMod2Mask))                          case ButtonRelease:
1170          {                                  g_last_gesturetime = xevent.xbutton.time;
1171                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8,                                  button = xkeymap_translate_button(xevent.xbutton.button);
1172                                 0);                                  if (button == 0)
1173                  key_down_state &= ~DMod2Mask;                                          break;
         }  
 }  
1174    
1175                                    /* If win_button_size is nonzero, enable single app mode */
1176                                    if (xevent.xbutton.y < g_win_button_size)
1177                                    {
1178                                            /* Stop moving window when button is released, regardless of cursor position */
1179                                            if (g_moving_wnd && (xevent.type == ButtonRelease))
1180                                                    g_moving_wnd = False;
1181    
1182  void                                          /*  Check from right to left: */
 xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode)  
 {  
1183    
1184          switch (scancode)                                          if (xevent.xbutton.x >= g_width - g_win_button_size)
1185          {                                          {
1186                  case 0x2a:                                                  /* The close button, continue */
1187                          key_down_state |= DShift1Mask;                                                  ;
1188                          break;                                          }
1189                  case 0x36:                                          else if (xevent.xbutton.x >=
1190                          key_down_state |= DShift2Mask;                                                   g_width - g_win_button_size * 2)
1191                          break;                                          {
1192                  case 0x1d:                                                  /* The maximize/restore button. Do not send to
1193                          key_down_state |= DControl1Mask;                                                     server.  It might be a good idea to change the
1194                          break;                                                     cursor or give some other visible indication
1195                  case 0x9d:                                                     that rdesktop inhibited this click */
1196                          key_down_state |= DControl2Mask;                                                  break;
1197                          break;                                          }
1198                  case 0x3a:                                          else if (xevent.xbutton.x >=
1199                          key_down_state ^= DLockMask;                                                   g_width - g_win_button_size * 3)
1200                          break;                                          {
1201                  case 0x45:                                                  /* The minimize button. Iconify window. */
1202                          key_down_state ^= DNumLockMask;                                                  XIconifyWindow(g_display, g_wnd,
1203                          break;                                                                 DefaultScreen(g_display));
1204                  case 0x38:                                                  break;
1205                          key_down_state |= DMod1Mask;                                          }
1206                          break;                                          else if (xevent.xbutton.x <= g_win_button_size)
1207                  case 0xb8:                                          {
1208                          key_down_state |= DMod2Mask;                                                  /* The system menu. Ignore. */
1209                          break;                                                  break;
1210          }                                          }
1211                                            else
1212                                            {
1213                                                    /* The title bar. */
1214                                                    if ((xevent.type == ButtonPress) && !g_fullscreen
1215                                                        && g_hide_decorations)
1216                                                    {
1217                                                            g_moving_wnd = True;
1218                                                            g_move_x_offset = xevent.xbutton.x;
1219                                                            g_move_y_offset = xevent.xbutton.y;
1220                                                    }
1221                                                    break;
1222    
1223          if ((numlock_modifier_mask && state)                                          }
1224              && !(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;  
         }  
1225    
1226          if ((LockMask & state) && !(key_down_state & DLockMask))                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1227          {                                                 flags | button, xevent.xbutton.x, xevent.xbutton.y);
1228                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);                                  break;
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);  
                 key_down_state |= DLockMask;  
1229    
1230          }                          case MotionNotify:
1231                                    if (g_moving_wnd)
1232                                    {
1233                                            XMoveWindow(g_display, g_wnd,
1234                                                        xevent.xmotion.x_root - g_move_x_offset,
1235                                                        xevent.xmotion.y_root - g_move_y_offset);
1236                                            break;
1237                                    }
1238    
1239                                    if (g_fullscreen && !g_focused)
1240                                            XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1241                                                           CurrentTime);
1242                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1243                                                   MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
1244                                    break;
1245    
1246          if ((ShiftMask & state)                          case FocusIn:
1247              && !((key_down_state & DShift1Mask)                                  if (xevent.xfocus.mode == NotifyGrab)
1248                   || (key_down_state & DShift2Mask)))                                          break;
1249          {                                  g_focused = True;
1250                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,                                  reset_modifier_keys();
1251                                 0x2a, 0);                                  if (g_grab_keyboard && g_mouse_in_wnd)
1252                  key_down_state |= DShift1Mask;                                          XGrabKeyboard(g_display, g_wnd, True,
1253                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
1254                                    break;
1255    
1256          }                          case FocusOut:
1257                                    if (xevent.xfocus.mode == NotifyUngrab)
1258                                            break;
1259                                    g_focused = False;
1260                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
1261                                            XUngrabKeyboard(g_display, CurrentTime);
1262                                    break;
1263    
1264          if ((ControlMask & state)                          case EnterNotify:
1265              && !((key_down_state & DControl1Mask)                                  /* we only register for this event when in fullscreen mode */
1266                   || (key_down_state & DControl2Mask)))                                  /* or grab_keyboard */
1267          {                                  g_mouse_in_wnd = True;
1268                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,                                  if (g_fullscreen)
1269                                 0x1d, 0);                                  {
1270                  key_down_state |= DControl1Mask;                                          XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1271                                                           CurrentTime);
1272                                            break;
1273                                    }
1274                                    if (g_focused)
1275                                            XGrabKeyboard(g_display, g_wnd, True,
1276                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
1277                                    break;
1278    
1279          }                          case LeaveNotify:
1280                                    /* we only register for this event when grab_keyboard */
1281                                    g_mouse_in_wnd = False;
1282                                    XUngrabKeyboard(g_display, CurrentTime);
1283                                    break;
1284    
1285          if ((Mod1Mask & state) && !(key_down_state & DMod1Mask))                          case Expose:
1286          {                                  XCopyArea(g_display, g_backstore, g_wnd, g_gc,
1287                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,                                            xevent.xexpose.x, xevent.xexpose.y,
1288                                 0x38, 0);                                            xevent.xexpose.width,
1289                  key_down_state |= DMod1Mask;                                            xevent.xexpose.height,
1290                                              xevent.xexpose.x, xevent.xexpose.y);
1291                                    break;
1292    
1293          }                          case MappingNotify:
1294                                    /* Refresh keyboard mapping if it has changed. This is important for
1295                                       Xvnc, since it allocates keycodes dynamically */
1296                                    if (xevent.xmapping.request == MappingKeyboard
1297                                        || xevent.xmapping.request == MappingModifier)
1298                                            XRefreshKeyboardMapping(&xevent.xmapping);
1299    
1300          if ((Mod2Mask & state) && !(key_down_state & DMod2Mask))                                  if (xevent.xmapping.request == MappingModifier)
1301          {                                  {
1302                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,                                          XFreeModifiermap(g_mod_map);
1303                                 0xb8, 0);                                          g_mod_map = XGetModifierMapping(g_display);
1304                  key_down_state |= DMod2Mask;                                  }
1305                                    break;
1306    
1307                                    /* clipboard stuff */
1308                            case SelectionNotify:
1309                                    xclip_handle_SelectionNotify(&xevent.xselection);
1310                                    break;
1311                            case SelectionRequest:
1312                                    xclip_handle_SelectionRequest(&xevent.xselectionrequest);
1313                                    break;
1314                            case SelectionClear:
1315                                    xclip_handle_SelectionClear();
1316                                    break;
1317                            case PropertyNotify:
1318                                    xclip_handle_PropertyNotify(&xevent.xproperty);
1319                                    break;
1320                    }
1321          }          }
1322            /* Keep going */
1323            return 1;
1324  }  }
1325    
1326  void  /* Returns 0 after user quit, 1 otherwise */
1327    int
1328  ui_select(int rdp_socket)  ui_select(int rdp_socket)
1329  {  {
1330          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;          int n;
1331          fd_set rfds;          fd_set rfds, wfds;
1332            struct timeval tv;
1333          FD_ZERO(&rfds);          BOOL s_timeout = False;
1334    
1335          while (True)          while (True)
1336          {          {
1337                    n = (rdp_socket > g_x_socket) ? rdp_socket : g_x_socket;
1338                    /* Process any events already waiting */
1339                    if (!xwin_process_events())
1340                            /* User quit */
1341                            return 0;
1342    
1343                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
1344                    FD_ZERO(&wfds);
1345                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
1346                  if (display != NULL)                  FD_SET(g_x_socket, &rfds);
1347    
1348    #ifdef WITH_RDPSND
1349                    /* FIXME: there should be an API for registering fds */
1350                    if (g_dsp_busy)
1351                  {                  {
1352                          FD_SET(x_socket, &rfds);                          FD_SET(g_dsp_fd, &wfds);
1353                          XFlush(display);                          n = (g_dsp_fd > n) ? g_dsp_fd : n;
1354                  }                  }
1355    #endif
1356                    /* default timeout */
1357                    tv.tv_sec = 60;
1358                    tv.tv_usec = 0;
1359    
1360                    /* add redirection handles */
1361                    rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
1362    
1363                    n++;
1364    
1365                  switch (select(n, &rfds, NULL, NULL, NULL))                  switch (select(n, &rfds, &wfds, NULL, &tv))
1366                  {                  {
1367                          case -1:                          case -1:
1368                                  error("select: %s\n", strerror(errno));                                  error("select: %s\n", strerror(errno));
1369    
1370                          case 0:                          case 0:
1371                                    /* TODO: if tv.tv_sec just times out
1372                                     * we will segfault.
1373                                     * FIXME:
1374                                     */
1375                                    //s_timeout = True;
1376                                    //rdpdr_check_fds(&rfds, &wfds, (BOOL) True);
1377                                  continue;                                  continue;
1378                  }                  }
1379    
1380                  if (FD_ISSET(x_socket, &rfds))                  rdpdr_check_fds(&rfds, &wfds, (BOOL) False);
                         xwin_process_events();  
1381    
1382                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
1383                          return;                          return 1;
1384    
1385    #ifdef WITH_RDPSND
1386                    if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))
1387                            wave_out_play();
1388    #endif
1389          }          }
1390  }  }
1391    
1392  void  void
1393  ui_move_pointer(int x, int y)  ui_move_pointer(int x, int y)
1394  {  {
1395          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);          XWarpPointer(g_display, g_wnd, g_wnd, 0, 0, 0, 0, x, y);
1396  }  }
1397    
1398  HBITMAP  HBITMAP
# Line 761  ui_create_bitmap(int width, int height, Line 1401  ui_create_bitmap(int width, int height,
1401          XImage *image;          XImage *image;
1402          Pixmap bitmap;          Pixmap bitmap;
1403          uint8 *tdata;          uint8 *tdata;
1404            int bitmap_pad;
1405    
1406            if (g_server_bpp == 8)
1407            {
1408                    bitmap_pad = 8;
1409            }
1410            else
1411            {
1412                    bitmap_pad = g_bpp;
1413    
1414          tdata = (owncolmap ? data : translate_image(width, height, data));                  if (g_bpp == 24)
1415          bitmap = XCreatePixmap(display, wnd, width, height, depth);                          bitmap_pad = 32;
1416          image = XCreateImage(display, visual, depth, ZPixmap,          }
                              0, tdata, width, height, 8, 0);  
1417    
1418          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          tdata = (g_owncolmap ? data : translate_image(width, height, data));
1419            bitmap = XCreatePixmap(g_display, g_wnd, width, height, g_depth);
1420            image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1421                                 (char *) tdata, width, height, bitmap_pad, 0);
1422    
1423            XPutImage(g_display, bitmap, g_gc, image, 0, 0, 0, 0, width, height);
1424    
1425          XFree(image);          XFree(image);
1426          if (!owncolmap)          if (tdata != data)
1427                  xfree(tdata);                  xfree(tdata);
1428          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
1429  }  }
1430    
1431  void  void
1432  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)  
1433  {  {
1434          XImage *image;          XImage *image;
1435          uint8 *tdata;          uint8 *tdata;
1436            int bitmap_pad;
1437    
1438          tdata = (owncolmap ? data : translate_image(width, height, data));          if (g_server_bpp == 8)
1439          image = XCreateImage(display, visual, depth, ZPixmap,          {
1440                               0, tdata, width, height, 8, 0);                  bitmap_pad = 8;
1441            }
1442            else
1443            {
1444                    bitmap_pad = g_bpp;
1445    
1446          if (ownbackstore)                  if (g_bpp == 24)
1447                            bitmap_pad = 32;
1448            }
1449    
1450            tdata = (g_owncolmap ? data : translate_image(width, height, data));
1451            image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1452                                 (char *) tdata, width, height, bitmap_pad, 0);
1453    
1454            if (g_ownbackstore)
1455          {          {
1456                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);
1457                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
1458          }          }
1459          else          else
1460          {          {
1461                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);
1462          }          }
1463    
1464          XFree(image);          XFree(image);
1465          if (!owncolmap)          if (tdata != data)
1466                  xfree(tdata);                  xfree(tdata);
1467  }  }
1468    
1469  void  void
1470  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
1471  {  {
1472          XFreePixmap(display, (Pixmap) bmp);          XFreePixmap(g_display, (Pixmap) bmp);
1473  }  }
1474    
1475  HGLYPH  HGLYPH
# Line 817  ui_create_glyph(int width, int height, u Line 1482  ui_create_glyph(int width, int height, u
1482    
1483          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1484    
1485          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);
1486          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(g_display, bitmap, 0, NULL);
1487    
1488          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,
1489                               data, width, height, 8, scanline);                               width, height, 8, scanline);
1490          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
1491          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1492          XInitImage(image);          XInitImage(image);
1493    
1494          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(g_display, bitmap, gc, image, 0, 0, 0, 0, width, height);
1495    
1496          XFree(image);          XFree(image);
1497          XFreeGC(display, gc);          XFreeGC(g_display, gc);
1498          return (HGLYPH) bitmap;          return (HGLYPH) bitmap;
1499  }  }
1500    
1501  void  void
1502  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
1503  {  {
1504          XFreePixmap(display, (Pixmap) glyph);          XFreePixmap(g_display, (Pixmap) glyph);
1505  }  }
1506    
1507  HCURSOR  HCURSOR
1508  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
1509                   int height, uint8 * andmask, uint8 * xormask)                   uint8 * andmask, uint8 * xormask)
1510  {  {
1511          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
1512          XColor bg, fg;          XColor bg, fg;
# Line 855  ui_create_cursor(unsigned int x, unsigne Line 1520  ui_create_cursor(unsigned int x, unsigne
1520          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1521          offset = scanline * height;          offset = scanline * height;
1522    
1523          cursor = xmalloc(offset);          cursor = (uint8 *) xmalloc(offset);
1524          memset(cursor, 0, offset);          memset(cursor, 0, offset);
1525    
1526          mask = xmalloc(offset);          mask = (uint8 *) xmalloc(offset);
1527          memset(mask, 0, offset);          memset(mask, 0, offset);
1528    
1529          /* 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 1564  ui_create_cursor(unsigned int x, unsigne
1564          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
1565          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
1566    
1567          xcursor = XCreatePixmapCursor(display, (Pixmap) cursorglyph,          xcursor =
1568                                        (Pixmap) maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(g_display, (Pixmap) cursorglyph,
1569                                        (Pixmap) maskglyph, &fg, &bg, x, y);
1570    
1571          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
1572          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
# Line 912  ui_create_cursor(unsigned int x, unsigne Line 1578  ui_create_cursor(unsigned int x, unsigne
1578  void  void
1579  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
1580  {  {
1581          XDefineCursor(display, wnd, (Cursor) cursor);          g_current_cursor = (Cursor) cursor;
1582            XDefineCursor(g_display, g_wnd, g_current_cursor);
1583  }  }
1584    
1585  void  void
1586  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
1587  {  {
1588          XFreeCursor(display, (Cursor) cursor);          XFreeCursor(g_display, (Cursor) cursor);
1589    }
1590    
1591    void
1592    ui_set_null_cursor(void)
1593    {
1594            ui_set_cursor(g_null_cursor);
1595  }  }
1596    
1597  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 927  ui_destroy_cursor(HCURSOR cursor) Line 1600  ui_destroy_cursor(HCURSOR cursor)
1600                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
1601                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
1602    
1603    
1604  HCOLOURMAP  HCOLOURMAP
1605  ui_create_colourmap(COLOURMAP * colours)  ui_create_colourmap(COLOURMAP * colours)
1606  {  {
1607          COLOURENTRY *entry;          COLOURENTRY *entry;
1608          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
1609            if (!g_owncolmap)
1610            {
1611                    uint32 *map = (uint32 *) xmalloc(sizeof(*g_colmap) * ncolours);
1612                    XColor xentry;
1613                    XColor xc_cache[256];
1614                    uint32 colour;
1615                    int colLookup = 256;
1616                    for (i = 0; i < ncolours; i++)
1617                    {
1618                            entry = &colours->colours[i];
1619                            MAKE_XCOLOR(&xentry, entry);
1620    
1621                            if (XAllocColor(g_display, g_xcolmap, &xentry) == 0)
1622                            {
1623                                    /* Allocation failed, find closest match. */
1624                                    int j = 256;
1625                                    int nMinDist = 3 * 256 * 256;
1626                                    long nDist = nMinDist;
1627    
1628                                    /* only get the colors once */
1629                                    while (colLookup--)
1630                                    {
1631                                            xc_cache[colLookup].pixel = colLookup;
1632                                            xc_cache[colLookup].red = xc_cache[colLookup].green =
1633                                                    xc_cache[colLookup].blue = 0;
1634                                            xc_cache[colLookup].flags = 0;
1635                                            XQueryColor(g_display,
1636                                                        DefaultColormap(g_display,
1637                                                                        DefaultScreen(g_display)),
1638                                                        &xc_cache[colLookup]);
1639                                    }
1640                                    colLookup = 0;
1641    
1642                                    /* approximate the pixel */
1643                                    while (j--)
1644                                    {
1645                                            if (xc_cache[j].flags)
1646                                            {
1647                                                    nDist = ((long) (xc_cache[j].red >> 8) -
1648                                                             (long) (xentry.red >> 8)) *
1649                                                            ((long) (xc_cache[j].red >> 8) -
1650                                                             (long) (xentry.red >> 8)) +
1651                                                            ((long) (xc_cache[j].green >> 8) -
1652                                                             (long) (xentry.green >> 8)) *
1653                                                            ((long) (xc_cache[j].green >> 8) -
1654                                                             (long) (xentry.green >> 8)) +
1655                                                            ((long) (xc_cache[j].blue >> 8) -
1656                                                             (long) (xentry.blue >> 8)) *
1657                                                            ((long) (xc_cache[j].blue >> 8) -
1658                                                             (long) (xentry.blue >> 8));
1659                                            }
1660                                            if (nDist < nMinDist)
1661                                            {
1662                                                    nMinDist = nDist;
1663                                                    xentry.pixel = j;
1664                                            }
1665                                    }
1666                            }
1667                            colour = xentry.pixel;
1668    
1669                            /* update our cache */
1670                            if (xentry.pixel < 256)
1671                            {
1672                                    xc_cache[xentry.pixel].red = xentry.red;
1673                                    xc_cache[xentry.pixel].green = xentry.green;
1674                                    xc_cache[xentry.pixel].blue = xentry.blue;
1675    
1676                            }
1677    
1678          if (owncolmap)                          map[i] = colour;
1679                    }
1680                    return map;
1681            }
1682            else
1683          {          {
1684                  XColor *xcolours, *xentry;                  XColor *xcolours, *xentry;
1685                  Colormap map;                  Colormap map;
1686    
1687                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  xcolours = (XColor *) xmalloc(sizeof(XColor) * ncolours);
1688                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
1689                  {                  {
1690                          entry = &colours->colours[i];                          entry = &colours->colours[i];
# Line 947  ui_create_colourmap(COLOURMAP * colours) Line 1693  ui_create_colourmap(COLOURMAP * colours)
1693                          MAKE_XCOLOR(xentry, entry);                          MAKE_XCOLOR(xentry, entry);
1694                  }                  }
1695    
1696                  map = XCreateColormap(display, wnd, visual, AllocAll);                  map = XCreateColormap(g_display, g_wnd, g_visual, AllocAll);
1697                  XStoreColors(display, map, xcolours, ncolours);                  XStoreColors(g_display, map, xcolours, ncolours);
1698    
1699                  xfree(xcolours);                  xfree(xcolours);
1700                  return (HCOLOURMAP) map;                  return (HCOLOURMAP) map;
1701          }          }
         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;  
         }  
1702  }  }
1703    
1704  void  void
1705  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
1706  {  {
1707          if (owncolmap)          if (!g_owncolmap)
                 XFreeColormap(display, (Colormap) map);  
         else  
1708                  xfree(map);                  xfree(map);
1709            else
1710                    XFreeColormap(g_display, (Colormap) map);
1711  }  }
1712    
1713  void  void
1714  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
1715  {  {
1716          if (owncolmap)          if (!g_owncolmap)
1717                  XSetWindowColormap(display, wnd, (Colormap) map);          {
1718                    if (g_colmap)
1719                            xfree(g_colmap);
1720    
1721                    g_colmap = (uint32 *) map;
1722            }
1723          else          else
1724                  colmap = map;                  XSetWindowColormap(g_display, g_wnd, (Colormap) map);
1725  }  }
1726    
1727  void  void
# Line 1004  ui_set_clip(int x, int y, int cx, int cy Line 1733  ui_set_clip(int x, int y, int cx, int cy
1733          rect.y = y;          rect.y = y;
1734          rect.width = cx;          rect.width = cx;
1735          rect.height = cy;          rect.height = cy;
1736          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
1737  }  }
1738    
1739  void  void
1740  ui_reset_clip()  ui_reset_clip(void)
1741  {  {
1742          XRectangle rect;          XRectangle rect;
1743    
1744          rect.x = 0;          rect.x = 0;
1745          rect.y = 0;          rect.y = 0;
1746          rect.width = width;          rect.width = g_width;
1747          rect.height = height;          rect.height = g_height;
1748          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
1749  }  }
1750    
1751  void  void
1752  ui_bell()  ui_bell(void)
1753  {  {
1754          XBell(display, 0);          XBell(g_display, 0);
1755  }  }
1756    
1757  void  void
# Line 1034  ui_destblt(uint8 opcode, Line 1763  ui_destblt(uint8 opcode,
1763          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1764  }  }
1765    
1766    static uint8 hatch_patterns[] = {
1767            0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */
1768            0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */
1769            0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */
1770            0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */
1771            0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */
1772            0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81  /* 5 - bsDiagCross */
1773    };
1774    
1775  void  void
1776  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
1777            /* 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 1789  ui_patblt(uint8 opcode,
1789                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1790                          break;                          break;
1791    
1792                    case 2: /* Hatch */
1793                            fill = (Pixmap) ui_create_glyph(8, 8,
1794                                                            hatch_patterns + brush->pattern[0] * 8);
1795                            SET_FOREGROUND(fgcolour);
1796                            SET_BACKGROUND(bgcolour);
1797                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
1798                            XSetStipple(g_display, g_gc, fill);
1799                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
1800                            FILL_RECTANGLE(x, y, cx, cy);
1801                            XSetFillStyle(g_display, g_gc, FillSolid);
1802                            XSetTSOrigin(g_display, g_gc, 0, 0);
1803                            ui_destroy_glyph((HGLYPH) fill);
1804                            break;
1805    
1806                  case 3: /* Pattern */                  case 3: /* Pattern */
1807                          for (i = 0; i != 8; i++)                          for (i = 0; i != 8; i++)
1808                                  ipattern[7 - i] = brush->pattern[i];                                  ipattern[7 - i] = brush->pattern[i];
# Line 1058  ui_patblt(uint8 opcode, Line 1810  ui_patblt(uint8 opcode,
1810    
1811                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
1812                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
1813                          XSetFillStyle(display, gc, FillOpaqueStippled);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
1814                          XSetStipple(display, gc, fill);                          XSetStipple(g_display, g_gc, fill);
1815                          XSetTSOrigin(display, gc, brush->xorigin,                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
                                      brush->yorigin);  
1816    
1817                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1818    
1819                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
1820                            XSetTSOrigin(g_display, g_gc, 0, 0);
1821                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
1822                          break;                          break;
1823    
# Line 1082  ui_screenblt(uint8 opcode, Line 1834  ui_screenblt(uint8 opcode,
1834               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
1835  {  {
1836          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1837          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          if (g_ownbackstore)
1838          if (ownbackstore)          {
1839                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
1840                            cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);
1841            }
1842            else
1843            {
1844                    XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
1845            }
1846          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1847  }  }
1848    
# Line 1095  ui_memblt(uint8 opcode, Line 1852  ui_memblt(uint8 opcode,
1852            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1853  {  {
1854          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1855          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(g_display, (Pixmap) src, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
1856          if (ownbackstore)          if (g_ownbackstore)
1857                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy,                  XCopyArea(g_display, (Pixmap) src, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1858          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1859  }  }
1860    
# Line 1115  ui_triblt(uint8 opcode, Line 1871  ui_triblt(uint8 opcode,
1871          {          {
1872                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1873                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1874                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1875                          break;                          break;
1876    
1877                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1878                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1879                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1880                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1881                          break;                          break;
1882    
1883                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1884                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1885                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1886                          break;                          break;
1887    
1888                  default:                  default:
# Line 1146  ui_line(uint8 opcode, Line 1898  ui_line(uint8 opcode,
1898  {  {
1899          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1900          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
1901          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(g_display, g_wnd, g_gc, startx, starty, endx, endy);
1902          if (ownbackstore)          if (g_ownbackstore)
1903                  XDrawLine(display, backstore, gc, startx, starty, endx, endy);                  XDrawLine(g_display, g_backstore, g_gc, startx, starty, endx, endy);
1904          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1905  }  }
1906    
# Line 1161  ui_rect( Line 1913  ui_rect(
1913          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
1914  }  }
1915    
1916    /* warning, this function only draws on wnd or backstore, not both */
1917  void  void
1918  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1919                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1920                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1921                int fgcolour)                int bgcolour, int fgcolour)
1922  {  {
1923          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1924          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1925    
1926          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(g_display, g_gc,
1927                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1928          XSetStipple(display, gc, (Pixmap) glyph);          XSetStipple(g_display, g_gc, (Pixmap) glyph);
1929          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(g_display, g_gc, x, y);
1930    
1931          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
1932    
1933          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(g_display, g_gc, FillSolid);
1934  }  }
1935    
1936  #define DO_GLYPH(ttext,idx) \  #define DO_GLYPH(ttext,idx) \
1937  {\  {\
1938    glyph = cache_get_font (font, ttext[idx]);\    glyph = cache_get_font (font, ttext[idx]);\
1939    if (!(flags & TEXT2_IMPLICIT_X))\    if (!(flags & TEXT2_IMPLICIT_X))\
1940      {\
1941        xyoffset = ttext[++idx];\
1942        if ((xyoffset & 0x80))\
1943      {\      {\
1944        xyoffset = ttext[++idx];\        if (flags & TEXT2_VERTICAL)\
1945        if ((xyoffset & 0x80))\          y += ttext[idx+1] | (ttext[idx+2] << 8);\
         {\  
           if (flags & TEXT2_VERTICAL) \  
             y += ttext[++idx] | (ttext[++idx] << 8);\  
           else\  
             x += ttext[++idx] | (ttext[++idx] << 8);\  
         }\  
1946        else\        else\
1947          {\          x += ttext[idx+1] | (ttext[idx+2] << 8);\
1948            if (flags & TEXT2_VERTICAL) \        idx += 2;\
             y += xyoffset;\  
           else\  
             x += xyoffset;\  
         }\  
1949      }\      }\
1950    if (glyph != NULL)\      else\
1951      {\      {\
1952        ui_draw_glyph (mixmode, x + (short) glyph->offset,\        if (flags & TEXT2_VERTICAL)\
1953                       y + (short) glyph->baseline,\          y += xyoffset;\
1954                       glyph->width, glyph->height,\        else\
1955                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\          x += xyoffset;\
       if (flags & TEXT2_IMPLICIT_X)\  
         x += glyph->width;\  
1956      }\      }\
1957      }\
1958      if (glyph != NULL)\
1959      {\
1960        x1 = x + glyph->offset;\
1961        y1 = y + glyph->baseline;\
1962        XSetStipple(g_display, g_gc, (Pixmap) glyph->pixmap);\
1963        XSetTSOrigin(g_display, g_gc, x1, y1);\
1964        FILL_RECTANGLE_BACKSTORE(x1, y1, glyph->width, glyph->height);\
1965        if (flags & TEXT2_IMPLICIT_X)\
1966          x += glyph->width;\
1967      }\
1968  }  }
1969    
1970  void  void
1971  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,
1972               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1973               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1974               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1975  {  {
1976          FONTGLYPH *glyph;          FONTGLYPH *glyph;
1977          int i, j, xyoffset;          int i, j, xyoffset, x1, y1;
1978          DATABLOB *entry;          DATABLOB *entry;
1979    
1980          SET_FOREGROUND(bgcolour);          SET_FOREGROUND(bgcolour);
1981    
1982            /* Sometimes, the boxcx value is something really large, like
1983               32691. This makes XCopyArea fail with Xvnc. The code below
1984               is a quick fix. */
1985            if (boxx + boxcx > g_width)
1986                    boxcx = g_width - boxx;
1987    
1988          if (boxcx > 1)          if (boxcx > 1)
1989          {          {
1990                  FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
1991          }          }
1992          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
1993          {          {
1994                  FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
1995          }          }
1996    
1997            SET_FOREGROUND(fgcolour);
1998            SET_BACKGROUND(bgcolour);
1999            XSetFillStyle(g_display, g_gc, FillStippled);
2000    
2001          /* Paint text, character by character */          /* Paint text, character by character */
2002          for (i = 0; i < length;)          for (i = 0; i < length;)
2003          {          {
# Line 1240  ui_draw_text(uint8 font, uint8 flags, in Line 2005  ui_draw_text(uint8 font, uint8 flags, in
2005                  {                  {
2006                          case 0xff:                          case 0xff:
2007                                  if (i + 2 < length)                                  if (i + 2 < length)
2008                                          cache_put_text(text[i + 1], text,                                          cache_put_text(text[i + 1], text, text[i + 2]);
                                                        text[i + 2]);  
2009                                  else                                  else
2010                                  {                                  {
2011                                          error("this shouldn't be happening\n");                                          error("this shouldn't be happening\n");
2012                                          break;                                          exit(1);
2013                                  }                                  }
2014                                  /* this will move pointer from start to first character after FF command */                                  /* this will move pointer from start to first character after FF command */
2015                                  length -= i + 3;                                  length -= i + 3;
# Line 1258  ui_draw_text(uint8 font, uint8 flags, in Line 2022  ui_draw_text(uint8 font, uint8 flags, in
2022                                  if (entry != NULL)                                  if (entry != NULL)
2023                                  {                                  {
2024                                          if ((((uint8 *) (entry->data))[1] ==                                          if ((((uint8 *) (entry->data))[1] ==
2025                                               0)                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
                                             && (!(flags & TEXT2_IMPLICIT_X)))  
2026                                          {                                          {
2027                                                  if (flags & TEXT2_VERTICAL)                                                  if (flags & TEXT2_VERTICAL)
2028                                                          y += text[i + 2];                                                          y += text[i + 2];
2029                                                  else                                                  else
2030                                                          x += text[i + 2];                                                          x += text[i + 2];
2031                                          }                                          }
                                         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;  
2032                                          for (j = 0; j < entry->size; j++)                                          for (j = 0; j < entry->size; j++)
2033                                                  DO_GLYPH(((uint8 *) (entry->                                                  DO_GLYPH(((uint8 *) (entry->data)), j);
                                                                      data)),  
                                                          j);  
2034                                  }                                  }
2035                                    if (i + 2 < length)
2036                                            i += 3;
2037                                    else
2038                                            i += 2;
2039                                    length -= i;
2040                                    /* this will move pointer from start to first character after FE command */
2041                                    text = &(text[i]);
2042                                    i = 0;
2043                                  break;                                  break;
2044    
2045                          default:                          default:
# Line 1288  ui_draw_text(uint8 font, uint8 flags, in Line 2049  ui_draw_text(uint8 font, uint8 flags, in
2049                  }                  }
2050          }          }
2051    
2052            XSetFillStyle(g_display, g_gc, FillSolid);
2053    
2054            if (g_ownbackstore)
2055            {
2056                    if (boxcx > 1)
2057                            XCopyArea(g_display, g_backstore, g_wnd, g_gc, boxx,
2058                                      boxy, boxcx, boxcy, boxx, boxy);
2059                    else
2060                            XCopyArea(g_display, g_backstore, g_wnd, g_gc, clipx,
2061                                      clipy, clipcx, clipcy, clipx, clipy);
2062            }
2063  }  }
2064    
2065  void  void
# Line 1297  ui_desktop_save(uint32 offset, int x, in Line 2068  ui_desktop_save(uint32 offset, int x, in
2068          Pixmap pix;          Pixmap pix;
2069          XImage *image;          XImage *image;
2070    
2071          if (ownbackstore)          if (g_ownbackstore)
2072          {          {
2073                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(g_display, g_backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
2074          }          }
2075          else          else
2076          {          {
2077                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(g_display, g_wnd, cx, cy, g_depth);
2078                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(g_display, g_wnd, pix, g_gc, x, y, cx, cy, 0, 0);
2079                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(g_display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
2080                                    ZPixmap);                  XFreePixmap(g_display, pix);
                 XFreePixmap(display, pix);  
2081          }          }
2082    
2083          offset *= bpp / 8;          offset *= g_bpp / 8;
2084          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line, g_bpp / 8, (uint8 *) image->data);
                           bpp / 8, (uint8 *) image->data);  
2085    
2086          XDestroyImage(image);          XDestroyImage(image);
2087  }  }
# Line 1324  ui_desktop_restore(uint32 offset, int x, Line 2092  ui_desktop_restore(uint32 offset, int x,
2092          XImage *image;          XImage *image;
2093          uint8 *data;          uint8 *data;
2094    
2095          offset *= bpp / 8;          offset *= g_bpp / 8;
2096          data = cache_get_desktop(offset, cx, cy, bpp / 8);          data = cache_get_desktop(offset, cx, cy, g_bpp / 8);
2097          if (data == NULL)          if (data == NULL)
2098                  return;                  return;
2099    
2100          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
2101                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(g_display), cx * g_bpp / 8);
                              cx * bpp / 8);  
2102    
2103          if (ownbackstore)          if (g_ownbackstore)
2104          {          {
2105                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);
2106                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
2107          }          }
2108          else          else
2109          {          {
2110                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);
2111          }          }
2112    
2113          XFree(image);          XFree(image);

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

  ViewVC Help
Powered by ViewVC 1.1.26