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

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

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

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

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

  ViewVC Help
Powered by ViewVC 1.1.26