/[rdesktop]/sourceforge.net/trunk/rdesktop/xwin.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

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

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

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

Legend:
Removed from v.52  
changed lines
  Added in v.695

  ViewVC Help
Powered by ViewVC 1.1.26