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

Diff of /sourceforge.net/branches/seamlessrdp-branch/rdesktop/xwin.c

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

revision 373 by jsorg71, Thu May 15 14:26:15 2003 UTC revision 991 by astrand, Fri Aug 26 07:01:02 2005 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-2002     Copyright (C) Matthew Chapman 1999-2005
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 <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 int width;  extern int g_width;
32  extern int height;  extern int g_height;
33  extern BOOL sendmotion;  extern int g_xpos;
34  extern BOOL fullscreen;  extern int g_ypos;
35  extern BOOL grab_keyboard;  extern int g_pos;
36  extern BOOL hide_decorations;  extern BOOL g_sendmotion;
37  extern char title[];  extern BOOL g_fullscreen;
38  extern int server_bpp;  extern BOOL g_grab_keyboard;
39  extern int win_button_size;  extern BOOL g_hide_decorations;
40  BOOL enable_compose = False;  extern char g_title[];
41  BOOL focused;  extern int g_server_bpp;
42  BOOL mouse_in_wnd;  extern int g_win_button_size;
43    
44  Display *display;  Display *g_display;
45  static int x_socket;  Time g_last_gesturetime;
46  static Screen *screen;  static int g_x_socket;
47  static Window wnd;  static Screen *g_screen;
48  static GC gc;  Window g_wnd;
49  static Visual *visual;  extern uint32 g_embed_wnd;
50  static int depth;  BOOL g_enable_compose = False;
51  static int bpp;  BOOL g_Unobscured;              /* used for screenblt */
52  static XIM IM;  static GC g_gc = NULL;
53  static XIC IC;  static GC g_create_bitmap_gc = NULL;
54  static XModifierKeymap *mod_map;  static GC g_create_glyph_gc = NULL;
55  static Cursor current_cursor;  static Visual *g_visual;
56  static Atom protocol_atom, kill_atom;  static int g_depth;
57    static int g_bpp;
58    static XIM g_IM;
59    static XIC g_IC;
60    static XModifierKeymap *g_mod_map;
61    static Cursor g_current_cursor;
62    static HCURSOR g_null_cursor = NULL;
63    static Atom g_protocol_atom, g_kill_atom;
64    static BOOL g_focused;
65    static BOOL g_mouse_in_wnd;
66    static BOOL g_arch_match = False;       /* set to True if RGB XServer and little endian */
67    
68  /* endianness */  /* endianness */
69  static BOOL host_be;  static BOOL g_host_be;
70  static BOOL xserver_be;  static BOOL g_xserver_be;
71    static int g_red_shift_r, g_blue_shift_r, g_green_shift_r;
72    static int g_red_shift_l, g_blue_shift_l, g_green_shift_l;
73    
74  /* software backing store */  /* software backing store */
75  static BOOL ownbackstore;  extern BOOL g_ownbackstore;
76  static Pixmap backstore;  static Pixmap g_backstore = 0;
77    
78  /* Moving in single app mode */  /* Moving in single app mode */
79  static BOOL moving_wnd;  static BOOL g_moving_wnd;
80  static int move_x_offset = 0;  static int g_move_x_offset = 0;
81  static int move_y_offset = 0;  static int g_move_y_offset = 0;
82    static BOOL g_using_full_workarea = False;
83    
84    #ifdef WITH_RDPSND
85    extern int g_dsp_fd;
86    extern BOOL g_dsp_busy;
87    extern BOOL g_rdpsnd;
88    #endif
89    
90  /* MWM decorations */  /* MWM decorations */
91  #define MWM_HINTS_DECORATIONS   (1L << 1)  #define MWM_HINTS_DECORATIONS   (1L << 1)
# Line 85  typedef struct Line 108  typedef struct
108  }  }
109  PixelColour;  PixelColour;
110    
111    
112  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
113  { \  { \
114          XFillRectangle(display, wnd, gc, x, y, cx, cy); \          XFillRectangle(g_display, g_wnd, g_gc, x, y, cx, cy); \
115          if (ownbackstore) \          if (g_ownbackstore) \
116                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \                  XFillRectangle(g_display, g_backstore, g_gc, x, y, cx, cy); \
117  }  }
118    
119  #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\  #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\
120  { \  { \
121          XFillRectangle(display, ownbackstore ? backstore : wnd, gc, x, y, cx, cy); \          XFillRectangle(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, cx, cy); \
122    }
123    
124    #define FILL_POLYGON(p,np)\
125    { \
126            XFillPolygon(g_display, g_wnd, g_gc, p, np, Complex, CoordModePrevious); \
127            if (g_ownbackstore) \
128                    XFillPolygon(g_display, g_backstore, g_gc, p, np, Complex, CoordModePrevious); \
129    }
130    
131    #define DRAW_ELLIPSE(x,y,cx,cy,m)\
132    { \
133            switch (m) \
134            { \
135                    case 0: /* Outline */ \
136                            XDrawArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \
137                            if (g_ownbackstore) \
138                                    XDrawArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \
139                            break; \
140                    case 1: /* Filled */ \
141                            XFillArc(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, \
142                                     cx, cy, 0, 360*64); \
143                            if (g_ownbackstore) \
144                                    XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y); \
145                            break; \
146            } \
147  }  }
148    
149  /* colour maps */  /* colour maps */
150  BOOL owncolmap = False;  extern BOOL g_owncolmap;
151  static Colormap xcolmap;  static Colormap g_xcolmap;
152  static uint32 *colmap;  static uint32 *g_colmap = NULL;
153    
154  #define TRANSLATE(col)          ( server_bpp != 8 ? translate_colour(col) : owncolmap ? col : translate_colour(colmap[col]) )  #define TRANSLATE(col)          ( g_server_bpp != 8 ? translate_colour(col) : g_owncolmap ? col : g_colmap[col] )
155  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_FOREGROUND(col)     XSetForeground(g_display, g_gc, TRANSLATE(col));
156  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(g_display, g_gc, TRANSLATE(col));
157    
158  static int rop2_map[] = {  static int rop2_map[] = {
159          GXclear,                /* 0 */          GXclear,                /* 0 */
# Line 125  static int rop2_map[] = { Line 174  static int rop2_map[] = {
174          GXset                   /* 1 */          GXset                   /* 1 */
175  };  };
176    
177  #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]); }
178  #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); }
179    
180  static void  static void
181  mwm_hide_decorations(void)  mwm_hide_decorations(void)
# Line 139  mwm_hide_decorations(void) Line 188  mwm_hide_decorations(void)
188          motif_hints.decorations = 0;          motif_hints.decorations = 0;
189    
190          /* get the atom for the property */          /* get the atom for the property */
191          hintsatom = XInternAtom(display, "_MOTIF_WM_HINTS", False);          hintsatom = XInternAtom(g_display, "_MOTIF_WM_HINTS", False);
192          if (!hintsatom)          if (!hintsatom)
193          {          {
194                  warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");                  warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");
195                  return;                  return;
196          }          }
197    
198          XChangeProperty(display, wnd, hintsatom, hintsatom, 32, PropModeReplace,          XChangeProperty(g_display, g_wnd, hintsatom, hintsatom, 32, PropModeReplace,
199                          (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);                          (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
200  }  }
201    
202  static PixelColour  #define SPLITCOLOUR15(colour, rv) \
203  split_colour15(uint32 colour)  { \
204  {          rv.red = ((colour >> 7) & 0xf8) | ((colour >> 12) & 0x7); \
205          PixelColour rv;          rv.green = ((colour >> 2) & 0xf8) | ((colour >> 8) & 0x7); \
206          rv.red = (colour & 0x7c00) >> 10;          rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); \
         rv.red = (rv.red * 0xff) / 0x1f;  
         rv.green = (colour & 0x03e0) >> 5;  
         rv.green = (rv.green * 0xff) / 0x1f;  
         rv.blue = (colour & 0x1f);  
         rv.blue = (rv.blue * 0xff) / 0x1f;  
         return rv;  
 }  
   
 static PixelColour  
 split_colour16(uint32 colour)  
 {  
         PixelColour rv;  
         rv.red = (colour & 0xf800) >> 11;  
         rv.red = (rv.red * 0xff) / 0x1f;  
         rv.green = (colour & 0x07e0) >> 5;  
         rv.green = (rv.green * 0xff) / 0x3f;  
         rv.blue = (colour & 0x001f);  
         rv.blue = (rv.blue * 0xff) / 0x1f;  
         return rv;  
 }  
   
 static PixelColour  
 split_colour24(uint32 colour)  
 {  
         PixelColour rv;  
         rv.blue = (colour & 0xff0000) >> 16;  
         rv.green = (colour & 0xff00) >> 8;  
         rv.red = (colour & 0xff);  
         return rv;  
207  }  }
208    
209  static uint32  #define SPLITCOLOUR16(colour, rv) \
210  make_colour16(PixelColour pc)  { \
211  {          rv.red = ((colour >> 8) & 0xf8) | ((colour >> 13) & 0x7); \
212          pc.red = (pc.red * 0x1f) / 0xff;          rv.green = ((colour >> 3) & 0xfc) | ((colour >> 9) & 0x3); \
213          pc.green = (pc.green * 0x3f) / 0xff;          rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); \
214          pc.blue = (pc.blue * 0x1f) / 0xff;  } \
         return (pc.red << 11) | (pc.green << 5) | pc.blue;  
 }  
215    
216  static uint32  #define SPLITCOLOUR24(colour, rv) \
217  make_colour24(PixelColour pc)  { \
218  {          rv.blue = (colour & 0xff0000) >> 16; \
219          return (pc.red << 16) | (pc.green << 8) | pc.blue;          rv.green = (colour & 0x00ff00) >> 8; \
220            rv.red = (colour & 0x0000ff); \
221  }  }
222    
223  static uint32  #define MAKECOLOUR(pc) \
224  make_colour32(PixelColour pc)          ((pc.red >> g_red_shift_r) << g_red_shift_l) \
225  {                  | ((pc.green >> g_green_shift_r) << g_green_shift_l) \
226          return (pc.red << 16) | (pc.green << 8) | pc.blue;                  | ((pc.blue >> g_blue_shift_r) << g_blue_shift_l) \
 }  
227    
228  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
229  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | (x & 0xff00)); }
230  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
231                          x = (x << 16) | (x >> 16); }                          x = (x << 16) | (x >> 16); }
232    
233    #define BOUT16(o, x) { *(o++) = x >> 8; *(o++) = x; }
234    #define BOUT24(o, x) { *(o++) = x >> 16; *(o++) = x >> 8; *(o++) = x; }
235    #define BOUT32(o, x) { *(o++) = x >> 24; *(o++) = x >> 16; *(o++) = x >> 8; *(o++) = x; }
236    #define LOUT16(o, x) { *(o++) = x; *(o++) = x >> 8; }
237    #define LOUT24(o, x) { *(o++) = x; *(o++) = x >> 8; *(o++) = x >> 16; }
238    #define LOUT32(o, x) { *(o++) = x; *(o++) = x >> 8; *(o++) = x >> 16; *(o++) = x >> 24; }
239    
240  static uint32  static uint32
241  translate_colour(uint32 colour)  translate_colour(uint32 colour)
242  {  {
243          switch (server_bpp)          PixelColour pc;
244            switch (g_server_bpp)
245          {          {
246                  case 15:                  case 15:
247                          switch (bpp)                          SPLITCOLOUR15(colour, pc);
                         {  
                                 case 16:  
                                         colour = make_colour16(split_colour15(colour));  
                                         break;  
                                 case 24:  
                                         colour = make_colour24(split_colour15(colour));  
                                         break;  
                                 case 32:  
                                         colour = make_colour32(split_colour15(colour));  
                                         break;  
                         }  
248                          break;                          break;
249                  case 16:                  case 16:
250                          switch (bpp)                          SPLITCOLOUR16(colour, pc);
                         {  
                                 case 16:  
                                         break;  
                                 case 24:  
                                         colour = make_colour24(split_colour16(colour));  
                                         break;  
                                 case 32:  
                                         colour = make_colour32(split_colour16(colour));  
                                         break;  
                         }  
251                          break;                          break;
252                  case 24:                  case 24:
253                          switch (bpp)                          SPLITCOLOUR24(colour, pc);
                         {  
                                 case 16:  
                                         colour = make_colour16(split_colour24(colour));  
                                         break;  
                                 case 24:  
                                         break;  
                                 case 32:  
                                         colour = make_colour32(split_colour24(colour));  
                                         break;  
                         }  
254                          break;                          break;
255          }          }
256          switch (bpp)          return MAKECOLOUR(pc);
257          {  }
                 case 16:  
                         if (host_be != xserver_be)  
                                 BSWAP16(colour);  
                         break;  
258    
259                  case 24:  /* indent is confused by UNROLL8 */
260                          if (xserver_be)  /* *INDENT-OFF* */
                                 BSWAP24(colour);  
                         break;  
261    
262                  case 32:  /* repeat and unroll, similar to bitmap.c */
263                          if (host_be != xserver_be)  /* potentialy any of the following translate */
264                                  BSWAP32(colour);  /* functions can use repeat but just doing */
265                          break;  /* the most common ones */
         }  
266    
267          return colour;  #define UNROLL8(stm) { stm stm stm stm stm stm stm stm }
268    /* 2 byte output repeat */
269    #define REPEAT2(stm) \
270    { \
271            while (out <= end - 8 * 2) \
272                    UNROLL8(stm) \
273            while (out < end) \
274                    { stm } \
275  }  }
276    /* 3 byte output repeat */
277    #define REPEAT3(stm) \
278    { \
279            while (out <= end - 8 * 3) \
280                    UNROLL8(stm) \
281            while (out < end) \
282                    { stm } \
283    }
284    /* 4 byte output repeat */
285    #define REPEAT4(stm) \
286    { \
287            while (out <= end - 8 * 4) \
288                    UNROLL8(stm) \
289            while (out < end) \
290                    { stm } \
291    }
292    /* *INDENT-ON* */
293    
294  static void  static void
295  translate8to8(uint8 * data, uint8 * out, uint8 * end)  translate8to8(const uint8 * data, uint8 * out, uint8 * end)
296  {  {
297          while (out < end)          while (out < end)
298                  *(out++) = (uint8) colmap[*(data++)];                  *(out++) = (uint8) g_colmap[*(data++)];
299  }  }
300    
301  static void  static void
302  translate8to16(uint8 * data, uint16 * out, uint16 * end)  translate8to16(const uint8 * data, uint8 * out, uint8 * end)
303  {  {
304          while (out < end)          uint16 value;
305                  *(out++) = (uint16) colmap[*(data++)];  
306            if (g_arch_match)
307            {
308                    /* *INDENT-OFF* */
309                    REPEAT2
310                    (
311                            *((uint16 *) out) = g_colmap[*(data++)];
312                            out += 2;
313                    )
314                    /* *INDENT-ON* */
315            }
316            else if (g_xserver_be)
317            {
318                    while (out < end)
319                    {
320                            value = (uint16) g_colmap[*(data++)];
321                            BOUT16(out, value);
322                    }
323            }
324            else
325            {
326                    while (out < end)
327                    {
328                            value = (uint16) g_colmap[*(data++)];
329                            LOUT16(out, value);
330                    }
331            }
332  }  }
333    
334  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
335  static void  static void
336  translate8to24(uint8 * data, uint8 * out, uint8 * end)  translate8to24(const uint8 * data, uint8 * out, uint8 * end)
337  {  {
338          uint32 value;          uint32 value;
339    
340          while (out < end)          if (g_xserver_be)
341          {          {
342                  value = colmap[*(data++)];                  while (out < end)
343                  *(out++) = value;                  {
344                  *(out++) = value >> 8;                          value = g_colmap[*(data++)];
345                  *(out++) = value >> 16;                          BOUT24(out, value);
346                    }
347            }
348            else
349            {
350                    while (out < end)
351                    {
352                            value = g_colmap[*(data++)];
353                            LOUT24(out, value);
354                    }
355          }          }
356  }  }
357    
358  static void  static void
359  translate8to32(uint8 * data, uint32 * out, uint32 * end)  translate8to32(const uint8 * data, uint8 * out, uint8 * end)
360  {  {
361          while (out < end)          uint32 value;
                 *(out++) = colmap[*(data++)];  
 }  
362    
363  /* todo the remaining translate function might need some big endian check ?? */          if (g_arch_match)
364            {
365                    /* *INDENT-OFF* */
366                    REPEAT4
367                    (
368                            *((uint32 *) out) = g_colmap[*(data++)];
369                            out += 4;
370                    )
371                    /* *INDENT-ON* */
372            }
373            else if (g_xserver_be)
374            {
375                    while (out < end)
376                    {
377                            value = g_colmap[*(data++)];
378                            BOUT32(out, value);
379                    }
380            }
381            else
382            {
383                    while (out < end)
384                    {
385                            value = g_colmap[*(data++)];
386                            LOUT32(out, value);
387                    }
388            }
389    }
390    
391  static void  static void
392  translate15to16(uint16 * data, uint16 * out, uint16 * end)  translate15to16(const uint16 * data, uint8 * out, uint8 * end)
393  {  {
394          while (out < end)          uint16 pixel;
395                  *(out++) = (uint16) make_colour16(split_colour15(*(data++)));          uint16 value;
396            PixelColour pc;
397    
398            if (g_xserver_be)
399            {
400                    while (out < end)
401                    {
402                            pixel = *(data++);
403                            if (g_host_be)
404                            {
405                                    BSWAP16(pixel);
406                            }
407                            SPLITCOLOUR15(pixel, pc);
408                            value = MAKECOLOUR(pc);
409                            BOUT16(out, value);
410                    }
411            }
412            else
413            {
414                    while (out < end)
415                    {
416                            pixel = *(data++);
417                            if (g_host_be)
418                            {
419                                    BSWAP16(pixel);
420                            }
421                            SPLITCOLOUR15(pixel, pc);
422                            value = MAKECOLOUR(pc);
423                            LOUT16(out, value);
424                    }
425            }
426  }  }
427    
428  static void  static void
429  translate15to24(uint16 * data, uint8 * out, uint8 * end)  translate15to24(const uint16 * data, uint8 * out, uint8 * end)
430  {  {
431          uint32 value;          uint32 value;
432            uint16 pixel;
433            PixelColour pc;
434    
435          while (out < end)          if (g_arch_match)
436          {          {
437                  value = make_colour24(split_colour15(*(data++)));                  /* *INDENT-OFF* */
438                  *(out++) = value;                  REPEAT3
439                  *(out++) = value >> 8;                  (
440                  *(out++) = value >> 16;                          pixel = *(data++);
441                            SPLITCOLOUR15(pixel, pc);
442                            *(out++) = pc.blue;
443                            *(out++) = pc.green;
444                            *(out++) = pc.red;
445                    )
446                    /* *INDENT-ON* */
447            }
448            else if (g_xserver_be)
449            {
450                    while (out < end)
451                    {
452                            pixel = *(data++);
453                            if (g_host_be)
454                            {
455                                    BSWAP16(pixel);
456                            }
457                            SPLITCOLOUR15(pixel, pc);
458                            value = MAKECOLOUR(pc);
459                            BOUT24(out, value);
460                    }
461            }
462            else
463            {
464                    while (out < end)
465                    {
466                            pixel = *(data++);
467                            if (g_host_be)
468                            {
469                                    BSWAP16(pixel);
470                            }
471                            SPLITCOLOUR15(pixel, pc);
472                            value = MAKECOLOUR(pc);
473                            LOUT24(out, value);
474                    }
475          }          }
476  }  }
477    
478  static void  static void
479  translate15to32(uint16 * data, uint32 * out, uint32 * end)  translate15to32(const uint16 * data, uint8 * out, uint8 * end)
480  {  {
481          while (out < end)          uint16 pixel;
482                  *(out++) = make_colour32(split_colour15(*(data++)));          uint32 value;
483            PixelColour pc;
484    
485            if (g_arch_match)
486            {
487                    /* *INDENT-OFF* */
488                    REPEAT4
489                    (
490                            pixel = *(data++);
491                            SPLITCOLOUR15(pixel, pc);
492                            *(out++) = pc.blue;
493                            *(out++) = pc.green;
494                            *(out++) = pc.red;
495                            *(out++) = 0;
496                    )
497                    /* *INDENT-ON* */
498            }
499            else if (g_xserver_be)
500            {
501                    while (out < end)
502                    {
503                            pixel = *(data++);
504                            if (g_host_be)
505                            {
506                                    BSWAP16(pixel);
507                            }
508                            SPLITCOLOUR15(pixel, pc);
509                            value = MAKECOLOUR(pc);
510                            BOUT32(out, value);
511                    }
512            }
513            else
514            {
515                    while (out < end)
516                    {
517                            pixel = *(data++);
518                            if (g_host_be)
519                            {
520                                    BSWAP16(pixel);
521                            }
522                            SPLITCOLOUR15(pixel, pc);
523                            value = MAKECOLOUR(pc);
524                            LOUT32(out, value);
525                    }
526            }
527  }  }
528    
529  static void  static void
530  translate16to16(uint16 * data, uint16 * out, uint16 * end)  translate16to16(const uint16 * data, uint8 * out, uint8 * end)
531  {  {
532          while (out < end)          uint16 pixel;
533                  *(out++) = (uint16) (*(data++));          uint16 value;
534  }          PixelColour pc;
535    
536            if (g_xserver_be)
537            {
538                    if (g_host_be)
539                    {
540                            while (out < end)
541                            {
542                                    pixel = *(data++);
543                                    BSWAP16(pixel);
544                                    SPLITCOLOUR16(pixel, pc);
545                                    value = MAKECOLOUR(pc);
546                                    BOUT16(out, value);
547                            }
548                    }
549                    else
550                    {
551                            while (out < end)
552                            {
553                                    pixel = *(data++);
554                                    SPLITCOLOUR16(pixel, pc);
555                                    value = MAKECOLOUR(pc);
556                                    BOUT16(out, value);
557                            }
558                    }
559            }
560            else
561            {
562                    if (g_host_be)
563                    {
564                            while (out < end)
565                            {
566                                    pixel = *(data++);
567                                    BSWAP16(pixel);
568                                    SPLITCOLOUR16(pixel, pc);
569                                    value = MAKECOLOUR(pc);
570                                    LOUT16(out, value);
571                            }
572                    }
573                    else
574                    {
575                            while (out < end)
576                            {
577                                    pixel = *(data++);
578                                    SPLITCOLOUR16(pixel, pc);
579                                    value = MAKECOLOUR(pc);
580                                    LOUT16(out, value);
581                            }
582                    }
583            }
584    }
585    
586  static void  static void
587  translate16to24(uint16 * data, uint8 * out, uint8 * end)  translate16to24(const uint16 * data, uint8 * out, uint8 * end)
588  {  {
589          uint32 value;          uint32 value;
590            uint16 pixel;
591            PixelColour pc;
592    
593          while (out < end)          if (g_arch_match)
594          {          {
595                  value = make_colour24(split_colour16(*(data++)));                  /* *INDENT-OFF* */
596                  *(out++) = value;                  REPEAT3
597                  *(out++) = value >> 8;                  (
598                  *(out++) = value >> 16;                          pixel = *(data++);
599                            SPLITCOLOUR16(pixel, pc);
600                            *(out++) = pc.blue;
601                            *(out++) = pc.green;
602                            *(out++) = pc.red;
603                    )
604                    /* *INDENT-ON* */
605            }
606            else if (g_xserver_be)
607            {
608                    if (g_host_be)
609                    {
610                            while (out < end)
611                            {
612                                    pixel = *(data++);
613                                    BSWAP16(pixel);
614                                    SPLITCOLOUR16(pixel, pc);
615                                    value = MAKECOLOUR(pc);
616                                    BOUT24(out, value);
617                            }
618                    }
619                    else
620                    {
621                            while (out < end)
622                            {
623                                    pixel = *(data++);
624                                    SPLITCOLOUR16(pixel, pc);
625                                    value = MAKECOLOUR(pc);
626                                    BOUT24(out, value);
627                            }
628                    }
629            }
630            else
631            {
632                    if (g_host_be)
633                    {
634                            while (out < end)
635                            {
636                                    pixel = *(data++);
637                                    BSWAP16(pixel);
638                                    SPLITCOLOUR16(pixel, pc);
639                                    value = MAKECOLOUR(pc);
640                                    LOUT24(out, value);
641                            }
642                    }
643                    else
644                    {
645                            while (out < end)
646                            {
647                                    pixel = *(data++);
648                                    SPLITCOLOUR16(pixel, pc);
649                                    value = MAKECOLOUR(pc);
650                                    LOUT24(out, value);
651                            }
652                    }
653          }          }
654  }  }
655    
656  static void  static void
657  translate16to32(uint16 * data, uint32 * out, uint32 * end)  translate16to32(const uint16 * data, uint8 * out, uint8 * end)
658  {  {
659          while (out < end)          uint16 pixel;
660                  *(out++) = make_colour32(split_colour16(*(data++)));          uint32 value;
661            PixelColour pc;
662    
663            if (g_arch_match)
664            {
665                    /* *INDENT-OFF* */
666                    REPEAT4
667                    (
668                            pixel = *(data++);
669                            SPLITCOLOUR16(pixel, pc);
670                            *(out++) = pc.blue;
671                            *(out++) = pc.green;
672                            *(out++) = pc.red;
673                            *(out++) = 0;
674                    )
675                    /* *INDENT-ON* */
676            }
677            else if (g_xserver_be)
678            {
679                    if (g_host_be)
680                    {
681                            while (out < end)
682                            {
683                                    pixel = *(data++);
684                                    BSWAP16(pixel);
685                                    SPLITCOLOUR16(pixel, pc);
686                                    value = MAKECOLOUR(pc);
687                                    BOUT32(out, value);
688                            }
689                    }
690                    else
691                    {
692                            while (out < end)
693                            {
694                                    pixel = *(data++);
695                                    SPLITCOLOUR16(pixel, pc);
696                                    value = MAKECOLOUR(pc);
697                                    BOUT32(out, value);
698                            }
699                    }
700            }
701            else
702            {
703                    if (g_host_be)
704                    {
705                            while (out < end)
706                            {
707                                    pixel = *(data++);
708                                    BSWAP16(pixel);
709                                    SPLITCOLOUR16(pixel, pc);
710                                    value = MAKECOLOUR(pc);
711                                    LOUT32(out, value);
712                            }
713                    }
714                    else
715                    {
716                            while (out < end)
717                            {
718                                    pixel = *(data++);
719                                    SPLITCOLOUR16(pixel, pc);
720                                    value = MAKECOLOUR(pc);
721                                    LOUT32(out, value);
722                            }
723                    }
724            }
725  }  }
726    
727  static void  static void
728  translate24to16(uint8 * data, uint16 * out, uint16 * end)  translate24to16(const uint8 * data, uint8 * out, uint8 * end)
729  {  {
730          uint32 pixel = 0;          uint32 pixel = 0;
731            uint16 value;
732            PixelColour pc;
733    
734          while (out < end)          while (out < end)
735          {          {
736                  pixel = *(data++) << 16;                  pixel = *(data++) << 16;
737                  pixel |= *(data++) << 8;                  pixel |= *(data++) << 8;
738                  pixel |= *(data++);                  pixel |= *(data++);
739                  *(out++) = (uint16) make_colour16(split_colour24(pixel));                  SPLITCOLOUR24(pixel, pc);
740                    value = MAKECOLOUR(pc);
741                    if (g_xserver_be)
742                    {
743                            BOUT16(out, value);
744                    }
745                    else
746                    {
747                            LOUT16(out, value);
748                    }
749          }          }
750  }  }
751    
752  static void  static void
753  translate24to24(uint8 * data, uint8 * out, uint8 * end)  translate24to24(const uint8 * data, uint8 * out, uint8 * end)
754  {  {
755          while (out < end)          uint32 pixel;
756            uint32 value;
757            PixelColour pc;
758    
759            if (g_xserver_be)
760          {          {
761                  *(out++) = (*(data++));                  while (out < end)
762                    {
763                            pixel = *(data++) << 16;
764                            pixel |= *(data++) << 8;
765                            pixel |= *(data++);
766                            SPLITCOLOUR24(pixel, pc);
767                            value = MAKECOLOUR(pc);
768                            BOUT24(out, value);
769                    }
770            }
771            else
772            {
773                    while (out < end)
774                    {
775                            pixel = *(data++) << 16;
776                            pixel |= *(data++) << 8;
777                            pixel |= *(data++);
778                            SPLITCOLOUR24(pixel, pc);
779                            value = MAKECOLOUR(pc);
780                            LOUT24(out, value);
781                    }
782          }          }
783  }  }
784    
785  static void  static void
786  translate24to32(uint8 * data, uint32 * out, uint32 * end)  translate24to32(const uint8 * data, uint8 * out, uint8 * end)
787  {  {
788          uint32 pixel = 0;          uint32 pixel;
789          while (out < end)          uint32 value;
790            PixelColour pc;
791    
792            if (g_arch_match)
793          {          {
794                  pixel = *(data++);                  /* *INDENT-OFF* */
795                  pixel |= *(data++) << 8;  #ifdef NEED_ALIGN
796                  pixel |= *(data++) << 16;                  REPEAT4
797                  *(out++) = pixel;                  (
798                            *(out++) = *(data++);
799                            *(out++) = *(data++);
800                            *(out++) = *(data++);
801                            *(out++) = 0;
802                    )
803    #else
804                    REPEAT4
805                    (
806                            *((uint32 *) out) = *((uint32 *) data);
807                            out += 4;
808                            data += 3;
809                    )
810    #endif
811                    /* *INDENT-ON* */
812            }
813            else if (g_xserver_be)
814            {
815                    while (out < end)
816                    {
817                            pixel = *(data++) << 16;
818                            pixel |= *(data++) << 8;
819                            pixel |= *(data++);
820                            SPLITCOLOUR24(pixel, pc);
821                            value = MAKECOLOUR(pc);
822                            BOUT32(out, value);
823                    }
824            }
825            else
826            {
827                    while (out < end)
828                    {
829                            pixel = *(data++) << 16;
830                            pixel |= *(data++) << 8;
831                            pixel |= *(data++);
832                            SPLITCOLOUR24(pixel, pc);
833                            value = MAKECOLOUR(pc);
834                            LOUT32(out, value);
835                    }
836          }          }
837  }  }
838    
839  static uint8 *  static uint8 *
840  translate_image(int width, int height, uint8 * data)  translate_image(int width, int height, uint8 * data)
841  {  {
842          int size = width * height * bpp / 8;          int size;
843          uint8 *out = xmalloc(size);          uint8 *out;
844          uint8 *end = out + size;          uint8 *end;
845    
846            /* if server and xserver bpp match, */
847            /* and arch(endian) matches, no need to translate */
848            /* just return data */
849            if (g_arch_match)
850            {
851                    if (g_depth == 15 && g_server_bpp == 15)
852                            return data;
853                    if (g_depth == 16 && g_server_bpp == 16)
854                            return data;
855                    if (g_depth == 24 && g_bpp == 24 && g_server_bpp == 24)
856                            return data;
857            }
858    
859            size = width * height * (g_bpp / 8);
860            out = (uint8 *) xmalloc(size);
861            end = out + size;
862    
863          switch (server_bpp)          switch (g_server_bpp)
864          {          {
865                  case 24:                  case 24:
866                          switch (bpp)                          switch (g_bpp)
867                          {                          {
868                                  case 32:                                  case 32:
869                                          translate24to32(data, (uint32 *) out, (uint32 *) end);                                          translate24to32(data, out, end);
870                                          break;                                          break;
871                                  case 24:                                  case 24:
872                                          translate24to24(data, out, end);                                          translate24to24(data, out, end);
873                                          break;                                          break;
874                                  case 16:                                  case 16:
875                                          translate24to16(data, (uint16 *) out, (uint16 *) end);                                          translate24to16(data, out, end);
876                                          break;                                          break;
877                          }                          }
878                          break;                          break;
879                  case 16:                  case 16:
880                          switch (bpp)                          switch (g_bpp)
881                          {                          {
882                                  case 32:                                  case 32:
883                                          translate16to32((uint16 *) data, (uint32 *) out,                                          translate16to32((uint16 *) data, out, end);
                                                         (uint32 *) end);  
884                                          break;                                          break;
885                                  case 24:                                  case 24:
886                                          translate16to24((uint16 *) data, out, end);                                          translate16to24((uint16 *) data, out, end);
887                                          break;                                          break;
888                                  case 16:                                  case 16:
889                                          translate16to16((uint16 *) data, (uint16 *) out,                                          translate16to16((uint16 *) data, out, end);
                                                         (uint16 *) end);  
890                                          break;                                          break;
891                          }                          }
892                          break;                          break;
893                  case 15:                  case 15:
894                          switch (bpp)                          switch (g_bpp)
895                          {                          {
896                                  case 32:                                  case 32:
897                                          translate15to32((uint16 *) data, (uint32 *) out,                                          translate15to32((uint16 *) data, out, end);
                                                         (uint32 *) end);  
898                                          break;                                          break;
899                                  case 24:                                  case 24:
900                                          translate15to24((uint16 *) data, out, end);                                          translate15to24((uint16 *) data, out, end);
901                                          break;                                          break;
902                                  case 16:                                  case 16:
903                                          translate15to16((uint16 *) data, (uint16 *) out,                                          translate15to16((uint16 *) data, out, end);
                                                         (uint16 *) end);  
904                                          break;                                          break;
905                          }                          }
906                          break;                          break;
907                  case 8:                  case 8:
908                          switch (bpp)                          switch (g_bpp)
909                          {                          {
910                                  case 8:                                  case 8:
911                                          translate8to8(data, out, end);                                          translate8to8(data, out, end);
912                                          break;                                          break;
913                                  case 16:                                  case 16:
914                                          translate8to16(data, (uint16 *) out, (uint16 *) end);                                          translate8to16(data, out, end);
915                                          break;                                          break;
916                                  case 24:                                  case 24:
917                                          translate8to24(data, out, end);                                          translate8to24(data, out, end);
918                                          break;                                          break;
919                                  case 32:                                  case 32:
920                                          translate8to32(data, (uint32 *) out, (uint32 *) end);                                          translate8to32(data, out, end);
921                                          break;                                          break;
922                          }                          }
923                          break;                          break;
# Line 491  get_key_state(unsigned int state, uint32 Line 931  get_key_state(unsigned int state, uint32
931          int modifierpos, key, keysymMask = 0;          int modifierpos, key, keysymMask = 0;
932          int offset;          int offset;
933    
934          KeyCode keycode = XKeysymToKeycode(display, keysym);          KeyCode keycode = XKeysymToKeycode(g_display, keysym);
935    
936          if (keycode == NoSymbol)          if (keycode == NoSymbol)
937                  return False;                  return False;
938    
939          for (modifierpos = 0; modifierpos < 8; modifierpos++)          for (modifierpos = 0; modifierpos < 8; modifierpos++)
940          {          {
941                  offset = mod_map->max_keypermod * modifierpos;                  offset = g_mod_map->max_keypermod * modifierpos;
942    
943                  for (key = 0; key < mod_map->max_keypermod; key++)                  for (key = 0; key < g_mod_map->max_keypermod; key++)
944                  {                  {
945                          if (mod_map->modifiermap[offset + key] == keycode)                          if (g_mod_map->modifiermap[offset + key] == keycode)
946                                  keysymMask |= 1 << modifierpos;                                  keysymMask |= 1 << modifierpos;
947                  }                  }
948          }          }
# Line 510  get_key_state(unsigned int state, uint32 Line 950  get_key_state(unsigned int state, uint32
950          return (state & keysymMask) ? True : False;          return (state & keysymMask) ? True : False;
951  }  }
952    
953    static void
954    calculate_shifts(uint32 mask, int *shift_r, int *shift_l)
955    {
956            *shift_l = ffs(mask) - 1;
957            mask >>= *shift_l;
958            *shift_r = 8 - ffs(mask & ~(mask >> 1));
959    }
960    
961  BOOL  BOOL
962  ui_init(void)  ui_init(void)
963  {  {
964            XVisualInfo vi;
965          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
966          uint16 test;          uint16 test;
967          int i;          int i, screen_num, nvisuals;
968            XVisualInfo *vmatches = NULL;
969            XVisualInfo template;
970            Bool TrueColorVisual = False;
971    
972          display = XOpenDisplay(NULL);          g_display = XOpenDisplay(NULL);
973          if (display == NULL)          if (g_display == NULL)
974          {          {
975                  error("Failed to open display: %s\n", XDisplayName(NULL));                  error("Failed to open display: %s\n", XDisplayName(NULL));
976                  return False;                  return False;
977          }          }
978    
979          x_socket = ConnectionNumber(display);          screen_num = DefaultScreen(g_display);
980          screen = DefaultScreenOfDisplay(display);          g_x_socket = ConnectionNumber(g_display);
981          visual = DefaultVisualOfScreen(screen);          g_screen = ScreenOfDisplay(g_display, screen_num);
982          depth = DefaultDepthOfScreen(screen);          g_depth = DefaultDepthOfScreen(g_screen);
983    
984            /* Search for best TrueColor depth */
985            template.class = TrueColor;
986            vmatches = XGetVisualInfo(g_display, VisualClassMask, &template, &nvisuals);
987    
988            nvisuals--;
989            while (nvisuals >= 0)
990            {
991                    if ((vmatches + nvisuals)->depth > g_depth)
992                    {
993                            g_depth = (vmatches + nvisuals)->depth;
994                    }
995                    nvisuals--;
996                    TrueColorVisual = True;
997            }
998    
999            test = 1;
1000            g_host_be = !(BOOL) (*(uint8 *) (&test));
1001            g_xserver_be = (ImageByteOrder(g_display) == MSBFirst);
1002    
1003            if ((g_server_bpp == 8) && ((!TrueColorVisual) || (g_depth <= 8)))
1004            {
1005                    /* we use a colourmap, so the default visual should do */
1006                    g_visual = DefaultVisualOfScreen(g_screen);
1007                    g_depth = DefaultDepthOfScreen(g_screen);
1008    
1009                    /* Do not allocate colours on a TrueColor visual */
1010                    if (g_visual->class == TrueColor)
1011                    {
1012                            g_owncolmap = False;
1013                    }
1014            }
1015            else
1016            {
1017                    /* need a truecolour visual */
1018                    if (!XMatchVisualInfo(g_display, screen_num, g_depth, TrueColor, &vi))
1019                    {
1020                            error("The display does not support true colour - high colour support unavailable.\n");
1021                            return False;
1022                    }
1023    
1024                    g_visual = vi.visual;
1025                    g_owncolmap = False;
1026                    calculate_shifts(vi.red_mask, &g_red_shift_r, &g_red_shift_l);
1027                    calculate_shifts(vi.blue_mask, &g_blue_shift_r, &g_blue_shift_l);
1028                    calculate_shifts(vi.green_mask, &g_green_shift_r, &g_green_shift_l);
1029    
1030                    /* if RGB video and everything is little endian */
1031                    if ((vi.red_mask > vi.green_mask && vi.green_mask > vi.blue_mask) &&
1032                        !g_xserver_be && !g_host_be)
1033                    {
1034                            if (g_depth <= 16 || (g_red_shift_l == 16 && g_green_shift_l == 8 &&
1035                                                  g_blue_shift_l == 0))
1036                            {
1037                                    g_arch_match = True;
1038                            }
1039                    }
1040    
1041                    if (g_arch_match)
1042                    {
1043                            DEBUG(("Architectures match, enabling little endian optimisations.\n"));
1044                    }
1045            }
1046    
1047          pfm = XListPixmapFormats(display, &i);          pfm = XListPixmapFormats(g_display, &i);
1048          if (pfm != NULL)          if (pfm != NULL)
1049          {          {
1050                  /* Use maximum bpp for this depth - this is generally                  /* Use maximum bpp for this depth - this is generally
1051                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
1052                  while (i--)                  while (i--)
1053                  {                  {
1054                          if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))                          if ((pfm[i].depth == g_depth) && (pfm[i].bits_per_pixel > g_bpp))
1055                          {                          {
1056                                  bpp = pfm[i].bits_per_pixel;                                  g_bpp = pfm[i].bits_per_pixel;
1057                          }                          }
1058                  }                  }
1059                  XFree(pfm);                  XFree(pfm);
1060          }          }
1061    
1062          if (bpp < 8)          if (g_bpp < 8)
1063          {          {
1064                  error("Less than 8 bpp not currently supported.\n");                  error("Less than 8 bpp not currently supported.\n");
1065                  XCloseDisplay(display);                  XCloseDisplay(g_display);
1066                  return False;                  return False;
1067          }          }
1068    
1069          if (owncolmap != True)          if (!g_owncolmap)
1070          {          {
1071                  xcolmap = DefaultColormapOfScreen(screen);                  g_xcolmap =
1072                  if (depth <= 8)                          XCreateColormap(g_display, RootWindowOfScreen(g_screen), g_visual,
1073                                            AllocNone);
1074                    if (g_depth <= 8)
1075                          warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");                          warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");
1076          }          }
1077    
1078          gc = XCreateGC(display, RootWindowOfScreen(screen), 0, NULL);          if ((!g_ownbackstore) && (DoesBackingStore(g_screen) != Always))
1079            {
1080          if (DoesBackingStore(screen) != Always)                  warning("External BackingStore not available, using internal\n");
1081                  ownbackstore = True;                  g_ownbackstore = True;
1082            }
         test = 1;  
         host_be = !(BOOL) (*(uint8 *) (&test));  
         xserver_be = (ImageByteOrder(display) == MSBFirst);  
1083    
1084          if ((width == 0) || (height == 0))          /*
1085             * Determine desktop size
1086             */
1087            if (g_fullscreen)
1088            {
1089                    g_width = WidthOfScreen(g_screen);
1090                    g_height = HeightOfScreen(g_screen);
1091            }
1092            else if (g_width < 0)
1093            {
1094                    /* Percent of screen */
1095                    if (-g_width >= 100)
1096                            g_using_full_workarea = True;
1097                    g_height = HeightOfScreen(g_screen) * (-g_width) / 100;
1098                    g_width = WidthOfScreen(g_screen) * (-g_width) / 100;
1099            }
1100            else if (g_width == 0)
1101          {          {
1102                  /* Fetch geometry from _NET_WORKAREA */                  /* Fetch geometry from _NET_WORKAREA */
1103                  uint32 x, y, cx, cy;                  uint32 x, y, cx, cy;
1104                    g_using_full_workarea = True;
1105    
1106                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)
1107                  {                  {
1108                          width = cx;                          g_width = cx;
1109                          height = cy;                          g_height = cy;
1110                  }                  }
1111                  else                  else
1112                  {                  {
1113                          warning("Failed to get workarea: probably your window manager does not support extended hints\n");                          warning("Failed to get workarea: probably your window manager does not support extended hints\n");
1114                          width = 800;                          g_width = 800;
1115                          height = 600;                          g_height = 600;
1116                  }                  }
1117          }          }
1118    
         if (fullscreen)  
         {  
                 width = WidthOfScreen(screen);  
                 height = HeightOfScreen(screen);  
         }  
   
1119          /* make sure width is a multiple of 4 */          /* make sure width is a multiple of 4 */
1120          width = (width + 3) & ~3;          g_width = (g_width + 3) & ~3;
1121    
1122          if (ownbackstore)          g_mod_map = XGetModifierMapping(g_display);
         {  
                 backstore =  
                         XCreatePixmap(display, RootWindowOfScreen(screen), width, height, depth);  
1123    
1124                  /* clear to prevent rubbish being exposed at startup */          xkeymap_init();
                 XSetForeground(display, gc, BlackPixelOfScreen(screen));  
                 XFillRectangle(display, backstore, gc, 0, 0, width, height);  
         }  
1125    
1126          mod_map = XGetModifierMapping(display);          if (g_enable_compose)
1127                    g_IM = XOpenIM(g_display, NULL, NULL, NULL);
1128    
1129          if (enable_compose)          xclip_init();
                 IM = XOpenIM(display, NULL, NULL, NULL);  
1130    
1131          xkeymap_init();          DEBUG_RDP5(("server bpp %d client bpp %d depth %d\n", g_server_bpp, g_bpp, g_depth));
   
         /* todo take this out when high colour is done */  
         printf("server bpp %d client bpp %d depth %d\n", server_bpp, bpp, depth);  
1132    
1133          return True;          return True;
1134  }  }
# Line 620  ui_init(void) Line 1136  ui_init(void)
1136  void  void
1137  ui_deinit(void)  ui_deinit(void)
1138  {  {
1139          if (IM != NULL)          if (g_IM != NULL)
1140                  XCloseIM(IM);                  XCloseIM(g_IM);
1141    
1142            if (g_null_cursor != NULL)
1143                    ui_destroy_cursor(g_null_cursor);
1144    
1145          XFreeModifiermap(mod_map);          XFreeModifiermap(g_mod_map);
1146    
1147          if (ownbackstore)          if (g_ownbackstore)
1148                  XFreePixmap(display, backstore);                  XFreePixmap(g_display, g_backstore);
1149    
1150          XFreeGC(display, gc);          XFreeGC(g_display, g_gc);
1151          XCloseDisplay(display);          XCloseDisplay(g_display);
1152          display = NULL;          g_display = NULL;
1153  }  }
1154    
1155  BOOL  BOOL
1156  ui_create_window(void)  ui_create_window(void)
1157  {  {
1158            uint8 null_pointer_mask[1] = { 0x80 };
1159            uint8 null_pointer_data[24] = { 0x00 };
1160    
1161          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
1162          XClassHint *classhints;          XClassHint *classhints;
1163          XSizeHints *sizehints;          XSizeHints *sizehints;
# Line 643  ui_create_window(void) Line 1165  ui_create_window(void)
1165          long input_mask, ic_input_mask;          long input_mask, ic_input_mask;
1166          XEvent xevent;          XEvent xevent;
1167    
1168          wndwidth = fullscreen ? WidthOfScreen(screen) : width;          wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;
1169          wndheight = fullscreen ? HeightOfScreen(screen) : height;          wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;
1170    
1171            /* Handle -x-y portion of geometry string */
1172            if (g_xpos < 0 || (g_xpos == 0 && (g_pos & 2)))
1173                    g_xpos = WidthOfScreen(g_screen) + g_xpos - g_width;
1174            if (g_ypos < 0 || (g_ypos == 0 && (g_pos & 4)))
1175                    g_ypos = HeightOfScreen(g_screen) + g_ypos - g_height;
1176    
1177            attribs.background_pixel = BlackPixelOfScreen(g_screen);
1178            attribs.border_pixel = WhitePixelOfScreen(g_screen);
1179            attribs.backing_store = g_ownbackstore ? NotUseful : Always;
1180            attribs.override_redirect = g_fullscreen;
1181            attribs.colormap = g_xcolmap;
1182    
1183            g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), g_xpos, g_ypos, wndwidth,
1184                                  wndheight, 0, g_depth, InputOutput, g_visual,
1185                                  CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
1186                                  CWBorderPixel, &attribs);
1187    
1188            if (g_gc == NULL)
1189                    g_gc = XCreateGC(g_display, g_wnd, 0, NULL);
1190    
1191          attribs.background_pixel = BlackPixelOfScreen(screen);          if (g_create_bitmap_gc == NULL)
1192          attribs.backing_store = ownbackstore ? NotUseful : Always;                  g_create_bitmap_gc = XCreateGC(g_display, g_wnd, 0, NULL);
         attribs.override_redirect = fullscreen;  
1193    
1194          wnd = XCreateWindow(display, RootWindowOfScreen(screen), 0, 0, wndwidth, wndheight,          if ((g_ownbackstore) && (g_backstore == 0))
1195                              0, CopyFromParent, InputOutput, CopyFromParent,          {
1196                              CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);                  g_backstore = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
1197    
1198                    /* clear to prevent rubbish being exposed at startup */
1199                    XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));
1200                    XFillRectangle(g_display, g_backstore, g_gc, 0, 0, g_width, g_height);
1201            }
1202    
1203          XStoreName(display, wnd, title);          XStoreName(g_display, g_wnd, g_title);
1204    
1205          if (hide_decorations)          if (g_hide_decorations)
1206                  mwm_hide_decorations();                  mwm_hide_decorations();
1207    
1208          classhints = XAllocClassHint();          classhints = XAllocClassHint();
1209          if (classhints != NULL)          if (classhints != NULL)
1210          {          {
1211                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = classhints->res_class = "rdesktop";
1212                  XSetClassHint(display, wnd, classhints);                  XSetClassHint(g_display, g_wnd, classhints);
1213                  XFree(classhints);                  XFree(classhints);
1214          }          }
1215    
# Line 671  ui_create_window(void) Line 1217  ui_create_window(void)
1217          if (sizehints)          if (sizehints)
1218          {          {
1219                  sizehints->flags = PMinSize | PMaxSize;                  sizehints->flags = PMinSize | PMaxSize;
1220                  sizehints->min_width = sizehints->max_width = width;                  if (g_pos)
1221                  sizehints->min_height = sizehints->max_height = height;                          sizehints->flags |= PPosition;
1222                  XSetWMNormalHints(display, wnd, sizehints);                  sizehints->min_width = sizehints->max_width = g_width;
1223                    sizehints->min_height = sizehints->max_height = g_height;
1224                    XSetWMNormalHints(g_display, g_wnd, sizehints);
1225                  XFree(sizehints);                  XFree(sizehints);
1226          }          }
1227    
1228            if (g_embed_wnd)
1229            {
1230                    XReparentWindow(g_display, g_wnd, (Window) g_embed_wnd, 0, 0);
1231            }
1232    
1233          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
1234                  VisibilityChangeMask | FocusChangeMask;                  VisibilityChangeMask | FocusChangeMask | StructureNotifyMask;
1235    
1236          if (sendmotion)          if (g_sendmotion)
1237                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
1238          if (ownbackstore)          if (g_ownbackstore)
1239                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
1240          if (fullscreen || grab_keyboard)          if (g_fullscreen || g_grab_keyboard)
1241                  input_mask |= EnterWindowMask;                  input_mask |= EnterWindowMask;
1242          if (grab_keyboard)          if (g_grab_keyboard)
1243                  input_mask |= LeaveWindowMask;                  input_mask |= LeaveWindowMask;
1244    
1245          if (IM != NULL)          if (g_IM != NULL)
1246          {          {
1247                  IC = XCreateIC(IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),                  g_IC = XCreateIC(g_IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
1248                                 XNClientWindow, wnd, XNFocusWindow, wnd, NULL);                                   XNClientWindow, g_wnd, XNFocusWindow, g_wnd, NULL);
1249    
1250                  if ((IC != NULL)                  if ((g_IC != NULL)
1251                      && (XGetICValues(IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))                      && (XGetICValues(g_IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
1252                          input_mask |= ic_input_mask;                          input_mask |= ic_input_mask;
1253          }          }
1254    
1255          XSelectInput(display, wnd, input_mask);          XSelectInput(g_display, g_wnd, input_mask);
1256          XMapWindow(display, wnd);          XMapWindow(g_display, g_wnd);
1257    
1258          /* wait for VisibilityNotify */          /* wait for VisibilityNotify */
1259          do          do
1260          {          {
1261                  XMaskEvent(display, VisibilityChangeMask, &xevent);                  XMaskEvent(g_display, VisibilityChangeMask, &xevent);
1262          }          }
1263          while (xevent.type != VisibilityNotify);          while (xevent.type != VisibilityNotify);
1264            g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1265    
1266          focused = False;          g_focused = False;
1267          mouse_in_wnd = False;          g_mouse_in_wnd = False;
1268    
1269          /* handle the WM_DELETE_WINDOW protocol */          /* handle the WM_DELETE_WINDOW protocol */
1270          protocol_atom = XInternAtom(display, "WM_PROTOCOLS", True);          g_protocol_atom = XInternAtom(g_display, "WM_PROTOCOLS", True);
1271          kill_atom = XInternAtom(display, "WM_DELETE_WINDOW", True);          g_kill_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", True);
1272          XSetWMProtocols(display, wnd, &kill_atom, 1);          XSetWMProtocols(g_display, g_wnd, &g_kill_atom, 1);
1273    
1274            /* create invisible 1x1 cursor to be used as null cursor */
1275            if (g_null_cursor == NULL)
1276                    g_null_cursor = ui_create_cursor(0, 0, 1, 1, null_pointer_mask, null_pointer_data);
1277    
1278          return True;          return True;
1279  }  }
1280    
1281  void  void
1282    ui_resize_window()
1283    {
1284            XSizeHints *sizehints;
1285            Pixmap bs;
1286    
1287            sizehints = XAllocSizeHints();
1288            if (sizehints)
1289            {
1290                    sizehints->flags = PMinSize | PMaxSize;
1291                    sizehints->min_width = sizehints->max_width = g_width;
1292                    sizehints->min_height = sizehints->max_height = g_height;
1293                    XSetWMNormalHints(g_display, g_wnd, sizehints);
1294                    XFree(sizehints);
1295            }
1296    
1297            if (!(g_fullscreen || g_embed_wnd))
1298            {
1299                    XResizeWindow(g_display, g_wnd, g_width, g_height);
1300            }
1301    
1302            /* create new backstore pixmap */
1303            if (g_backstore != 0)
1304            {
1305                    bs = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
1306                    XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));
1307                    XFillRectangle(g_display, bs, g_gc, 0, 0, g_width, g_height);
1308                    XCopyArea(g_display, g_backstore, bs, g_gc, 0, 0, g_width, g_height, 0, 0);
1309                    XFreePixmap(g_display, g_backstore);
1310                    g_backstore = bs;
1311            }
1312    }
1313    
1314    void
1315  ui_destroy_window(void)  ui_destroy_window(void)
1316  {  {
1317          if (IC != NULL)          if (g_IC != NULL)
1318                  XDestroyIC(IC);                  XDestroyIC(g_IC);
1319    
1320          XDestroyWindow(display, wnd);          XDestroyWindow(g_display, g_wnd);
1321  }  }
1322    
1323  void  void
# Line 734  xwin_toggle_fullscreen(void) Line 1325  xwin_toggle_fullscreen(void)
1325  {  {
1326          Pixmap contents = 0;          Pixmap contents = 0;
1327    
1328          if (!ownbackstore)          if (!g_ownbackstore)
1329          {          {
1330                  /* need to save contents of window */                  /* need to save contents of window */
1331                  contents = XCreatePixmap(display, wnd, width, height, depth);                  contents = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
1332                  XCopyArea(display, wnd, contents, gc, 0, 0, width, height, 0, 0);                  XCopyArea(g_display, g_wnd, contents, g_gc, 0, 0, g_width, g_height, 0, 0);
1333          }          }
1334    
1335          ui_destroy_window();          ui_destroy_window();
1336          fullscreen = !fullscreen;          g_fullscreen = !g_fullscreen;
1337          ui_create_window();          ui_create_window();
1338    
1339          XDefineCursor(display, wnd, current_cursor);          XDefineCursor(g_display, g_wnd, g_current_cursor);
1340    
1341          if (!ownbackstore)          if (!g_ownbackstore)
1342          {          {
1343                  XCopyArea(display, contents, wnd, gc, 0, 0, width, height, 0, 0);                  XCopyArea(g_display, contents, g_wnd, g_gc, 0, 0, g_width, g_height, 0, 0);
1344                  XFreePixmap(display, contents);                  XFreePixmap(g_display, contents);
1345          }          }
1346  }  }
1347    
1348  /* Process all events in Xlib queue  static void
1349    handle_button_event(XEvent xevent, BOOL down)
1350    {
1351            uint16 button, flags = 0;
1352            g_last_gesturetime = xevent.xbutton.time;
1353            button = xkeymap_translate_button(xevent.xbutton.button);
1354            if (button == 0)
1355                    return;
1356    
1357            if (down)
1358                    flags = MOUSE_FLAG_DOWN;
1359    
1360            /* Stop moving window when button is released, regardless of cursor position */
1361            if (g_moving_wnd && (xevent.type == ButtonRelease))
1362                    g_moving_wnd = False;
1363    
1364            /* If win_button_size is nonzero, enable single app mode */
1365            if (xevent.xbutton.y < g_win_button_size)
1366            {
1367                    /*  Check from right to left: */
1368                    if (xevent.xbutton.x >= g_width - g_win_button_size)
1369                    {
1370                            /* The close button, continue */
1371                            ;
1372                    }
1373                    else if (xevent.xbutton.x >= g_width - g_win_button_size * 2)
1374                    {
1375                            /* The maximize/restore button. Do not send to
1376                               server.  It might be a good idea to change the
1377                               cursor or give some other visible indication
1378                               that rdesktop inhibited this click */
1379                            if (xevent.type == ButtonPress)
1380                                    return;
1381                    }
1382                    else if (xevent.xbutton.x >= g_width - g_win_button_size * 3)
1383                    {
1384                            /* The minimize button. Iconify window. */
1385                            if (xevent.type == ButtonRelease)
1386                            {
1387                                    /* Release the mouse button outside the minimize button, to prevent the
1388                                       actual minimazation to happen */
1389                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE, button, 1, 1);
1390                                    XIconifyWindow(g_display, g_wnd, DefaultScreen(g_display));
1391                                    return;
1392                            }
1393                    }
1394                    else if (xevent.xbutton.x <= g_win_button_size)
1395                    {
1396                            /* The system menu. Ignore. */
1397                            if (xevent.type == ButtonPress)
1398                                    return;
1399                    }
1400                    else
1401                    {
1402                            /* The title bar. */
1403                            if (xevent.type == ButtonPress)
1404                            {
1405                                    if (!g_fullscreen && g_hide_decorations && !g_using_full_workarea)
1406                                    {
1407                                            g_moving_wnd = True;
1408                                            g_move_x_offset = xevent.xbutton.x;
1409                                            g_move_y_offset = xevent.xbutton.y;
1410                                    }
1411                                    return;
1412                            }
1413                    }
1414            }
1415    
1416            rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1417                           flags | button, xevent.xbutton.x, xevent.xbutton.y);
1418    }
1419    
1420    /* Process events in Xlib queue
1421     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1422  static int  static int
1423  xwin_process_events(void)  xwin_process_events(void)
1424  {  {
1425          XEvent xevent;          XEvent xevent;
1426          KeySym keysym;          KeySym keysym;
         uint16 button, flags;  
1427          uint32 ev_time;          uint32 ev_time;
         key_translation tr;  
1428          char str[256];          char str[256];
1429          Status status;          Status status;
1430          unsigned int state;          int events = 0;
         Window wdummy;  
         int dummy;  
1431    
1432          while (XPending(display) > 0)          while ((XPending(g_display) > 0) && events++ < 20)
1433          {          {
1434                  XNextEvent(display, &xevent);                  XNextEvent(g_display, &xevent);
1435    
1436                  if ((IC != NULL) && (XFilterEvent(&xevent, None) == True))                  if ((g_IC != NULL) && (XFilterEvent(&xevent, None) == True))
1437                  {                  {
1438                          DEBUG_KBD(("Filtering event\n"));                          DEBUG_KBD(("Filtering event\n"));
1439                          continue;                          continue;
1440                  }                  }
1441    
                 flags = 0;  
   
1442                  switch (xevent.type)                  switch (xevent.type)
1443                  {                  {
1444                            case VisibilityNotify:
1445                                    g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1446                                    break;
1447                          case ClientMessage:                          case ClientMessage:
1448                                  /* the window manager told us to quit */                                  /* the window manager told us to quit */
1449                                  if ((xevent.xclient.message_type == protocol_atom)                                  if ((xevent.xclient.message_type == g_protocol_atom)
1450                                      && (xevent.xclient.data.l[0] == kill_atom))                                      && ((Atom) xevent.xclient.data.l[0] == g_kill_atom))
1451                                          /* Quit */                                          /* Quit */
1452                                          return 0;                                          return 0;
1453                                  break;                                  break;
1454    
1455                          case KeyPress:                          case KeyPress:
1456                                  if (IC != NULL)                                  g_last_gesturetime = xevent.xkey.time;
1457                                    if (g_IC != NULL)
1458                                          /* Multi_key compatible version */                                          /* Multi_key compatible version */
1459                                  {                                  {
1460                                          XmbLookupString(IC,                                          XmbLookupString(g_IC,
1461                                                          (XKeyPressedEvent *) &                                                          &xevent.xkey, str, sizeof(str), &keysym,
1462                                                          xevent, str, sizeof(str), &keysym, &status);                                                          &status);
1463                                          if (!((status == XLookupKeySym) || (status == XLookupBoth)))                                          if (!((status == XLookupKeySym) || (status == XLookupBoth)))
1464                                          {                                          {
1465                                                  error("XmbLookupString failed with status 0x%x\n",                                                  error("XmbLookupString failed with status 0x%x\n",
# Line 814  xwin_process_events(void) Line 1475  xwin_process_events(void)
1475                                                        str, sizeof(str), &keysym, NULL);                                                        str, sizeof(str), &keysym, NULL);
1476                                  }                                  }
1477    
1478                                  DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,                                  DEBUG_KBD(("KeyPress for keysym (0x%lx, %s)\n", keysym,
1479                                             get_ksname(keysym)));                                             get_ksname(keysym)));
1480    
1481                                  ev_time = time(NULL);                                  ev_time = time(NULL);
1482                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
1483                                          break;                                          break;
1484    
1485                                  tr = xkeymap_translate_key(keysym,                                  xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state,
1486                                                             xevent.xkey.keycode, xevent.xkey.state);                                                    ev_time, True, 0);
   
                                 if (tr.scancode == 0)  
                                         break;  
   
                                 ensure_remote_modifiers(ev_time, tr);  
   
                                 rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);  
1487                                  break;                                  break;
1488    
1489                          case KeyRelease:                          case KeyRelease:
1490                                    g_last_gesturetime = xevent.xkey.time;
1491                                  XLookupString((XKeyEvent *) & xevent, str,                                  XLookupString((XKeyEvent *) & xevent, str,
1492                                                sizeof(str), &keysym, NULL);                                                sizeof(str), &keysym, NULL);
1493    
1494                                  DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,                                  DEBUG_KBD(("\nKeyRelease for keysym (0x%lx, %s)\n", keysym,
1495                                             get_ksname(keysym)));                                             get_ksname(keysym)));
1496    
1497                                  ev_time = time(NULL);                                  ev_time = time(NULL);
1498                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
1499                                          break;                                          break;
1500    
1501                                  tr = xkeymap_translate_key(keysym,                                  xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state,
1502                                                             xevent.xkey.keycode, xevent.xkey.state);                                                    ev_time, False, 0);
   
                                 if (tr.scancode == 0)  
                                         break;  
   
                                 rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);  
1503                                  break;                                  break;
1504    
1505                          case ButtonPress:                          case ButtonPress:
1506                                  flags = MOUSE_FLAG_DOWN;                                  handle_button_event(xevent, True);
1507                                  /* fall through */                                  break;
1508    
1509                          case ButtonRelease:                          case ButtonRelease:
1510                                  button = xkeymap_translate_button(xevent.xbutton.button);                                  handle_button_event(xevent, False);
                                 if (button == 0)  
                                         break;  
   
                                 /* If win_button_size is nonzero, enable single app mode */  
                                 if (xevent.xbutton.y < win_button_size)  
                                 {  
                                         /* Stop moving window when button is released, regardless of cursor position */  
                                         if (moving_wnd && (xevent.type == ButtonRelease))  
                                                 moving_wnd = False;  
   
                                         /*  Check from right to left: */  
   
                                         if (xevent.xbutton.x >= width - win_button_size)  
                                         {  
                                                 /* The close button, continue */  
                                                 ;  
                                         }  
                                         else if (xevent.xbutton.x >= width - win_button_size * 2)  
                                         {  
                                                 /* The maximize/restore button. Do not send to  
                                                    server.  It might be a good idea to change the  
                                                    cursor or give some other visible indication  
                                                    that rdesktop inhibited this click */  
                                                 break;  
                                         }  
                                         else if (xevent.xbutton.x >= width - win_button_size * 3)  
                                         {  
                                                 /* The minimize button. Iconify window. */  
                                                 XIconifyWindow(display, wnd,  
                                                                DefaultScreen(display));  
                                                 break;  
                                         }  
                                         else if (xevent.xbutton.x <= win_button_size)  
                                         {  
                                                 /* The system menu. Ignore. */  
                                                 break;  
                                         }  
                                         else  
                                         {  
                                                 /* The title bar. */  
                                                 if ((xevent.type == ButtonPress) && !fullscreen  
                                                     && hide_decorations)  
                                                 {  
                                                         moving_wnd = True;  
                                                         move_x_offset = xevent.xbutton.x;  
                                                         move_y_offset = xevent.xbutton.y;  
                                                 }  
                                                 break;  
   
                                         }  
                                 }  
   
                                 rdp_send_input(time(NULL), RDP_INPUT_MOUSE,  
                                                flags | button, xevent.xbutton.x, xevent.xbutton.y);  
1511                                  break;                                  break;
1512    
1513                          case MotionNotify:                          case MotionNotify:
1514                                  if (moving_wnd)                                  if (g_moving_wnd)
1515                                  {                                  {
1516                                          XMoveWindow(display, wnd,                                          XMoveWindow(g_display, g_wnd,
1517                                                      xevent.xmotion.x_root - move_x_offset,                                                      xevent.xmotion.x_root - g_move_x_offset,
1518                                                      xevent.xmotion.y_root - move_y_offset);                                                      xevent.xmotion.y_root - g_move_y_offset);
1519                                          break;                                          break;
1520                                  }                                  }
1521    
1522                                  if (fullscreen && !focused)                                  if (g_fullscreen && !g_focused)
1523                                          XSetInputFocus(display, wnd, RevertToPointerRoot,                                          XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1524                                                         CurrentTime);                                                         CurrentTime);
1525                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1526                                                 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);                                                 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
# Line 933  xwin_process_events(void) Line 1529  xwin_process_events(void)
1529                          case FocusIn:                          case FocusIn:
1530                                  if (xevent.xfocus.mode == NotifyGrab)                                  if (xevent.xfocus.mode == NotifyGrab)
1531                                          break;                                          break;
1532                                  focused = True;                                  g_focused = True;
1533                                  XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy,                                  reset_modifier_keys();
1534                                                &dummy, &dummy, &state);                                  if (g_grab_keyboard && g_mouse_in_wnd)
1535                                  reset_modifier_keys(state);                                          XGrabKeyboard(g_display, g_wnd, True,
                                 if (grab_keyboard && mouse_in_wnd)  
                                         XGrabKeyboard(display, wnd, True,  
1536                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
1537                                  break;                                  break;
1538    
1539                          case FocusOut:                          case FocusOut:
1540                                  if (xevent.xfocus.mode == NotifyUngrab)                                  if (xevent.xfocus.mode == NotifyUngrab)
1541                                          break;                                          break;
1542                                  focused = False;                                  g_focused = False;
1543                                  if (xevent.xfocus.mode == NotifyWhileGrabbed)                                  if (xevent.xfocus.mode == NotifyWhileGrabbed)
1544                                          XUngrabKeyboard(display, CurrentTime);                                          XUngrabKeyboard(g_display, CurrentTime);
1545                                  break;                                  break;
1546    
1547                          case EnterNotify:                          case EnterNotify:
1548                                  /* we only register for this event when in fullscreen mode */                                  /* we only register for this event when in fullscreen mode */
1549                                  /* or grab_keyboard */                                  /* or grab_keyboard */
1550                                  mouse_in_wnd = True;                                  g_mouse_in_wnd = True;
1551                                  if (fullscreen)                                  if (g_fullscreen)
1552                                  {                                  {
1553                                          XSetInputFocus(display, wnd, RevertToPointerRoot,                                          XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1554                                                         CurrentTime);                                                         CurrentTime);
1555                                          break;                                          break;
1556                                  }                                  }
1557                                  if (focused)                                  if (g_focused)
1558                                          XGrabKeyboard(display, wnd, True,                                          XGrabKeyboard(g_display, g_wnd, True,
1559                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
1560                                  break;                                  break;
1561    
1562                          case LeaveNotify:                          case LeaveNotify:
1563                                  /* we only register for this event when grab_keyboard */                                  /* we only register for this event when grab_keyboard */
1564                                  mouse_in_wnd = False;                                  g_mouse_in_wnd = False;
1565                                  XUngrabKeyboard(display, CurrentTime);                                  XUngrabKeyboard(g_display, CurrentTime);
1566                                  break;                                  break;
1567    
1568                          case Expose:                          case Expose:
1569                                  XCopyArea(display, backstore, wnd, gc,                                  XCopyArea(g_display, g_backstore, g_wnd, g_gc,
1570                                            xevent.xexpose.x, xevent.xexpose.y,                                            xevent.xexpose.x, xevent.xexpose.y,
1571                                            xevent.xexpose.width,                                            xevent.xexpose.width,
1572                                            xevent.xexpose.height,                                            xevent.xexpose.height,
# Line 988  xwin_process_events(void) Line 1582  xwin_process_events(void)
1582    
1583                                  if (xevent.xmapping.request == MappingModifier)                                  if (xevent.xmapping.request == MappingModifier)
1584                                  {                                  {
1585                                          XFreeModifiermap(mod_map);                                          XFreeModifiermap(g_mod_map);
1586                                          mod_map = XGetModifierMapping(display);                                          g_mod_map = XGetModifierMapping(g_display);
1587                                  }                                  }
1588                                  break;                                  break;
1589    
1590                                    /* clipboard stuff */
1591                            case SelectionNotify:
1592                                    xclip_handle_SelectionNotify(&xevent.xselection);
1593                                    break;
1594                            case SelectionRequest:
1595                                    xclip_handle_SelectionRequest(&xevent.xselectionrequest);
1596                                    break;
1597                            case SelectionClear:
1598                                    xclip_handle_SelectionClear();
1599                                    break;
1600                            case PropertyNotify:
1601                                    xclip_handle_PropertyNotify(&xevent.xproperty);
1602                                    break;
1603                            case MapNotify:
1604                                    rdp_send_client_window_status(1);
1605                                    break;
1606                            case UnmapNotify:
1607                                    rdp_send_client_window_status(0);
1608                                    break;
1609                  }                  }
1610          }          }
1611          /* Keep going */          /* Keep going */
# Line 1003  xwin_process_events(void) Line 1616  xwin_process_events(void)
1616  int  int
1617  ui_select(int rdp_socket)  ui_select(int rdp_socket)
1618  {  {
1619          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;          int n;
1620          fd_set rfds;          fd_set rfds, wfds;
1621            struct timeval tv;
1622          FD_ZERO(&rfds);          BOOL s_timeout = False;
1623    
1624          while (True)          while (True)
1625          {          {
1626                    n = (rdp_socket > g_x_socket) ? rdp_socket : g_x_socket;
1627                  /* Process any events already waiting */                  /* Process any events already waiting */
1628                  if (!xwin_process_events())                  if (!xwin_process_events())
1629                          /* User quit */                          /* User quit */
1630                          return 0;                          return 0;
1631    
1632                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
1633                    FD_ZERO(&wfds);
1634                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
1635                  FD_SET(x_socket, &rfds);                  FD_SET(g_x_socket, &rfds);
1636    
1637    #ifdef WITH_RDPSND
1638                    /* FIXME: there should be an API for registering fds */
1639                    if (g_dsp_busy)
1640                    {
1641                            FD_SET(g_dsp_fd, &wfds);
1642                            n = (g_dsp_fd > n) ? g_dsp_fd : n;
1643                    }
1644    #endif
1645                    /* default timeout */
1646                    tv.tv_sec = 60;
1647                    tv.tv_usec = 0;
1648    
1649                    /* add redirection handles */
1650                    rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
1651    
1652                  switch (select(n, &rfds, NULL, NULL, NULL))                  n++;
1653    
1654                    switch (select(n, &rfds, &wfds, NULL, &tv))
1655                  {                  {
1656                          case -1:                          case -1:
1657                                  error("select: %s\n", strerror(errno));                                  error("select: %s\n", strerror(errno));
1658    
1659                          case 0:                          case 0:
1660                                    /* Abort serial read calls */
1661                                    if (s_timeout)
1662                                            rdpdr_check_fds(&rfds, &wfds, (BOOL) True);
1663                                  continue;                                  continue;
1664                  }                  }
1665    
1666                    rdpdr_check_fds(&rfds, &wfds, (BOOL) False);
1667    
1668                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
1669                          return 1;                          return 1;
1670    
1671    #ifdef WITH_RDPSND
1672                    if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))
1673                            wave_out_play();
1674    #endif
1675          }          }
1676  }  }
1677    
1678  void  void
1679  ui_move_pointer(int x, int y)  ui_move_pointer(int x, int y)
1680  {  {
1681          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);          XWarpPointer(g_display, g_wnd, g_wnd, 0, 0, 0, 0, x, y);
1682  }  }
1683    
1684  HBITMAP  HBITMAP
# Line 1045  ui_create_bitmap(int width, int height, Line 1687  ui_create_bitmap(int width, int height,
1687          XImage *image;          XImage *image;
1688          Pixmap bitmap;          Pixmap bitmap;
1689          uint8 *tdata;          uint8 *tdata;
1690            int bitmap_pad;
1691    
1692          tdata = (owncolmap ? data : translate_image(width, height, data));          if (g_server_bpp == 8)
1693          bitmap = XCreatePixmap(display, wnd, width, height, depth);          {
1694          image = XCreateImage(display, visual, depth, ZPixmap, 0,                  bitmap_pad = 8;
1695                               (char *) tdata, width, height, server_bpp == 8 ? 8 : bpp, 0);          }
1696            else
1697            {
1698                    bitmap_pad = g_bpp;
1699    
1700          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);                  if (g_bpp == 24)
1701                            bitmap_pad = 32;
1702            }
1703    
1704            tdata = (g_owncolmap ? data : translate_image(width, height, data));
1705            bitmap = XCreatePixmap(g_display, g_wnd, width, height, g_depth);
1706            image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1707                                 (char *) tdata, width, height, bitmap_pad, 0);
1708    
1709            XPutImage(g_display, bitmap, g_create_bitmap_gc, image, 0, 0, 0, 0, width, height);
1710    
1711          XFree(image);          XFree(image);
1712          if (!owncolmap)          if (tdata != data)
1713                  xfree(tdata);                  xfree(tdata);
1714          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
1715  }  }
# Line 1064  ui_paint_bitmap(int x, int y, int cx, in Line 1719  ui_paint_bitmap(int x, int y, int cx, in
1719  {  {
1720          XImage *image;          XImage *image;
1721          uint8 *tdata;          uint8 *tdata;
1722          tdata = (owncolmap ? data : translate_image(width, height, data));          int bitmap_pad;
         image = XCreateImage(display, visual, depth, ZPixmap, 0,  
                              (char *) tdata, width, height, server_bpp == 8 ? 8 : bpp, 0);  
1723    
1724          if (ownbackstore)          if (g_server_bpp == 8)
1725          {          {
1726                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);                  bitmap_pad = 8;
                 XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);  
1727          }          }
1728          else          else
1729          {          {
1730                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);                  bitmap_pad = g_bpp;
1731    
1732                    if (g_bpp == 24)
1733                            bitmap_pad = 32;
1734            }
1735    
1736            tdata = (g_owncolmap ? data : translate_image(width, height, data));
1737            image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1738                                 (char *) tdata, width, height, bitmap_pad, 0);
1739    
1740            if (g_ownbackstore)
1741            {
1742                    XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);
1743                    XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
1744            }
1745            else
1746            {
1747                    XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);
1748          }          }
1749    
1750          XFree(image);          XFree(image);
1751          if (!owncolmap)          if (tdata != data)
1752                  xfree(tdata);                  xfree(tdata);
1753  }  }
1754    
1755  void  void
1756  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
1757  {  {
1758          XFreePixmap(display, (Pixmap) bmp);          XFreePixmap(g_display, (Pixmap) bmp);
1759  }  }
1760    
1761  HGLYPH  HGLYPH
# Line 1095  ui_create_glyph(int width, int height, u Line 1764  ui_create_glyph(int width, int height, u
1764          XImage *image;          XImage *image;
1765          Pixmap bitmap;          Pixmap bitmap;
1766          int scanline;          int scanline;
         GC gc;  
1767    
1768          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1769    
1770          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);
1771          gc = XCreateGC(display, bitmap, 0, NULL);          if (g_create_glyph_gc == 0)
1772                    g_create_glyph_gc = XCreateGC(g_display, bitmap, 0, NULL);
1773    
1774          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,          image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,
1775                               width, height, 8, scanline);                               width, height, 8, scanline);
1776          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
1777          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1778          XInitImage(image);          XInitImage(image);
1779    
1780          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(g_display, bitmap, g_create_glyph_gc, image, 0, 0, 0, 0, width, height);
1781    
1782          XFree(image);          XFree(image);
         XFreeGC(display, gc);  
1783          return (HGLYPH) bitmap;          return (HGLYPH) bitmap;
1784  }  }
1785    
1786  void  void
1787  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
1788  {  {
1789          XFreePixmap(display, (Pixmap) glyph);          XFreePixmap(g_display, (Pixmap) glyph);
1790  }  }
1791    
1792  HCURSOR  HCURSOR
# Line 1137  ui_create_cursor(unsigned int x, unsigne Line 1805  ui_create_cursor(unsigned int x, unsigne
1805          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1806          offset = scanline * height;          offset = scanline * height;
1807    
1808          cursor = xmalloc(offset);          cursor = (uint8 *) xmalloc(offset);
1809          memset(cursor, 0, offset);          memset(cursor, 0, offset);
1810    
1811          mask = xmalloc(offset);          mask = (uint8 *) xmalloc(offset);
1812          memset(mask, 0, offset);          memset(mask, 0, offset);
1813    
1814          /* approximate AND and XOR masks with a monochrome X pointer */          /* approximate AND and XOR masks with a monochrome X pointer */
# Line 1182  ui_create_cursor(unsigned int x, unsigne Line 1850  ui_create_cursor(unsigned int x, unsigne
1850          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
1851    
1852          xcursor =          xcursor =
1853                  XCreatePixmapCursor(display, (Pixmap) cursorglyph,                  XCreatePixmapCursor(g_display, (Pixmap) cursorglyph,
1854                                      (Pixmap) maskglyph, &fg, &bg, x, y);                                      (Pixmap) maskglyph, &fg, &bg, x, y);
1855    
1856          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
# Line 1195  ui_create_cursor(unsigned int x, unsigne Line 1863  ui_create_cursor(unsigned int x, unsigne
1863  void  void
1864  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
1865  {  {
1866          current_cursor = (Cursor) cursor;          g_current_cursor = (Cursor) cursor;
1867          XDefineCursor(display, wnd, current_cursor);          XDefineCursor(g_display, g_wnd, g_current_cursor);
1868  }  }
1869    
1870  void  void
1871  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
1872  {  {
1873          XFreeCursor(display, (Cursor) cursor);          XFreeCursor(g_display, (Cursor) cursor);
1874    }
1875    
1876    void
1877    ui_set_null_cursor(void)
1878    {
1879            ui_set_cursor(g_null_cursor);
1880  }  }
1881    
1882  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 1217  ui_create_colourmap(COLOURMAP * colours) Line 1891  ui_create_colourmap(COLOURMAP * colours)
1891  {  {
1892          COLOURENTRY *entry;          COLOURENTRY *entry;
1893          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
1894          if (!owncolmap)          if (!g_owncolmap)
1895          {          {
1896                  uint32 *map = xmalloc(sizeof(*colmap) * ncolours);                  uint32 *map = (uint32 *) xmalloc(sizeof(*g_colmap) * ncolours);
1897                  XColor xentry;                  XColor xentry;
1898                  XColor xc_cache[256];                  XColor xc_cache[256];
1899                  uint32 colour;                  uint32 colour;
# Line 1229  ui_create_colourmap(COLOURMAP * colours) Line 1903  ui_create_colourmap(COLOURMAP * colours)
1903                          entry = &colours->colours[i];                          entry = &colours->colours[i];
1904                          MAKE_XCOLOR(&xentry, entry);                          MAKE_XCOLOR(&xentry, entry);
1905    
1906                          if (XAllocColor(display, xcolmap, &xentry) == 0)                          if (XAllocColor(g_display, g_xcolmap, &xentry) == 0)
1907                          {                          {
1908                                  /* Allocation failed, find closest match. */                                  /* Allocation failed, find closest match. */
1909                                  int j = 256;                                  int j = 256;
# Line 1243  ui_create_colourmap(COLOURMAP * colours) Line 1917  ui_create_colourmap(COLOURMAP * colours)
1917                                          xc_cache[colLookup].red = xc_cache[colLookup].green =                                          xc_cache[colLookup].red = xc_cache[colLookup].green =
1918                                                  xc_cache[colLookup].blue = 0;                                                  xc_cache[colLookup].blue = 0;
1919                                          xc_cache[colLookup].flags = 0;                                          xc_cache[colLookup].flags = 0;
1920                                          XQueryColor(display,                                          XQueryColor(g_display,
1921                                                      DefaultColormap(display,                                                      DefaultColormap(g_display,
1922                                                                      DefaultScreen(display)),                                                                      DefaultScreen(g_display)),
1923                                                      &xc_cache[colLookup]);                                                      &xc_cache[colLookup]);
1924                                  }                                  }
1925                                  colLookup = 0;                                  colLookup = 0;
# Line 1286  ui_create_colourmap(COLOURMAP * colours) Line 1960  ui_create_colourmap(COLOURMAP * colours)
1960    
1961                          }                          }
1962    
1963                            map[i] = colour;
                         /* byte swap here to make translate_image faster */  
                         map[i] = translate_colour(colour);  
1964                  }                  }
1965                  return map;                  return map;
1966          }          }
# Line 1297  ui_create_colourmap(COLOURMAP * colours) Line 1969  ui_create_colourmap(COLOURMAP * colours)
1969                  XColor *xcolours, *xentry;                  XColor *xcolours, *xentry;
1970                  Colormap map;                  Colormap map;
1971    
1972                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  xcolours = (XColor *) xmalloc(sizeof(XColor) * ncolours);
1973                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
1974                  {                  {
1975                          entry = &colours->colours[i];                          entry = &colours->colours[i];
# Line 1306  ui_create_colourmap(COLOURMAP * colours) Line 1978  ui_create_colourmap(COLOURMAP * colours)
1978                          MAKE_XCOLOR(xentry, entry);                          MAKE_XCOLOR(xentry, entry);
1979                  }                  }
1980    
1981                  map = XCreateColormap(display, wnd, visual, AllocAll);                  map = XCreateColormap(g_display, g_wnd, g_visual, AllocAll);
1982                  XStoreColors(display, map, xcolours, ncolours);                  XStoreColors(g_display, map, xcolours, ncolours);
1983    
1984                  xfree(xcolours);                  xfree(xcolours);
1985                  return (HCOLOURMAP) map;                  return (HCOLOURMAP) map;
# Line 1317  ui_create_colourmap(COLOURMAP * colours) Line 1989  ui_create_colourmap(COLOURMAP * colours)
1989  void  void
1990  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
1991  {  {
1992          if (!owncolmap)          if (!g_owncolmap)
1993                  xfree(map);                  xfree(map);
1994          else          else
1995                  XFreeColormap(display, (Colormap) map);                  XFreeColormap(g_display, (Colormap) map);
1996  }  }
1997    
1998  void  void
1999  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
2000  {  {
2001          if (!owncolmap)          if (!g_owncolmap)
2002                  colmap = map;          {
2003                    if (g_colmap)
2004                            xfree(g_colmap);
2005    
2006                    g_colmap = (uint32 *) map;
2007            }
2008          else          else
2009                  XSetWindowColormap(display, wnd, (Colormap) map);                  XSetWindowColormap(g_display, g_wnd, (Colormap) map);
2010  }  }
2011    
2012  void  void
# Line 1341  ui_set_clip(int x, int y, int cx, int cy Line 2018  ui_set_clip(int x, int y, int cx, int cy
2018          rect.y = y;          rect.y = y;
2019          rect.width = cx;          rect.width = cx;
2020          rect.height = cy;          rect.height = cy;
2021          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
2022  }  }
2023    
2024  void  void
# Line 1351  ui_reset_clip(void) Line 2028  ui_reset_clip(void)
2028    
2029          rect.x = 0;          rect.x = 0;
2030          rect.y = 0;          rect.y = 0;
2031          rect.width = width;          rect.width = g_width;
2032          rect.height = height;          rect.height = g_height;
2033          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
2034  }  }
2035    
2036  void  void
2037  ui_bell(void)  ui_bell(void)
2038  {  {
2039          XBell(display, 0);          XBell(g_display, 0);
2040  }  }
2041    
2042  void  void
# Line 1372  ui_destblt(uint8 opcode, Line 2049  ui_destblt(uint8 opcode,
2049  }  }
2050    
2051  static uint8 hatch_patterns[] = {  static uint8 hatch_patterns[] = {
2052          0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */          0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */
2053          0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */          0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */
2054          0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */          0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */
2055          0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */          0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */
2056          0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */          0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */
2057          0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81  /* 5 - bsDiagCross */          0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81  /* 5 - bsDiagCross */
2058  };  };
2059    
2060  void  void
# Line 1394  ui_patblt(uint8 opcode, Line 2071  ui_patblt(uint8 opcode,
2071          {          {
2072                  case 0: /* Solid */                  case 0: /* Solid */
2073                          SET_FOREGROUND(fgcolour);                          SET_FOREGROUND(fgcolour);
2074                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2075                          break;                          break;
2076    
2077                  case 2: /* Hatch */                  case 2: /* Hatch */
2078                          fill = (Pixmap) ui_create_glyph(8, 8, hatch_patterns + brush->pattern[0] * 8);                          fill = (Pixmap) ui_create_glyph(8, 8,
2079                          SET_FOREGROUND(bgcolour);                                                          hatch_patterns + brush->pattern[0] * 8);
2080                          SET_BACKGROUND(fgcolour);                          SET_FOREGROUND(fgcolour);
2081                          XSetFillStyle(display, gc, FillOpaqueStippled);                          SET_BACKGROUND(bgcolour);
2082                          XSetStipple(display, gc, fill);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2083                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);                          XSetStipple(g_display, g_gc, fill);
2084                          FILL_RECTANGLE(x, y, cx, cy);                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2085                          XSetFillStyle(display, gc, FillSolid);                          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2086                          XSetTSOrigin(display, gc, 0, 0);                          XSetFillStyle(g_display, g_gc, FillSolid);
2087                            XSetTSOrigin(g_display, g_gc, 0, 0);
2088                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
2089                          break;                          break;
2090    
# Line 1414  ui_patblt(uint8 opcode, Line 2092  ui_patblt(uint8 opcode,
2092                          for (i = 0; i != 8; i++)                          for (i = 0; i != 8; i++)
2093                                  ipattern[7 - i] = brush->pattern[i];                                  ipattern[7 - i] = brush->pattern[i];
2094                          fill = (Pixmap) ui_create_glyph(8, 8, ipattern);                          fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
   
2095                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
2096                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
2097                          XSetFillStyle(display, gc, FillOpaqueStippled);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2098                          XSetStipple(display, gc, fill);                          XSetStipple(g_display, g_gc, fill);
2099                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2100                            FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2101                          FILL_RECTANGLE(x, y, cx, cy);                          XSetFillStyle(g_display, g_gc, FillSolid);
2102                            XSetTSOrigin(g_display, g_gc, 0, 0);
                         XSetFillStyle(display, gc, FillSolid);  
                         XSetTSOrigin(display, gc, 0, 0);  
2103                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
2104                          break;                          break;
2105    
# Line 1433  ui_patblt(uint8 opcode, Line 2108  ui_patblt(uint8 opcode,
2108          }          }
2109    
2110          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
2111    
2112            if (g_ownbackstore)
2113                    XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
2114  }  }
2115    
2116  void  void
# Line 1441  ui_screenblt(uint8 opcode, Line 2119  ui_screenblt(uint8 opcode,
2119               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
2120  {  {
2121          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
2122          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          if (g_ownbackstore)
2123          if (ownbackstore)          {
2124                  XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);                  if (g_Unobscured)
2125                    {
2126                            XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
2127                            XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x,
2128                                      y);
2129                    }
2130                    else
2131                    {
2132                            XCopyArea(g_display, g_backstore, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
2133                            XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x,
2134                                      y);
2135                    }
2136            }
2137            else
2138            {
2139                    XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
2140            }
2141          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
2142  }  }
2143    
# Line 1453  ui_memblt(uint8 opcode, Line 2147  ui_memblt(uint8 opcode,
2147            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
2148  {  {
2149          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
2150          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);
2151          if (ownbackstore)          if (g_ownbackstore)
2152                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);                  XCopyArea(g_display, (Pixmap) src, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);
2153          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
2154  }  }
2155    
# Line 1499  ui_line(uint8 opcode, Line 2193  ui_line(uint8 opcode,
2193  {  {
2194          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
2195          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
2196          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(g_display, g_wnd, g_gc, startx, starty, endx, endy);
2197          if (ownbackstore)          if (g_ownbackstore)
2198                  XDrawLine(display, backstore, gc, startx, starty, endx, endy);                  XDrawLine(g_display, g_backstore, g_gc, startx, starty, endx, endy);
2199          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
2200  }  }
2201    
# Line 1514  ui_rect( Line 2208  ui_rect(
2208          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
2209  }  }
2210    
2211    void
2212    ui_polygon(uint8 opcode,
2213               /* mode */ uint8 fillmode,
2214               /* dest */ POINT * point, int npoints,
2215               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2216    {
2217            uint8 style, i, ipattern[8];
2218            Pixmap fill;
2219    
2220            SET_FUNCTION(opcode);
2221    
2222            switch (fillmode)
2223            {
2224                    case ALTERNATE:
2225                            XSetFillRule(g_display, g_gc, EvenOddRule);
2226                            break;
2227                    case WINDING:
2228                            XSetFillRule(g_display, g_gc, WindingRule);
2229                            break;
2230                    default:
2231                            unimpl("fill mode %d\n", fillmode);
2232            }
2233    
2234            if (brush)
2235                    style = brush->style;
2236            else
2237                    style = 0;
2238    
2239            switch (style)
2240            {
2241                    case 0: /* Solid */
2242                            SET_FOREGROUND(fgcolour);
2243                            FILL_POLYGON((XPoint *) point, npoints);
2244                            break;
2245    
2246                    case 2: /* Hatch */
2247                            fill = (Pixmap) ui_create_glyph(8, 8,
2248                                                            hatch_patterns + brush->pattern[0] * 8);
2249                            SET_FOREGROUND(fgcolour);
2250                            SET_BACKGROUND(bgcolour);
2251                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2252                            XSetStipple(g_display, g_gc, fill);
2253                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2254                            FILL_POLYGON((XPoint *) point, npoints);
2255                            XSetFillStyle(g_display, g_gc, FillSolid);
2256                            XSetTSOrigin(g_display, g_gc, 0, 0);
2257                            ui_destroy_glyph((HGLYPH) fill);
2258                            break;
2259    
2260                    case 3: /* Pattern */
2261                            for (i = 0; i != 8; i++)
2262                                    ipattern[7 - i] = brush->pattern[i];
2263                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2264                            SET_FOREGROUND(bgcolour);
2265                            SET_BACKGROUND(fgcolour);
2266                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2267                            XSetStipple(g_display, g_gc, fill);
2268                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2269                            FILL_POLYGON((XPoint *) point, npoints);
2270                            XSetFillStyle(g_display, g_gc, FillSolid);
2271                            XSetTSOrigin(g_display, g_gc, 0, 0);
2272                            ui_destroy_glyph((HGLYPH) fill);
2273                            break;
2274    
2275                    default:
2276                            unimpl("brush %d\n", brush->style);
2277            }
2278    
2279            RESET_FUNCTION(opcode);
2280    }
2281    
2282    void
2283    ui_polyline(uint8 opcode,
2284                /* dest */ POINT * points, int npoints,
2285                /* pen */ PEN * pen)
2286    {
2287            /* TODO: set join style */
2288            SET_FUNCTION(opcode);
2289            SET_FOREGROUND(pen->colour);
2290            XDrawLines(g_display, g_wnd, g_gc, (XPoint *) points, npoints, CoordModePrevious);
2291            if (g_ownbackstore)
2292                    XDrawLines(g_display, g_backstore, g_gc, (XPoint *) points, npoints,
2293                               CoordModePrevious);
2294            RESET_FUNCTION(opcode);
2295    }
2296    
2297    void
2298    ui_ellipse(uint8 opcode,
2299               /* mode */ uint8 fillmode,
2300               /* dest */ int x, int y, int cx, int cy,
2301               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2302    {
2303            uint8 style, i, ipattern[8];
2304            Pixmap fill;
2305    
2306            SET_FUNCTION(opcode);
2307    
2308            if (brush)
2309                    style = brush->style;
2310            else
2311                    style = 0;
2312    
2313            switch (style)
2314            {
2315                    case 0: /* Solid */
2316                            SET_FOREGROUND(fgcolour);
2317                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2318                            break;
2319    
2320                    case 2: /* Hatch */
2321                            fill = (Pixmap) ui_create_glyph(8, 8,
2322                                                            hatch_patterns + brush->pattern[0] * 8);
2323                            SET_FOREGROUND(fgcolour);
2324                            SET_BACKGROUND(bgcolour);
2325                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2326                            XSetStipple(g_display, g_gc, fill);
2327                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2328                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2329                            XSetFillStyle(g_display, g_gc, FillSolid);
2330                            XSetTSOrigin(g_display, g_gc, 0, 0);
2331                            ui_destroy_glyph((HGLYPH) fill);
2332                            break;
2333    
2334                    case 3: /* Pattern */
2335                            for (i = 0; i != 8; i++)
2336                                    ipattern[7 - i] = brush->pattern[i];
2337                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2338                            SET_FOREGROUND(bgcolour);
2339                            SET_BACKGROUND(fgcolour);
2340                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2341                            XSetStipple(g_display, g_gc, fill);
2342                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2343                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2344                            XSetFillStyle(g_display, g_gc, FillSolid);
2345                            XSetTSOrigin(g_display, g_gc, 0, 0);
2346                            ui_destroy_glyph((HGLYPH) fill);
2347                            break;
2348    
2349                    default:
2350                            unimpl("brush %d\n", brush->style);
2351            }
2352    
2353            RESET_FUNCTION(opcode);
2354    }
2355    
2356  /* warning, this function only draws on wnd or backstore, not both */  /* warning, this function only draws on wnd or backstore, not both */
2357  void  void
2358  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
# Line 1524  ui_draw_glyph(int mixmode, Line 2363  ui_draw_glyph(int mixmode,
2363          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
2364          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
2365    
2366          XSetFillStyle(display, gc,          XSetFillStyle(g_display, g_gc,
2367                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
2368          XSetStipple(display, gc, (Pixmap) glyph);          XSetStipple(g_display, g_gc, (Pixmap) glyph);
2369          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(g_display, g_gc, x, y);
2370    
2371          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2372    
2373          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(g_display, g_gc, FillSolid);
2374  }  }
2375    
2376  #define DO_GLYPH(ttext,idx) \  #define DO_GLYPH(ttext,idx) \
2377  {\  {\
2378    glyph = cache_get_font (font, ttext[idx]);\    glyph = cache_get_font (font, ttext[idx]);\
2379    if (!(flags & TEXT2_IMPLICIT_X))\    if (!(flags & TEXT2_IMPLICIT_X))\
2380      {\
2381        xyoffset = ttext[++idx];\
2382        if ((xyoffset & 0x80))\
2383      {\      {\
2384        xyoffset = ttext[++idx];\        if (flags & TEXT2_VERTICAL)\
2385        if ((xyoffset & 0x80))\          y += ttext[idx+1] | (ttext[idx+2] << 8);\
         {\  
           if (flags & TEXT2_VERTICAL) \  
             y += ttext[idx+1] | (ttext[idx+2] << 8);\  
           else\  
             x += ttext[idx+1] | (ttext[idx+2] << 8);\  
           idx += 2;\  
         }\  
2386        else\        else\
2387          {\          x += ttext[idx+1] | (ttext[idx+2] << 8);\
2388            if (flags & TEXT2_VERTICAL) \        idx += 2;\
             y += xyoffset;\  
           else\  
             x += xyoffset;\  
         }\  
2389      }\      }\
2390    if (glyph != NULL)\      else\
2391      {\      {\
2392        ui_draw_glyph (mixmode, x + glyph->offset,\        if (flags & TEXT2_VERTICAL)\
2393                       y + glyph->baseline,\          y += xyoffset;\
2394                       glyph->width, glyph->height,\        else\
2395                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\          x += xyoffset;\
       if (flags & TEXT2_IMPLICIT_X)\  
         x += glyph->width;\  
2396      }\      }\
2397      }\
2398      if (glyph != NULL)\
2399      {\
2400        x1 = x + glyph->offset;\
2401        y1 = y + glyph->baseline;\
2402        XSetStipple(g_display, g_gc, (Pixmap) glyph->pixmap);\
2403        XSetTSOrigin(g_display, g_gc, x1, y1);\
2404        FILL_RECTANGLE_BACKSTORE(x1, y1, glyph->width, glyph->height);\
2405        if (flags & TEXT2_IMPLICIT_X)\
2406          x += glyph->width;\
2407      }\
2408  }  }
2409    
2410  void  void
2411  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,  ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode, int x, int y,
2412               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy,
2413               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
2414               int fgcolour, uint8 * text, uint8 length)               int bgcolour, int fgcolour, uint8 * text, uint8 length)
2415  {  {
2416            /* TODO: use brush appropriately */
2417    
2418          FONTGLYPH *glyph;          FONTGLYPH *glyph;
2419          int i, j, xyoffset;          int i, j, xyoffset, x1, y1;
2420          DATABLOB *entry;          DATABLOB *entry;
2421    
2422          SET_FOREGROUND(bgcolour);          SET_FOREGROUND(bgcolour);
2423    
2424            /* Sometimes, the boxcx value is something really large, like
2425               32691. This makes XCopyArea fail with Xvnc. The code below
2426               is a quick fix. */
2427            if (boxx + boxcx > g_width)
2428                    boxcx = g_width - boxx;
2429    
2430          if (boxcx > 1)          if (boxcx > 1)
2431          {          {
2432                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
# Line 1588  ui_draw_text(uint8 font, uint8 flags, in Line 2436  ui_draw_text(uint8 font, uint8 flags, in
2436                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
2437          }          }
2438    
2439            SET_FOREGROUND(fgcolour);
2440            SET_BACKGROUND(bgcolour);
2441            XSetFillStyle(g_display, g_gc, FillStippled);
2442    
2443          /* Paint text, character by character */          /* Paint text, character by character */
2444          for (i = 0; i < length;)          for (i = 0; i < length;)
2445          {          {
# Line 1638  ui_draw_text(uint8 font, uint8 flags, in Line 2490  ui_draw_text(uint8 font, uint8 flags, in
2490                                  break;                                  break;
2491                  }                  }
2492          }          }
2493          if (ownbackstore)  
2494            XSetFillStyle(g_display, g_gc, FillSolid);
2495    
2496            if (g_ownbackstore)
2497          {          {
2498                  if (boxcx > 1)                  if (boxcx > 1)
2499                          XCopyArea(display, backstore, wnd, gc, boxx,                          XCopyArea(g_display, g_backstore, g_wnd, g_gc, boxx,
2500                                    boxy, boxcx, boxcy, boxx, boxy);                                    boxy, boxcx, boxcy, boxx, boxy);
2501                  else                  else
2502                          XCopyArea(display, backstore, wnd, gc, clipx,                          XCopyArea(g_display, g_backstore, g_wnd, g_gc, clipx,
2503                                    clipy, clipcx, clipcy, clipx, clipy);                                    clipy, clipcx, clipcy, clipx, clipy);
2504          }          }
2505  }  }
# Line 1655  ui_desktop_save(uint32 offset, int x, in Line 2510  ui_desktop_save(uint32 offset, int x, in
2510          Pixmap pix;          Pixmap pix;
2511          XImage *image;          XImage *image;
2512    
2513          if (ownbackstore)          if (g_ownbackstore)
2514          {          {
2515                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);                  image = XGetImage(g_display, g_backstore, x, y, cx, cy, AllPlanes, ZPixmap);
2516          }          }
2517          else          else
2518          {          {
2519                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(g_display, g_wnd, cx, cy, g_depth);
2520                  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);
2521                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);                  image = XGetImage(g_display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
2522                  XFreePixmap(display, pix);                  XFreePixmap(g_display, pix);
2523          }          }
2524    
2525          offset *= bpp / 8;          offset *= g_bpp / 8;
2526          cache_put_desktop(offset, cx, cy, image->bytes_per_line, bpp / 8, (uint8 *) image->data);          cache_put_desktop(offset, cx, cy, image->bytes_per_line, g_bpp / 8, (uint8 *) image->data);
2527    
2528          XDestroyImage(image);          XDestroyImage(image);
2529  }  }
# Line 1679  ui_desktop_restore(uint32 offset, int x, Line 2534  ui_desktop_restore(uint32 offset, int x,
2534          XImage *image;          XImage *image;
2535          uint8 *data;          uint8 *data;
2536    
2537          offset *= bpp / 8;          offset *= g_bpp / 8;
2538          data = cache_get_desktop(offset, cx, cy, bpp / 8);          data = cache_get_desktop(offset, cx, cy, g_bpp / 8);
2539          if (data == NULL)          if (data == NULL)
2540                  return;                  return;
2541    
2542          image = XCreateImage(display, visual, depth, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
2543                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);                               (char *) data, cx, cy, BitmapPad(g_display), cx * g_bpp / 8);
2544    
2545          if (ownbackstore)          if (g_ownbackstore)
2546          {          {
2547                  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);
2548                  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);
2549          }          }
2550          else          else
2551          {          {
2552                  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);
2553          }          }
2554    
2555          XFree(image);          XFree(image);
2556  }  }
2557    
2558    /* these do nothing here but are used in uiports */
2559    void
2560    ui_begin_update(void)
2561    {
2562    }
2563    
2564    void
2565    ui_end_update(void)
2566    {
2567    }

Legend:
Removed from v.373  
changed lines
  Added in v.991

  ViewVC Help
Powered by ViewVC 1.1.26