/[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 677 by n-ki, Mon Apr 26 13:48:39 2004 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     User interface services - X Window System     User interface services - X Window System
4     Copyright (C) Matthew Chapman 1999-2001     Copyright (C) Matthew Chapman 1999-2002
5    
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 20  Line 20 
20    
21  #include <X11/Xlib.h>  #include <X11/Xlib.h>
22  #include <X11/Xutil.h>  #include <X11/Xutil.h>
23  #include <X11/XKBlib.h>  #include <unistd.h>
24    #include <sys/time.h>
25  #include <time.h>  #include <time.h>
26  #include <errno.h>  #include <errno.h>
27    #include <strings.h>
28  #include "rdesktop.h"  #include "rdesktop.h"
29    #include "xproto.h"
30    
31  extern char keymapname[16];  extern int g_width;
32  extern int keylayout;  extern int g_height;
33  extern int width;  extern BOOL g_sendmotion;
34  extern int height;  extern BOOL g_fullscreen;
35  extern BOOL sendmotion;  extern BOOL g_grab_keyboard;
36  extern BOOL fullscreen;  extern BOOL g_hide_decorations;
37    extern char g_title[];
38  Display *display;  extern int g_server_bpp;
39  XkbDescPtr xkb;  extern int g_win_button_size;
40  static int x_socket;  
41  static Window wnd;  Display *g_display;
42  static GC gc;  Time g_last_gesturetime;
43  static Visual *visual;  static int g_x_socket;
44  static int depth;  static Screen *g_screen;
45  static int bpp;  Window g_wnd;
46    extern uint32 g_embed_wnd;
47    BOOL g_enable_compose = False;
48    static GC g_gc = NULL;
49    static Visual *g_visual;
50    static int g_depth;
51    static int g_bpp;
52    static XIM g_IM;
53    static XIC g_IC;
54    static XModifierKeymap *g_mod_map;
55    static Cursor g_current_cursor;
56    static HCURSOR g_null_cursor = NULL;
57    static Atom g_protocol_atom, g_kill_atom;
58    static BOOL g_focused;
59    static BOOL g_mouse_in_wnd;
60    static BOOL g_arch_match = False;       /* set to True if RGB XServer and little endian */
61    
62  /* endianness */  /* endianness */
63  static BOOL host_be;  static BOOL g_host_be;
64  static BOOL xserver_be;  static BOOL g_xserver_be;
65    static int g_red_shift_r, g_blue_shift_r, g_green_shift_r;
66    static int g_red_shift_l, g_blue_shift_l, g_green_shift_l;
67    
68  /* software backing store */  /* software backing store */
69  static BOOL ownbackstore;  extern BOOL g_ownbackstore;
70  static Pixmap backstore;  static Pixmap g_backstore = 0;
71    
72    /* Moving in single app mode */
73    static BOOL g_moving_wnd;
74    static int g_move_x_offset = 0;
75    static int g_move_y_offset = 0;
76    
77    #ifdef WITH_RDPSND
78    extern int g_dsp_fd;
79    extern BOOL g_dsp_busy;
80    extern BOOL g_rdpsnd;
81    #endif
82    
83    /* MWM decorations */
84    #define MWM_HINTS_DECORATIONS   (1L << 1)
85    #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
86    typedef struct
87    {
88            uint32 flags;
89            uint32 functions;
90            uint32 decorations;
91            sint32 inputMode;
92            uint32 status;
93    }
94    PropMotifWmHints;
95    
96    typedef struct
97    {
98            uint32 red;
99            uint32 green;
100            uint32 blue;
101    }
102    PixelColour;
103    
 /* needed to keep track of the modifiers */  
 static unsigned int 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;  extern BOOL g_owncolmap;
119  static Colormap xcolmap;  static Colormap g_xcolmap;
120  static uint32 white;  static uint32 *g_colmap = NULL;
121  static uint32 *colmap;  
122    #define TRANSLATE(col)          ( g_server_bpp != 8 ? translate_colour(col) : g_owncolmap ? col : g_colmap[col] )
123  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )  #define SET_FOREGROUND(col)     XSetForeground(g_display, g_gc, TRANSLATE(col));
124  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(g_display, g_gc, TRANSLATE(col));
 #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  
125    
126  static int rop2_map[] = {  static int rop2_map[] = {
127          GXclear,                /* 0 */          GXclear,                /* 0 */
# Line 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  void xwin_release_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode);  static void
149  void xwin_press_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode);  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    static uint32
214    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;
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;                          break;
681          }          }
682            return out;
683    }
684    
685          return colour;  BOOL
686    get_key_state(unsigned int state, uint32 keysym)
687    {
688            int modifierpos, key, keysymMask = 0;
689            int offset;
690    
691            KeyCode keycode = XKeysymToKeycode(g_display, keysym);
692    
693            if (keycode == NoSymbol)
694                    return False;
695    
696            for (modifierpos = 0; modifierpos < 8; modifierpos++)
697            {
698                    offset = g_mod_map->max_keypermod * modifierpos;
699    
700                    for (key = 0; key < g_mod_map->max_keypermod; key++)
701                    {
702                            if (g_mod_map->modifiermap[offset + key] == keycode)
703                                    keysymMask |= 1 << modifierpos;
704                    }
705            }
706    
707            return (state & keysymMask) ? True : False;
708    }
709    
710    static void
711    calculate_shifts(uint32 mask, int *shift_r, int *shift_l)
712    {
713            *shift_l = ffs(mask) - 1;
714            mask >>= *shift_l;
715            *shift_r = 8 - ffs(mask & ~(mask >> 1));
716  }  }
717    
718  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                  attribs.override_redirect = False;                  /* 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                    /* 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            /* make sure width is a multiple of 4 */
863            g_width = (g_width + 3) & ~3;
864    
865            g_mod_map = XGetModifierMapping(g_display);
866    
867            xkeymap_init();
868    
869            if (g_enable_compose)
870                    g_IM = XOpenIM(g_display, NULL, NULL, NULL);
871    
872            xclip_init();
873    
874            DEBUG_RDP5(("server bpp %d client bpp %d depth %d\n", g_server_bpp, g_bpp, g_depth));
875    
876            return True;
877    }
878    
879    void
880    ui_deinit(void)
881    {
882            if (g_IM != NULL)
883                    XCloseIM(g_IM);
884    
885            if (g_null_cursor != NULL)
886                    ui_destroy_cursor(g_null_cursor);
887    
888            XFreeModifiermap(g_mod_map);
889    
890            if (g_ownbackstore)
891                    XFreePixmap(g_display, g_backstore);
892    
893            XFreeGC(g_display, g_gc);
894            XCloseDisplay(g_display);
895            g_display = NULL;
896    }
897    
898    BOOL
899    ui_create_window(void)
900    {
901            uint8 null_pointer_mask[1] = { 0x80 };
902            uint8 null_pointer_data[4] = { 0x00, 0x00, 0x00, 0x00 };
903            XSetWindowAttributes attribs;
904            XClassHint *classhints;
905            XSizeHints *sizehints;
906            int wndwidth, wndheight;
907            long input_mask, ic_input_mask;
908            XEvent xevent;
909    
910            wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;
911            wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;
912    
913          width = (width + 3) & ~3; /* make width a multiple of 32 bits */          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          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), 0, 0, wndwidth, wndheight,
920                              0, 0, width, height, 0, CopyFromParent,                                0, g_depth, InputOutput, g_visual,
921                              InputOutput, CopyFromParent,                                CWBackPixel | CWBackingStore | CWOverrideRedirect |
922                              CWBackingStore | CWBackPixel | CWOverrideRedirect,                                CWColormap | CWBorderPixel, &attribs);
                             &attribs);  
923    
924          XStoreName(display, wnd, title);          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_resize_window()
1013  {  {
1014          if( xkb != NULL )          XSizeHints *sizehints;
                 XkbFreeKeyboard(xkb, XkbAllControlsMask, True);  
1015    
1016          if (ownbackstore)          sizehints = XAllocSizeHints();
1017                  XFreePixmap(display, backstore);          if (sizehints)
1018            {
1019                    sizehints->flags = PMinSize | PMaxSize;
1020                    sizehints->min_width = sizehints->max_width = g_width;
1021                    sizehints->min_height = sizehints->max_height = g_height;
1022                    XSetWMNormalHints(g_display, g_wnd, sizehints);
1023                    XFree(sizehints);
1024            }
1025    
1026          XFreeGC(display, gc);          if (!(g_fullscreen || g_embed_wnd))
1027          XDestroyWindow(display, wnd);          {
1028          XCloseDisplay(display);                  XResizeWindow(g_display, g_wnd, g_width, g_height);
1029          display = NULL;          }
1030  }  }
1031    
1032  static void  void
1033  xwin_process_events()  ui_destroy_window(void)
1034  {  {
1035          XkbEvent xkbevent;          if (g_IC != NULL)
1036                            XDestroyIC(g_IC);
1037    
1038            XDestroyWindow(g_display, g_wnd);
1039    }
1040    
1041    void
1042    xwin_toggle_fullscreen(void)
1043    {
1044            Pixmap contents = 0;
1045    
1046            if (!g_ownbackstore)
1047            {
1048                    /* need to save contents of window */
1049                    contents = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
1050                    XCopyArea(g_display, g_wnd, contents, g_gc, 0, 0, g_width, g_height, 0, 0);
1051            }
1052    
1053            ui_destroy_window();
1054            g_fullscreen = !g_fullscreen;
1055            ui_create_window();
1056    
1057            XDefineCursor(g_display, g_wnd, g_current_cursor);
1058    
1059            if (!g_ownbackstore)
1060            {
1061                    XCopyArea(g_display, contents, g_wnd, g_gc, 0, 0, g_width, g_height, 0, 0);
1062                    XFreePixmap(g_display, contents);
1063            }
1064    }
1065    
1066    /* Process all events in Xlib queue
1067       Returns 0 after user quit, 1 otherwise */
1068    static int
1069    xwin_process_events(void)
1070    {
1071            XEvent xevent;
1072          KeySym keysym;          KeySym keysym;
         uint8 scancode;  
1073          uint16 button, flags;          uint16 button, flags;
1074          uint32 ev_time;          uint32 ev_time;
1075          uint32 tmpmods;          key_translation tr;
1076            char str[256];
1077            Status status;
1078    
1079          if (display == NULL)          while (XPending(g_display) > 0)
                 return;  
   
         while (XCheckMaskEvent(display, ~0, &xkbevent.core))  
1080          {          {
1081                  ev_time = time(NULL);                  XNextEvent(g_display, &xevent);
1082    
1083                    if ((g_IC != NULL) && (XFilterEvent(&xevent, None) == True))
1084                    {
1085                            DEBUG_KBD(("Filtering event\n"));
1086                            continue;
1087                    }
1088    
1089                  flags = 0;                  flags = 0;
1090    
1091                  switch (xkbevent.type)                  switch (xevent.type)
1092                  {                  {
1093                          case KeymapNotify:                          case ClientMessage:
1094                                  /* TODO:                                  /* the window manager told us to quit */
1095                                   * 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)
1096                                   * if not, we may get out of sync.                                      && ((Atom) xevent.xclient.data.l[0] == g_kill_atom))
1097                                   * xkbevent.core.xkeymap.key_vector                                          /* Quit */
1098                                   * char key_vector[32];                                          return 0;
                                  */  
1099                                  break;                                  break;
1100    
                         case KeyRelease:  
                                 flags = KBD_FLAG_DOWN | KBD_FLAG_UP;  
                                 /* fall through */  
   
1101                          case KeyPress:                          case KeyPress:
1102                                  if( XkbTranslateKeyCode(xkb, xkbevent.core.xkey.keycode, xkbevent.core.xkey.state, &tmpmods, &keysym) == False )                                  g_last_gesturetime = xevent.xkey.time;
1103                                    if (g_IC != NULL)
1104                                            /* Multi_key compatible version */
1105                                    {
1106                                            XmbLookupString(g_IC,
1107                                                            &xevent.xkey, str, sizeof(str), &keysym,
1108                                                            &status);
1109                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
1110                                            {
1111                                                    error("XmbLookupString failed with status 0x%x\n",
1112                                                          status);
1113                                                    break;
1114                                            }
1115                                    }
1116                                    else
1117                                    {
1118                                            /* Plain old XLookupString */
1119                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
1120                                            XLookupString((XKeyEvent *) & xevent,
1121                                                          str, sizeof(str), &keysym, NULL);
1122                                    }
1123    
1124                                    DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
1125                                               get_ksname(keysym)));
1126    
1127                                    ev_time = time(NULL);
1128                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
1129                                          break;                                          break;
                                 scancode = xkeymap_translate_key(keysym, xkbevent.core.xkey.keycode, &flags);  
1130    
1131                                  if (scancode == 0 )                                  tr = xkeymap_translate_key(keysym,
1132                                                               xevent.xkey.keycode, xevent.xkey.state);
1133    
1134                                    if (tr.scancode == 0)
1135                                          break;                                          break;
1136    
1137                                  /* keep track of the modifiers -- needed for stickykeys... */                                  save_remote_modifiers(tr.scancode);
1138                                  if( xkbevent.type == KeyPress )                                  ensure_remote_modifiers(ev_time, tr);
1139                                          xwin_press_modifiers( &xkbevent.core.xkey, ev_time, scancode );                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
1140                                    restore_remote_modifiers(ev_time, tr.scancode);
1141    
1142                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, flags, scancode, 0);                                  break;
1143    
1144                            case KeyRelease:
1145                                    g_last_gesturetime = xevent.xkey.time;
1146                                    XLookupString((XKeyEvent *) & xevent, str,
1147                                                  sizeof(str), &keysym, NULL);
1148    
1149                                  if( xkbevent.type == KeyRelease )                                  DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
1150                                          xwin_release_modifiers( &xkbevent.core.xkey, ev_time, scancode );                                             get_ksname(keysym)));
1151    
1152                                    ev_time = time(NULL);
1153                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
1154                                            break;
1155    
1156                                    tr = xkeymap_translate_key(keysym,
1157                                                               xevent.xkey.keycode, xevent.xkey.state);
1158    
1159                                    if (tr.scancode == 0)
1160                                            break;
1161    
1162                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
1163                                  break;                                  break;
1164    
1165                          case ButtonPress:                          case ButtonPress:
# Line 444  xwin_process_events() Line 1167  xwin_process_events()
1167                                  /* fall through */                                  /* fall through */
1168    
1169                          case ButtonRelease:                          case ButtonRelease:
1170                                  button = xkeymap_translate_button(xkbevent.core.xbutton.button);                                  g_last_gesturetime = xevent.xbutton.time;
1171                                    button = xkeymap_translate_button(xevent.xbutton.button);
1172                                  if (button == 0)                                  if (button == 0)
1173                                          break;                                          break;
1174    
1175                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  /* If win_button_size is nonzero, enable single app mode */
1176                                                 flags | button,                                  if (xevent.xbutton.y < g_win_button_size)
1177                                                 xkbevent.core.xbutton.x,                                  {
1178                                                 xkbevent.core.xbutton.y);                                          /* Stop moving window when button is released, regardless of cursor position */
1179                                            if (g_moving_wnd && (xevent.type == ButtonRelease))
1180                                                    g_moving_wnd = False;
1181    
1182                                            /*  Check from right to left: */
1183    
1184                                            if (xevent.xbutton.x >= g_width - g_win_button_size)
1185                                            {
1186                                                    /* The close button, continue */
1187                                                    ;
1188                                            }
1189                                            else if (xevent.xbutton.x >=
1190                                                     g_width - g_win_button_size * 2)
1191                                            {
1192                                                    /* The maximize/restore button. Do not send to
1193                                                       server.  It might be a good idea to change the
1194                                                       cursor or give some other visible indication
1195                                                       that rdesktop inhibited this click */
1196                                                    break;
1197                                            }
1198                                            else if (xevent.xbutton.x >=
1199                                                     g_width - g_win_button_size * 3)
1200                                            {
1201                                                    /* The minimize button. Iconify window. */
1202                                                    XIconifyWindow(g_display, g_wnd,
1203                                                                   DefaultScreen(g_display));
1204                                                    break;
1205                                            }
1206                                            else if (xevent.xbutton.x <= g_win_button_size)
1207                                            {
1208                                                    /* The system menu. Ignore. */
1209                                                    break;
1210                                            }
1211                                            else
1212                                            {
1213                                                    /* The title bar. */
1214                                                    if ((xevent.type == ButtonPress) && !g_fullscreen
1215                                                        && g_hide_decorations)
1216                                                    {
1217                                                            g_moving_wnd = True;
1218                                                            g_move_x_offset = xevent.xbutton.x;
1219                                                            g_move_y_offset = xevent.xbutton.y;
1220                                                    }
1221                                                    break;
1222    
1223                                            }
1224                                    }
1225    
1226                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1227                                                   flags | button, xevent.xbutton.x, xevent.xbutton.y);
1228                                  break;                                  break;
1229    
1230                          case MotionNotify:                          case MotionNotify:
1231                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  if (g_moving_wnd)
1232                                                 MOUSE_FLAG_MOVE,                                  {
1233                                                 xkbevent.core.xmotion.x,                                          XMoveWindow(g_display, g_wnd,
1234                                                 xkbevent.core.xmotion.y);                                                      xevent.xmotion.x_root - g_move_x_offset,
1235                                                        xevent.xmotion.y_root - g_move_y_offset);
1236                                            break;
1237                                    }
1238    
1239                                    if (g_fullscreen && !g_focused)
1240                                            XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1241                                                           CurrentTime);
1242                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1243                                                   MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
1244                                    break;
1245    
1246                            case FocusIn:
1247                                    if (xevent.xfocus.mode == NotifyGrab)
1248                                            break;
1249                                    g_focused = True;
1250                                    reset_modifier_keys();
1251                                    if (g_grab_keyboard && g_mouse_in_wnd)
1252                                            XGrabKeyboard(g_display, g_wnd, True,
1253                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
1254                                    break;
1255    
1256                            case FocusOut:
1257                                    if (xevent.xfocus.mode == NotifyUngrab)
1258                                            break;
1259                                    g_focused = False;
1260                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
1261                                            XUngrabKeyboard(g_display, CurrentTime);
1262                                  break;                                  break;
1263    
1264                          case EnterNotify:                          case EnterNotify:
1265                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,                                  /* we only register for this event when in fullscreen mode */
1266                                                GrabModeAsync, CurrentTime);                                  /* or grab_keyboard */
1267                                    g_mouse_in_wnd = True;
1268                                    if (g_fullscreen)
1269                                    {
1270                                            XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1271                                                           CurrentTime);
1272                                            break;
1273                                    }
1274                                    if (g_focused)
1275                                            XGrabKeyboard(g_display, g_wnd, True,
1276                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
1277                                  break;                                  break;
1278    
1279                          case LeaveNotify:                          case LeaveNotify:
1280                                  XUngrabKeyboard(display, CurrentTime);                                  /* we only register for this event when grab_keyboard */
1281                                    g_mouse_in_wnd = False;
1282                                    XUngrabKeyboard(g_display, CurrentTime);
1283                                  break;                                  break;
1284    
1285                          case Expose:                          case Expose:
1286                                  XCopyArea(display, backstore, wnd, gc,                                  XCopyArea(g_display, g_backstore, g_wnd, g_gc,
1287                                            xkbevent.core.xexpose.x, xkbevent.core.xexpose.y,                                            xevent.xexpose.x, xevent.xexpose.y,
1288                                            xkbevent.core.xexpose.width, xkbevent.core.xexpose.height,                                            xevent.xexpose.width,
1289                                            xkbevent.core.xexpose.x, xkbevent.core.xexpose.y);                                            xevent.xexpose.height,
1290                                              xevent.xexpose.x, xevent.xexpose.y);
1291                                  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;  
         }  
1292    
1293          if( !(ShiftMask & ev->state) && (key_down_state & DShift1Mask))                          case MappingNotify:
1294          {                                  /* Refresh keyboard mapping if it has changed. This is important for
1295                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a, 0);                                     Xvnc, since it allocates keycodes dynamically */
1296                  key_down_state &= ~DShift1Mask;                                  if (xevent.xmapping.request == MappingKeyboard
1297                                        || xevent.xmapping.request == MappingModifier)
1298          }                                          XRefreshKeyboardMapping(&xevent.xmapping);
1299    
1300          if( !(ControlMask & ev->state) && (key_down_state & DControl1Mask))                                  if (xevent.xmapping.request == MappingModifier)
1301          {                                  {
1302                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d, 0);                                          XFreeModifiermap(g_mod_map);
1303                  key_down_state &= ~DControl1Mask;                                          g_mod_map = XGetModifierMapping(g_display);
1304                                    }
1305          }                                  break;
           
         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;  
   
         }  
   
         if( (Mod2Mask & ev->state) && !(key_down_state & DMod2Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0xb8, 0);  
                 key_down_state |= DMod2Mask;  
1306    
1307                                    /* clipboard stuff */
1308                            case SelectionNotify:
1309                                    xclip_handle_SelectionNotify(&xevent.xselection);
1310                                    break;
1311                            case SelectionRequest:
1312                                    xclip_handle_SelectionRequest(&xevent.xselectionrequest);
1313                                    break;
1314                            case SelectionClear:
1315                                    xclip_handle_SelectionClear();
1316                                    break;
1317                            case PropertyNotify:
1318                                    xclip_handle_PropertyNotify(&xevent.xproperty);
1319                                    break;
1320                    }
1321          }          }
1322            /* Keep going */
1323            return 1;
1324  }  }
1325    
1326  void  /* Returns 0 after user quit, 1 otherwise */
1327    int
1328  ui_select(int rdp_socket)  ui_select(int rdp_socket)
1329  {  {
1330          int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;          int n;
1331          fd_set rfds;          fd_set rfds, wfds;
1332            struct timeval tv;
1333          XFlush(display);          BOOL s_timeout = False;
   
         FD_ZERO(&rfds);  
1334    
1335          while (True)          while (True)
1336          {          {
1337                    n = (rdp_socket > g_x_socket) ? rdp_socket : g_x_socket;
1338                    /* Process any events already waiting */
1339                    if (!xwin_process_events())
1340                            /* User quit */
1341                            return 0;
1342    
1343                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
1344                    FD_ZERO(&wfds);
1345                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
1346                  FD_SET(x_socket, &rfds);                  FD_SET(g_x_socket, &rfds);
1347    
1348                  switch (select(n, &rfds, NULL, NULL, NULL))  #ifdef WITH_RDPSND
1349                    /* FIXME: there should be an API for registering fds */
1350                    if (g_dsp_busy)
1351                    {
1352                            FD_SET(g_dsp_fd, &wfds);
1353                            n = (g_dsp_fd > n) ? g_dsp_fd : n;
1354                    }
1355    #endif
1356                    /* default timeout */
1357                    tv.tv_sec = 60;
1358                    tv.tv_usec = 0;
1359    
1360                    /* add redirection handles */
1361                    rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
1362    
1363                    n++;
1364    
1365                    switch (select(n, &rfds, &wfds, NULL, &tv))
1366                  {                  {
1367                          case -1:                          case -1:
1368                                  error("select: %s\n", strerror(errno));                                  error("select: %s\n", strerror(errno));
1369    
1370                          case 0:                          case 0:
1371                                    /* TODO: if tv.tv_sec just times out
1372                                     * we will segfault.
1373                                     * FIXME:
1374                                     */
1375                                    //s_timeout = True;
1376                                    //rdpdr_check_fds(&rfds, &wfds, (BOOL) True);
1377                                  continue;                                  continue;
1378                  }                  }
1379    
1380                  if (FD_ISSET(x_socket, &rfds))                  rdpdr_check_fds(&rfds, &wfds, (BOOL) False);
                         xwin_process_events();  
1381    
1382                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
1383                          return;                          return 1;
1384    
1385    #ifdef WITH_RDPSND
1386                    if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))
1387                            wave_out_play();
1388    #endif
1389          }          }
1390  }  }
1391    
1392  void  void
1393  ui_move_pointer(int x, int y)  ui_move_pointer(int x, int y)
1394  {  {
1395          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);          XWarpPointer(g_display, g_wnd, g_wnd, 0, 0, 0, 0, x, y);
1396  }  }
1397    
1398  HBITMAP  HBITMAP
1399  ui_create_bitmap(int width, int height, uint8 *data)  ui_create_bitmap(int width, int height, uint8 * data)
1400  {  {
1401          XImage *image;          XImage *image;
1402          Pixmap bitmap;          Pixmap bitmap;
1403          uint8 *tdata;          uint8 *tdata;
1404            int bitmap_pad;
1405    
1406            if (g_server_bpp == 8)
1407            {
1408                    bitmap_pad = 8;
1409            }
1410            else
1411            {
1412                    bitmap_pad = g_bpp;
1413    
1414                    if (g_bpp == 24)
1415                            bitmap_pad = 32;
1416            }
1417    
1418          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (g_owncolmap ? data : translate_image(width, height, data));
1419          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, g_depth);
1420          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1421                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, bitmap_pad, 0);
1422    
1423          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(g_display, bitmap, g_gc, image, 0, 0, 0, 0, width, height);
1424    
1425          XFree(image);          XFree(image);
1426          if (!owncolmap)          if (tdata != data)
1427                  xfree(tdata);                  xfree(tdata);
1428          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
1429  }  }
1430    
1431  void  void
1432  ui_paint_bitmap(int x, int y, int cx, int cy,  ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 * data)
                 int width, int height, uint8 *data)  
1433  {  {
1434          XImage *image;          XImage *image;
1435          uint8 *tdata;          uint8 *tdata;
1436            int bitmap_pad;
1437    
1438            if (g_server_bpp == 8)
1439            {
1440                    bitmap_pad = 8;
1441            }
1442            else
1443            {
1444                    bitmap_pad = g_bpp;
1445    
1446                    if (g_bpp == 24)
1447                            bitmap_pad = 32;
1448            }
1449    
1450          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (g_owncolmap ? data : translate_image(width, height, data));
1451          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1452                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, bitmap_pad, 0);
1453    
1454          if (ownbackstore)          if (g_ownbackstore)
1455          {          {
1456                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);
1457                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
1458          }          }
1459          else          else
1460          {          {
1461                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);
1462          }          }
1463    
1464          XFree(image);          XFree(image);
1465          if (!owncolmap)          if (tdata != data)
1466                  xfree(tdata);                  xfree(tdata);
1467  }  }
1468    
1469  void  void
1470  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
1471  {  {
1472          XFreePixmap(display, (Pixmap)bmp);          XFreePixmap(g_display, (Pixmap) bmp);
1473  }  }
1474    
1475  HGLYPH  HGLYPH
1476  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 * data)
1477  {  {
1478          XImage *image;          XImage *image;
1479          Pixmap bitmap;          Pixmap bitmap;
# Line 689  ui_create_glyph(int width, int height, u Line 1482  ui_create_glyph(int width, int height, u
1482    
1483          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1484    
1485          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);
1486          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(g_display, bitmap, 0, NULL);
1487    
1488          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,
1489                               data, width, height, 8, scanline);                               width, height, 8, scanline);
1490          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
1491          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1492          XInitImage(image);          XInitImage(image);
1493    
1494          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(g_display, bitmap, gc, image, 0, 0, 0, 0, width, height);
1495    
1496          XFree(image);          XFree(image);
1497          XFreeGC(display, gc);          XFreeGC(g_display, gc);
1498          return (HGLYPH)bitmap;          return (HGLYPH) bitmap;
1499  }  }
1500    
1501  void  void
1502  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
1503  {  {
1504          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(g_display, (Pixmap) glyph);
1505  }  }
1506    
1507  HCURSOR  HCURSOR
1508  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
1509                   int height, uint8 *andmask, uint8 *xormask)                   uint8 * andmask, uint8 * xormask)
1510  {  {
1511          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
1512          XColor bg, fg;          XColor bg, fg;
# Line 727  ui_create_cursor(unsigned int x, unsigne Line 1520  ui_create_cursor(unsigned int x, unsigne
1520          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1521          offset = scanline * height;          offset = scanline * height;
1522    
1523          cursor = xmalloc(offset);          cursor = (uint8 *) xmalloc(offset);
1524          memset(cursor, 0, offset);          memset(cursor, 0, offset);
1525    
1526          mask = xmalloc(offset);          mask = (uint8 *) xmalloc(offset);
1527          memset(mask, 0, offset);          memset(mask, 0, offset);
1528    
1529          /* approximate AND and XOR masks with a monochrome X pointer */          /* approximate AND and XOR masks with a monochrome X pointer */
# Line 770  ui_create_cursor(unsigned int x, unsigne Line 1563  ui_create_cursor(unsigned int x, unsigne
1563    
1564          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
1565          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
1566            
1567          xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,          xcursor =
1568                                  (Pixmap)maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(g_display, (Pixmap) cursorglyph,
1569                                        (Pixmap) maskglyph, &fg, &bg, x, y);
1570    
1571          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
1572          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
1573          xfree(mask);          xfree(mask);
1574          xfree(cursor);          xfree(cursor);
1575          return (HCURSOR)xcursor;          return (HCURSOR) xcursor;
1576  }  }
1577    
1578  void  void
1579  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
1580  {  {
1581          XDefineCursor(display, wnd, (Cursor)cursor);          g_current_cursor = (Cursor) cursor;
1582            XDefineCursor(g_display, g_wnd, g_current_cursor);
1583  }  }
1584    
1585  void  void
1586  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
1587  {  {
1588          XFreeCursor(display, (Cursor)cursor);          XFreeCursor(g_display, (Cursor) cursor);
1589    }
1590    
1591    void
1592    ui_set_null_cursor(void)
1593    {
1594            ui_set_cursor(g_null_cursor);
1595  }  }
1596    
1597  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 799  ui_destroy_cursor(HCURSOR cursor) Line 1600  ui_destroy_cursor(HCURSOR cursor)
1600                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
1601                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
1602    
1603    
1604  HCOLOURMAP  HCOLOURMAP
1605  ui_create_colourmap(COLOURMAP *colours)  ui_create_colourmap(COLOURMAP * colours)
1606  {  {
1607          COLOURENTRY *entry;          COLOURENTRY *entry;
1608          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
1609            if (!g_owncolmap)
         if (owncolmap)  
1610          {          {
1611                  XColor *xcolours, *xentry;                  uint32 *map = (uint32 *) xmalloc(sizeof(*g_colmap) * ncolours);
1612                  Colormap map;                  XColor xentry;
1613                    XColor xc_cache[256];
1614                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  uint32 colour;
1615                    int colLookup = 256;
1616                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
1617                  {                  {
1618                          entry = &colours->colours[i];                          entry = &colours->colours[i];
1619                          xentry = &xcolours[i];                          MAKE_XCOLOR(&xentry, entry);
                         xentry->pixel = i;  
                         MAKE_XCOLOR(xentry, entry);  
                 }  
1620    
1621                  map = XCreateColormap(display, wnd, visual, AllocAll);                          if (XAllocColor(g_display, g_xcolmap, &xentry) == 0)
1622                  XStoreColors(display, map, xcolours, ncolours);                          {
1623                                    /* Allocation failed, find closest match. */
1624                                    int j = 256;
1625                                    int nMinDist = 3 * 256 * 256;
1626                                    long nDist = nMinDist;
1627    
1628                  xfree(xcolours);                                  /* only get the colors once */
1629                  return (HCOLOURMAP)map;                                  while (colLookup--)
1630                                    {
1631                                            xc_cache[colLookup].pixel = colLookup;
1632                                            xc_cache[colLookup].red = xc_cache[colLookup].green =
1633                                                    xc_cache[colLookup].blue = 0;
1634                                            xc_cache[colLookup].flags = 0;
1635                                            XQueryColor(g_display,
1636                                                        DefaultColormap(g_display,
1637                                                                        DefaultScreen(g_display)),
1638                                                        &xc_cache[colLookup]);
1639                                    }
1640                                    colLookup = 0;
1641    
1642                                    /* approximate the pixel */
1643                                    while (j--)
1644                                    {
1645                                            if (xc_cache[j].flags)
1646                                            {
1647                                                    nDist = ((long) (xc_cache[j].red >> 8) -
1648                                                             (long) (xentry.red >> 8)) *
1649                                                            ((long) (xc_cache[j].red >> 8) -
1650                                                             (long) (xentry.red >> 8)) +
1651                                                            ((long) (xc_cache[j].green >> 8) -
1652                                                             (long) (xentry.green >> 8)) *
1653                                                            ((long) (xc_cache[j].green >> 8) -
1654                                                             (long) (xentry.green >> 8)) +
1655                                                            ((long) (xc_cache[j].blue >> 8) -
1656                                                             (long) (xentry.blue >> 8)) *
1657                                                            ((long) (xc_cache[j].blue >> 8) -
1658                                                             (long) (xentry.blue >> 8));
1659                                            }
1660                                            if (nDist < nMinDist)
1661                                            {
1662                                                    nMinDist = nDist;
1663                                                    xentry.pixel = j;
1664                                            }
1665                                    }
1666                            }
1667                            colour = xentry.pixel;
1668    
1669                            /* update our cache */
1670                            if (xentry.pixel < 256)
1671                            {
1672                                    xc_cache[xentry.pixel].red = xentry.red;
1673                                    xc_cache[xentry.pixel].green = xentry.green;
1674                                    xc_cache[xentry.pixel].blue = xentry.blue;
1675    
1676                            }
1677    
1678                            map[i] = colour;
1679                    }
1680                    return map;
1681          }          }
1682          else          else
1683          {          {
1684                  uint32 *map = xmalloc(sizeof(*colmap) * ncolours);                  XColor *xcolours, *xentry;
1685                  XColor xentry;                  Colormap map;
                 uint32 colour;  
1686    
1687                    xcolours = (XColor *) xmalloc(sizeof(XColor) * ncolours);
1688                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
1689                  {                  {
1690                          entry = &colours->colours[i];                          entry = &colours->colours[i];
1691                          MAKE_XCOLOR(&xentry, entry);                          xentry = &xcolours[i];
1692                            xentry->pixel = i;
1693                          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);  
1694                  }                  }
1695    
1696                  return map;                  map = XCreateColormap(g_display, g_wnd, g_visual, AllocAll);
1697                    XStoreColors(g_display, map, xcolours, ncolours);
1698    
1699                    xfree(xcolours);
1700                    return (HCOLOURMAP) map;
1701          }          }
1702  }  }
1703    
1704  void  void
1705  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
1706  {  {
1707          if (owncolmap)          if (!g_owncolmap)
                 XFreeColormap(display, (Colormap)map);  
         else  
1708                  xfree(map);                  xfree(map);
1709            else
1710                    XFreeColormap(g_display, (Colormap) map);
1711  }  }
1712    
1713  void  void
1714  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
1715  {  {
1716          if (owncolmap)          if (!g_owncolmap)
1717                  XSetWindowColormap(display, wnd, (Colormap)map);          {
1718                    if (g_colmap)
1719                            xfree(g_colmap);
1720    
1721                    g_colmap = (uint32 *) map;
1722            }
1723          else          else
1724                  colmap = map;                  XSetWindowColormap(g_display, g_wnd, (Colormap) map);
1725  }  }
1726    
1727  void  void
# Line 876  ui_set_clip(int x, int y, int cx, int cy Line 1733  ui_set_clip(int x, int y, int cx, int cy
1733          rect.y = y;          rect.y = y;
1734          rect.width = cx;          rect.width = cx;
1735          rect.height = cy;          rect.height = cy;
1736          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
1737  }  }
1738    
1739  void  void
1740  ui_reset_clip()  ui_reset_clip(void)
1741  {  {
1742          XRectangle rect;          XRectangle rect;
1743    
1744          rect.x = 0;          rect.x = 0;
1745          rect.y = 0;          rect.y = 0;
1746          rect.width = width;          rect.width = g_width;
1747          rect.height = height;          rect.height = g_height;
1748          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
1749  }  }
1750    
1751  void  void
1752  ui_bell()  ui_bell(void)
1753  {  {
1754          XBell(display, 0);          XBell(g_display, 0);
1755  }  }
1756    
1757  void  void
# Line 906  ui_destblt(uint8 opcode, Line 1763  ui_destblt(uint8 opcode,
1763          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1764  }  }
1765    
1766    static uint8 hatch_patterns[] = {
1767            0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */
1768            0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */
1769            0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */
1770            0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */
1771            0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */
1772            0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81  /* 5 - bsDiagCross */
1773    };
1774    
1775  void  void
1776  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
1777            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1778            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1779  {  {
1780          Pixmap fill;          Pixmap fill;
1781            uint8 i, ipattern[8];
1782    
1783          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1784    
# Line 922  ui_patblt(uint8 opcode, Line 1789  ui_patblt(uint8 opcode,
1789                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1790                          break;                          break;
1791    
1792                    case 2: /* Hatch */
1793                            fill = (Pixmap) ui_create_glyph(8, 8,
1794                                                            hatch_patterns + brush->pattern[0] * 8);
1795                            SET_FOREGROUND(fgcolour);
1796                            SET_BACKGROUND(bgcolour);
1797                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
1798                            XSetStipple(g_display, g_gc, fill);
1799                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
1800                            FILL_RECTANGLE(x, y, cx, cy);
1801                            XSetFillStyle(g_display, g_gc, FillSolid);
1802                            XSetTSOrigin(g_display, g_gc, 0, 0);
1803                            ui_destroy_glyph((HGLYPH) fill);
1804                            break;
1805    
1806                  case 3: /* Pattern */                  case 3: /* Pattern */
1807                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);                          for (i = 0; i != 8; i++)
1808                                    ipattern[7 - i] = brush->pattern[i];
1809                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
1810    
1811                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
1812                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
1813                          XSetFillStyle(display, gc, FillOpaqueStippled);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
1814                          XSetStipple(display, gc, fill);                          XSetStipple(g_display, g_gc, fill);
1815                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
1816    
1817                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1818    
1819                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
1820                          ui_destroy_glyph((HGLYPH)fill);                          XSetTSOrigin(g_display, g_gc, 0, 0);
1821                            ui_destroy_glyph((HGLYPH) fill);
1822                          break;                          break;
1823    
1824                  default:                  default:
# Line 950  ui_screenblt(uint8 opcode, Line 1834  ui_screenblt(uint8 opcode,
1834               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
1835  {  {
1836          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1837          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          if (g_ownbackstore)
1838          if (ownbackstore)          {
1839                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
1840                            cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);
1841            }
1842            else
1843            {
1844                    XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
1845            }
1846          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1847  }  }
1848    
# Line 963  ui_memblt(uint8 opcode, Line 1852  ui_memblt(uint8 opcode,
1852            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1853  {  {
1854          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1855          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(g_display, (Pixmap) src, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
1856          if (ownbackstore)          if (g_ownbackstore)
1857                  XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,                  XCopyArea(g_display, (Pixmap) src, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1858          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1859  }  }
1860    
# Line 974  void Line 1862  void
1862  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
1863            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1864            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ HBITMAP src, int srcx, int srcy,
1865            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1866  {  {
1867          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
1868             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 1871  ui_triblt(uint8 opcode,
1871          {          {
1872                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1873                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1874                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1875                          break;                          break;
1876    
1877                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1878                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1879                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1880                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1881                          break;                          break;
1882    
1883                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1884                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1885                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1886                          break;                          break;
1887    
1888                  default:                  default:
# Line 1010  ui_triblt(uint8 opcode, Line 1894  ui_triblt(uint8 opcode,
1894  void  void
1895  ui_line(uint8 opcode,  ui_line(uint8 opcode,
1896          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
1897          /* pen */ PEN *pen)          /* pen */ PEN * pen)
1898  {  {
1899          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1900          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
1901          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(g_display, g_wnd, g_gc, startx, starty, endx, endy);
1902          if (ownbackstore)          if (g_ownbackstore)
1903                  XDrawLine(display, backstore, gc, startx, starty, endx, endy);                  XDrawLine(g_display, g_backstore, g_gc, startx, starty, endx, endy);
1904          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1905  }  }
1906    
# Line 1029  ui_rect( Line 1913  ui_rect(
1913          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
1914  }  }
1915    
1916    /* warning, this function only draws on wnd or backstore, not both */
1917  void  void
1918  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1919                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1920                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1921                int fgcolour)                int bgcolour, int fgcolour)
1922  {  {
1923          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1924          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1925    
1926          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(g_display, g_gc,
1927                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1928          XSetStipple(display, gc, (Pixmap)glyph);          XSetStipple(g_display, g_gc, (Pixmap) glyph);
1929          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(g_display, g_gc, x, y);
1930    
1931          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
1932    
1933          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(g_display, g_gc, FillSolid);
1934  }  }
1935    
1936  #define DO_GLYPH(ttext,idx) \  #define DO_GLYPH(ttext,idx) \
1937  {\  {\
1938    glyph = cache_get_font (font, ttext[idx]);\    glyph = cache_get_font (font, ttext[idx]);\
1939    if (!(flags & TEXT2_IMPLICIT_X))\    if (!(flags & TEXT2_IMPLICIT_X))\
1940      {\
1941        xyoffset = ttext[++idx];\
1942        if ((xyoffset & 0x80))\
1943      {\      {\
1944        xyoffset = ttext[++idx];\        if (flags & TEXT2_VERTICAL)\
1945        if ((xyoffset & 0x80))\          y += ttext[idx+1] | (ttext[idx+2] << 8);\
         {\  
           if (flags & TEXT2_VERTICAL) \  
             y += ttext[++idx] | (ttext[++idx] << 8);\  
           else\  
             x += ttext[++idx] | (ttext[++idx] << 8);\  
         }\  
1946        else\        else\
1947          {\          x += ttext[idx+1] | (ttext[idx+2] << 8);\
1948            if (flags & TEXT2_VERTICAL) \        idx += 2;\
             y += xyoffset;\  
           else\  
             x += xyoffset;\  
         }\  
1949      }\      }\
1950    if (glyph != NULL)\      else\
1951      {\      {\
1952        ui_draw_glyph (mixmode, x + (short) glyph->offset,\        if (flags & TEXT2_VERTICAL)\
1953                       y + (short) glyph->baseline,\          y += xyoffset;\
1954                       glyph->width, glyph->height,\        else\
1955                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\          x += xyoffset;\
       if (flags & TEXT2_IMPLICIT_X)\  
         x += glyph->width;\  
1956      }\      }\
1957      }\
1958      if (glyph != NULL)\
1959      {\
1960        x1 = x + glyph->offset;\
1961        y1 = y + glyph->baseline;\
1962        XSetStipple(g_display, g_gc, (Pixmap) glyph->pixmap);\
1963        XSetTSOrigin(g_display, g_gc, x1, y1);\
1964        FILL_RECTANGLE_BACKSTORE(x1, y1, glyph->width, glyph->height);\
1965        if (flags & TEXT2_IMPLICIT_X)\
1966          x += glyph->width;\
1967      }\
1968  }  }
1969    
1970  void  void
1971  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
1972               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1973               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1974               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1975  {  {
1976          FONTGLYPH *glyph;          FONTGLYPH *glyph;
1977          int i, j, xyoffset;          int i, j, xyoffset, x1, y1;
1978          DATABLOB *entry;          DATABLOB *entry;
1979    
1980          SET_FOREGROUND(bgcolour);          SET_FOREGROUND(bgcolour);
1981    
1982            /* Sometimes, the boxcx value is something really large, like
1983               32691. This makes XCopyArea fail with Xvnc. The code below
1984               is a quick fix. */
1985            if (boxx + boxcx > g_width)
1986                    boxcx = g_width - boxx;
1987    
1988          if (boxcx > 1)          if (boxcx > 1)
1989          {          {
1990                  FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
1991          }          }
1992          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
1993          {          {
1994                  FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
1995          }          }
1996    
1997            SET_FOREGROUND(fgcolour);
1998            SET_BACKGROUND(bgcolour);
1999            XSetFillStyle(g_display, g_gc, FillStippled);
2000    
2001          /* Paint text, character by character */          /* Paint text, character by character */
2002          for (i = 0; i < length;) {          for (i = 0; i < length;)
2003                  switch (text[i]) {          {
2004                  case 0xff:                  switch (text[i])
2005                          if (i + 2 < length)                  {
2006                                  cache_put_text(text[i + 1], text, text[i + 2]);                          case 0xff:
2007                          else {                                  if (i + 2 < length)
2008                                  error("this shouldn't be happening\n");                                          cache_put_text(text[i + 1], text, text[i + 2]);
2009                                    else
2010                                    {
2011                                            error("this shouldn't be happening\n");
2012                                            exit(1);
2013                                    }
2014                                    /* this will move pointer from start to first character after FF command */
2015                                    length -= i + 3;
2016                                    text = &(text[i + 3]);
2017                                    i = 0;
2018                                  break;                                  break;
                         }  
                         /* this will move pointer from start to first character after FF command */  
                         length -= i + 3;  
                         text = &(text[i + 3]);  
                         i = 0;  
                         break;  
2019    
2020                  case 0xfe:                          case 0xfe:
2021                          entry = cache_get_text(text[i + 1]);                                  entry = cache_get_text(text[i + 1]);
2022                          if (entry != NULL) {                                  if (entry != NULL)
2023                                  if ((((uint8 *) (entry->data))[1] == 0)                                  {
2024                                      && (!(flags & TEXT2_IMPLICIT_X))) {                                          if ((((uint8 *) (entry->data))[1] ==
2025                                          if (flags & TEXT2_VERTICAL)                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
2026                                                  y += text[i + 2];                                          {
2027                                          else                                                  if (flags & TEXT2_VERTICAL)
2028                                                  x += text[i + 2];                                                          y += text[i + 2];
2029                                                    else
2030                                                            x += text[i + 2];
2031                                            }
2032                                            for (j = 0; j < entry->size; j++)
2033                                                    DO_GLYPH(((uint8 *) (entry->data)), j);
2034                                  }                                  }
2035                                  if (i + 2 < length)                                  if (i + 2 < length)
2036                                          i += 3;                                          i += 3;
2037                                  else                                  else
2038                                          i += 2;                                          i += 2;
2039                                  length -= i;                                  length -= i;
2040                                  /* this will move pointer from start to first character after FE command */                                  /* this will move pointer from start to first character after FE command */
2041                                  text = &(text[i]);                                  text = &(text[i]);
2042                                  i = 0;                                  i = 0;
2043                                  for (j = 0; j < entry->size; j++)                                  break;
                                         DO_GLYPH(((uint8 *) (entry->data)), j);  
                         }  
                         break;  
2044    
2045                  default:                          default:
2046                          DO_GLYPH(text, i);                                  DO_GLYPH(text, i);
2047                          i++;                                  i++;
2048                          break;                                  break;
2049                  }                  }
2050          }          }
2051    
2052            XSetFillStyle(g_display, g_gc, FillSolid);
2053    
2054            if (g_ownbackstore)
2055            {
2056                    if (boxcx > 1)
2057                            XCopyArea(g_display, g_backstore, g_wnd, g_gc, boxx,
2058                                      boxy, boxcx, boxcy, boxx, boxy);
2059                    else
2060                            XCopyArea(g_display, g_backstore, g_wnd, g_gc, clipx,
2061                                      clipy, clipcx, clipcy, clipx, clipy);
2062            }
2063  }  }
2064    
2065  void  void
# Line 1156  ui_desktop_save(uint32 offset, int x, in Line 2068  ui_desktop_save(uint32 offset, int x, in
2068          Pixmap pix;          Pixmap pix;
2069          XImage *image;          XImage *image;
2070    
2071          if (ownbackstore)          if (g_ownbackstore)
2072          {          {
2073                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(g_display, g_backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
2074          }          }
2075          else          else
2076          {          {
2077                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(g_display, g_wnd, cx, cy, g_depth);
2078                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(g_display, g_wnd, pix, g_gc, x, y, cx, cy, 0, 0);
2079                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(g_display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
2080                                    ZPixmap);                  XFreePixmap(g_display, pix);
                 XFreePixmap(display, pix);  
2081          }          }
2082    
2083          offset *= bpp/8;          offset *= g_bpp / 8;
2084          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line, g_bpp / 8, (uint8 *) image->data);
                           bpp/8, (uint8 *)image->data);  
2085    
2086          XDestroyImage(image);          XDestroyImage(image);
2087  }  }
# Line 1183  ui_desktop_restore(uint32 offset, int x, Line 2092  ui_desktop_restore(uint32 offset, int x,
2092          XImage *image;          XImage *image;
2093          uint8 *data;          uint8 *data;
2094    
2095          offset *= bpp/8;          offset *= g_bpp / 8;
2096          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, g_bpp / 8);
2097          if (data == NULL)          if (data == NULL)
2098                  return;                  return;
2099    
2100          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
2101                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(g_display), cx * g_bpp / 8);
                              cx * bpp/8);  
2102    
2103          if (ownbackstore)          if (g_ownbackstore)
2104          {          {
2105                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);
2106                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
2107          }          }
2108          else          else
2109          {          {
2110                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);
2111          }          }
2112    
2113          XFree(image);          XFree(image);

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

  ViewVC Help
Powered by ViewVC 1.1.26