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

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

  ViewVC Help
Powered by ViewVC 1.1.26