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

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

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

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

Legend:
Removed from v.448  
changed lines
  Added in v.949

  ViewVC Help
Powered by ViewVC 1.1.26