/[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 53 by matthewc, Tue May 28 11:48:55 2002 UTC revision 262 by astrand, Mon Nov 18 15:37:20 2002 UTC
# Line 1  Line 1 
1  /*  /*
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    
 extern char keymapname[16];  
 extern int keylayout;  
27  extern int width;  extern int width;
28  extern int height;  extern int height;
29  extern BOOL sendmotion;  extern BOOL sendmotion;
30  extern BOOL fullscreen;  extern BOOL fullscreen;
31    extern BOOL grab_keyboard;
32    extern BOOL hide_decorations;
33    extern char title[];
34    BOOL enable_compose = False;
35    BOOL focused;
36    BOOL mouse_in_wnd;
37    
38  Display *display;  Display *display;
 XkbDescPtr xkb;  
39  static int x_socket;  static int x_socket;
40    static Screen *screen;
41  static Window wnd;  static Window wnd;
42  static GC gc;  static GC gc;
43  static Visual *visual;  static Visual *visual;
44  static int depth;  static int depth;
45  static int bpp;  static int bpp;
46    static XIM IM;
47    static XIC IC;
48    static XModifierKeymap *mod_map;
49    static Cursor current_cursor;
50    
51  /* endianness */  /* endianness */
52  static BOOL host_be;  static BOOL host_be;
# Line 49  static BOOL xserver_be; Line 56  static BOOL xserver_be;
56  static BOOL ownbackstore;  static BOOL ownbackstore;
57  static Pixmap backstore;  static Pixmap backstore;
58    
59  /* needed to keep track of the modifiers */  /* MWM decorations */
60  static unsigned int key_modifier_state = 0;  #define MWM_HINTS_DECORATIONS   (1L << 1)
61  static unsigned int key_down_state = 0;  #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
62    typedef struct
63  #define DShift1Mask   (1<<0)  {
64  #define DShift2Mask   (1<<1)          unsigned long flags;
65  #define DControl1Mask (1<<2)          unsigned long functions;
66  #define DControl2Mask (1<<3)          unsigned long decorations;
67  #define DMod1Mask     (1<<4)          long inputMode;
68  #define DMod2Mask     (1<<5)          unsigned long status;
69    }
70    PropMotifWmHints;
71    
72    
73  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
74  { \  { \
# Line 68  static unsigned int key_down_state = 0; Line 78  static unsigned int key_down_state = 0;
78  }  }
79    
80  /* colour maps */  /* colour maps */
 static BOOL owncolmap;  
81  static Colormap xcolmap;  static Colormap xcolmap;
 static uint32 white;  
82  static uint32 *colmap;  static uint32 *colmap;
83    
84  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )  #define SET_FOREGROUND(col)     XSetForeground(display, gc, translate_colour(colmap[col]));
85  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(display, gc, translate_colour(colmap[col]));
 #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  
86    
87  static int rop2_map[] = {  static int rop2_map[] = {
88          GXclear,                /* 0 */          GXclear,                /* 0 */
# Line 99  static int rop2_map[] = { Line 106  static int rop2_map[] = {
106  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
107  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
108    
109  void xwin_release_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode);  void
110  void xwin_press_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode);  mwm_hide_decorations(void)
111    {
112            PropMotifWmHints motif_hints;
113            Atom hintsatom;
114    
115            /* setup the property */
116            motif_hints.flags = MWM_HINTS_DECORATIONS;
117            motif_hints.decorations = 0;
118    
119            /* get the atom for the property */
120            hintsatom = XInternAtom(display, "_MOTIF_WM_HINTS", False);
121            if (!hintsatom)
122            {
123                    error("Failed to get atom _MOTIF_WM_HINTS\n");
124                    return;
125            }
126    
127            XChangeProperty(display, wnd, hintsatom, hintsatom, 32, PropModeReplace,
128                            (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
129    }
130    
131  static void  static void
132  translate8(uint8 *data, uint8 *out, uint8 *end)  translate8(uint8 * data, uint8 * out, uint8 * end)
133  {  {
134          while (out < end)          while (out < end)
135                  *(out++) = (uint8)colmap[*(data++)];                  *(out++) = (uint8) colmap[*(data++)];
136  }  }
137    
138  static void  static void
139  translate16(uint8 *data, uint16 *out, uint16 *end)  translate16(uint8 * data, uint16 * out, uint16 * end)
140  {  {
141          while (out < end)          while (out < end)
142                  *(out++) = (uint16)colmap[*(data++)];                  *(out++) = (uint16) colmap[*(data++)];
143  }  }
144    
145  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
146  static void  static void
147  translate24(uint8 *data, uint8 *out, uint8 *end)  translate24(uint8 * data, uint8 * out, uint8 * end)
148  {  {
149          uint32 value;          uint32 value;
150    
# Line 132  translate24(uint8 *data, uint8 *out, uin Line 158  translate24(uint8 *data, uint8 *out, uin
158  }  }
159    
160  static void  static void
161  translate32(uint8 *data, uint32 *out, uint32 *end)  translate32(uint8 * data, uint32 * out, uint32 * end)
162  {  {
163          while (out < end)          while (out < end)
164                  *(out++) = colmap[*(data++)];                  *(out++) = colmap[*(data++)];
165  }  }
166    
167  static uint8 *  static uint8 *
168  translate_image(int width, int height, uint8 *data)  translate_image(int width, int height, uint8 * data)
169  {  {
170          int size = width * height * bpp/8;          int size = width * height * bpp / 8;
171          uint8 *out = xmalloc(size);          uint8 *out = xmalloc(size);
172          uint8 *end = out + size;          uint8 *end = out + size;
173    
# Line 152  translate_image(int width, int height, u Line 178  translate_image(int width, int height, u
178                          break;                          break;
179    
180                  case 16:                  case 16:
181                          translate16(data, (uint16 *)out, (uint16 *)end);                          translate16(data, (uint16 *) out, (uint16 *) end);
182                          break;                          break;
183    
184                  case 24:                  case 24:
# Line 160  translate_image(int width, int height, u Line 186  translate_image(int width, int height, u
186                          break;                          break;
187    
188                  case 32:                  case 32:
189                          translate32(data, (uint32 *)out, (uint32 *)end);                          translate32(data, (uint32 *) out, (uint32 *) end);
190                          break;                          break;
191          }          }
192    
# Line 197  translate_colour(uint32 colour) Line 223  translate_colour(uint32 colour)
223  }  }
224    
225  BOOL  BOOL
226  ui_create_window(char *title)  get_key_state(unsigned int state, uint32 keysym)
227  {  {
228          XSetWindowAttributes attribs;          int modifierpos, key, keysymMask = 0;
229          XClassHint *classhints;          int offset;
230          XSizeHints *sizehints;  
231          unsigned long input_mask;          KeyCode keycode = XKeysymToKeycode(display, keysym);
         XPixmapFormatValues *pfm;  
         Screen *screen;  
         uint16 test;  
         int i;  
           
         int xkb_minor, xkb_major;  
         int xkb_event, xkb_error, xkb_reason;  
   
         /* compare compiletime libs with runtime libs. */  
         xkb_major = XkbMajorVersion;  
         xkb_minor = XkbMinorVersion;  
         if( XkbLibraryVersion( &xkb_major, &xkb_minor ) == False )  
         {  
                 error("please re-compile rdesktop\ncompile time version of xkb is not compatible with\nyour runtime version of the library\n");  
                 return False;  
         }  
232    
233            if (keycode == NoSymbol)
234                    return False;
235    
236          /* 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. )          for (modifierpos = 0; modifierpos < 8; modifierpos++)
          * 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)  
237          {          {
238                  case XkbOD_BadLibraryVersion:                  offset = mod_map->max_keypermod * modifierpos;
239                          error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n");  
240                          break;                  for (key = 0; key < mod_map->max_keypermod; key++)
241                  case XkbOD_ConnectionRefused:                  {
242                          error("XkbOD_ConnectionRefused\n");                          if (mod_map->modifiermap[offset + key] == keycode)
243                          break;                                  keysymMask |= 1 << modifierpos;
244                  case XkbOD_BadServerVersion:                  }
                         error("XkbOD_BadServerVersion\n");  
                         break;  
                 case XkbOD_NonXkbServer:  
                         error("XkbOD_NonXkbServer: XKB extension not present in server\nupdate your X server.\n");  
                         break;  
                 case XkbOD_Success:  
                         DEBUG("XkbOD_Success: Connection established with display\n");  
                         break;  
245          }          }
246    
247            return (state & keysymMask) ? True : False;
248    }
249    
250    BOOL
251    ui_init(void)
252    {
253            XPixmapFormatValues *pfm;
254            uint16 test;
255            int i;
256    
257            display = XOpenDisplay(NULL);
258          if (display == NULL)          if (display == NULL)
259          {          {
260                  error("Failed to open display\n");                  error("Failed to open display: %s\n", XDisplayName(NULL));
261                  return False;                  return False;
262          }          }
263    
# Line 255  ui_create_window(char *title) Line 265  ui_create_window(char *title)
265          screen = DefaultScreenOfDisplay(display);          screen = DefaultScreenOfDisplay(display);
266          visual = DefaultVisualOfScreen(screen);          visual = DefaultVisualOfScreen(screen);
267          depth = DefaultDepthOfScreen(screen);          depth = DefaultDepthOfScreen(screen);
268            
269          pfm = XListPixmapFormats(display, &i);          pfm = XListPixmapFormats(display, &i);
270          if (pfm != NULL)          if (pfm != NULL)
271          {          {
# Line 263  ui_create_window(char *title) Line 273  ui_create_window(char *title)
273                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
274                  while (i--)                  while (i--)
275                  {                  {
276                          if ((pfm[i].depth == depth)                          if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))
                             && (pfm[i].bits_per_pixel > bpp))  
277                          {                          {
278                                  bpp = pfm[i].bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
279                          }                          }
# Line 279  ui_create_window(char *title) Line 288  ui_create_window(char *title)
288                  return False;                  return False;
289          }          }
290    
291          if (depth <= 8)          xcolmap = DefaultColormapOfScreen(screen);
292                  owncolmap = True;          gc = XCreateGC(display, RootWindowOfScreen(screen), 0, NULL);
293          else  
294                  xcolmap = DefaultColormapOfScreen(screen);          if (DoesBackingStore(screen) != Always)
295                    ownbackstore = True;
296    
297          test = 1;          test = 1;
298          host_be = !(BOOL)(*(uint8 *)(&test));          host_be = !(BOOL) (*(uint8 *) (&test));
299          xserver_be = (ImageByteOrder(display) == MSBFirst);          xserver_be = (ImageByteOrder(display) == MSBFirst);
300    
         white = WhitePixelOfScreen(screen);  
         attribs.background_pixel = BlackPixelOfScreen(screen);  
         attribs.backing_store = DoesBackingStore(screen);  
   
         if (attribs.backing_store == NotUseful)  
                 ownbackstore = True;  
   
301          if (fullscreen)          if (fullscreen)
302          {          {
                 attribs.override_redirect = True;  
303                  width = WidthOfScreen(screen);                  width = WidthOfScreen(screen);
304                  height = HeightOfScreen(screen);                  height = HeightOfScreen(screen);
305          }          }
306          else  
307            /* make sure width is a multiple of 4 */
308            width = (width + 3) & ~3;
309    
310            if (ownbackstore)
311          {          {
312                  attribs.override_redirect = False;                  backstore =
313                            XCreatePixmap(display, RootWindowOfScreen(screen), width, height, depth);
314    
315                    /* clear to prevent rubbish being exposed at startup */
316                    XSetForeground(display, gc, BlackPixelOfScreen(screen));
317                    XFillRectangle(display, backstore, gc, 0, 0, width, height);
318          }          }
319    
320          width = (width + 3) & ~3; /* make width a multiple of 32 bits */          mod_map = XGetModifierMapping(display);
321    
322            if (enable_compose)
323                    IM = XOpenIM(display, NULL, NULL, NULL);
324    
325            xkeymap_init();
326            return True;
327    }
328    
329    void
330    ui_deinit(void)
331    {
332            if (IM != NULL)
333                    XCloseIM(IM);
334    
335            XFreeModifiermap(mod_map);
336    
337            if (ownbackstore)
338                    XFreePixmap(display, backstore);
339    
340            XFreeGC(display, gc);
341            XCloseDisplay(display);
342            display = NULL;
343    }
344    
345    BOOL
346    ui_create_window(void)
347    {
348            XSetWindowAttributes attribs;
349            XClassHint *classhints;
350            XSizeHints *sizehints;
351            int wndwidth, wndheight;
352            long input_mask, ic_input_mask;
353            XEvent xevent;
354    
355            wndwidth = fullscreen ? WidthOfScreen(screen) : width;
356            wndheight = fullscreen ? HeightOfScreen(screen) : height;
357    
358            attribs.background_pixel = BlackPixelOfScreen(screen);
359            attribs.backing_store = ownbackstore ? NotUseful : Always;
360            attribs.override_redirect = fullscreen;
361    
362          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          wnd = XCreateWindow(display, RootWindowOfScreen(screen), 0, 0, wndwidth, wndheight,
363                              0, 0, width, height, 0, CopyFromParent,                              0, CopyFromParent, InputOutput, CopyFromParent,
364                              InputOutput, CopyFromParent,                              CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);
                             CWBackingStore | CWBackPixel | CWOverrideRedirect,  
                             &attribs);  
365    
366          XStoreName(display, wnd, title);          XStoreName(display, wnd, title);
367    
368            if (hide_decorations)
369                    mwm_hide_decorations();
370    
371          classhints = XAllocClassHint();          classhints = XAllocClassHint();
372          if (classhints != NULL)          if (classhints != NULL)
373          {          {
# Line 334  ui_create_window(char *title) Line 386  ui_create_window(char *title)
386                  XFree(sizehints);                  XFree(sizehints);
387          }          }
388    
389          xkeymap_init();          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
390                    VisibilityChangeMask | FocusChangeMask;
391    
         input_mask = KeyPressMask | KeyReleaseMask |  
                          ButtonPressMask | ButtonReleaseMask |  
                          EnterWindowMask | LeaveWindowMask | KeymapStateMask;  
392          if (sendmotion)          if (sendmotion)
393                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
   
394          if (ownbackstore)          if (ownbackstore)
395                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
396            if (fullscreen || grab_keyboard)
397                    input_mask |= EnterWindowMask;
398            if (grab_keyboard)
399                    input_mask |= LeaveWindowMask;
400    
401            if (IM != NULL)
402            {
403                    IC = XCreateIC(IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
404                                   XNClientWindow, wnd, XNFocusWindow, wnd, NULL);
405    
406                    if ((IC != NULL)
407                        && (XGetICValues(IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
408                            input_mask |= ic_input_mask;
409            }
410    
411          XSelectInput(display, wnd, input_mask);          XSelectInput(display, wnd, input_mask);
         gc = XCreateGC(display, wnd, 0, NULL);  
   
         if (ownbackstore)  
                 backstore = XCreatePixmap(display, wnd, width, height, depth);  
   
412          XMapWindow(display, wnd);          XMapWindow(display, wnd);
413    
414          /* TODO: error texts... make them friendly. */          /* wait for VisibilityNotify */
415          xkb = XkbGetKeyboard(display, XkbAllComponentsMask, XkbUseCoreKbd);          do
         if ((int)xkb == BadAlloc || xkb == NULL)  
         {  
                         error( "XkbGetKeyboard failed.\n");  
                         exit(0);  
         }  
   
         /* TODO: error texts... make them friendly. */  
         if( XkbSelectEvents(display, xkb->device_spec, XkbAllEventsMask, XkbAllEventsMask) == False )  
416          {          {
417                          error( "XkbSelectEvents failed.\n");                  XMaskEvent(display, VisibilityChangeMask, &xevent);
                         exit(0);  
418          }          }
419            while (xevent.type != VisibilityNotify);
420    
421            focused = False;
422            mouse_in_wnd = False;
423    
424          return True;          return True;
425  }  }
426    
427  void  void
428  ui_destroy_window()  ui_destroy_window(void)
429  {  {
430          if( xkb != NULL )          if (IC != NULL)
431                  XkbFreeKeyboard(xkb, XkbAllControlsMask, True);                  XDestroyIC(IC);
432    
         if (ownbackstore)  
                 XFreePixmap(display, backstore);  
   
         XFreeGC(display, gc);  
433          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
         XCloseDisplay(display);  
         display = NULL;  
434  }  }
435    
436    void
437    xwin_toggle_fullscreen(void)
438    {
439            Pixmap contents = 0;
440    
441            if (!ownbackstore)
442            {
443                    /* need to save contents of window */
444                    contents = XCreatePixmap(display, wnd, width, height, depth);
445                    XCopyArea(display, wnd, contents, gc, 0, 0, width, height, 0, 0);
446            }
447    
448            ui_destroy_window();
449            fullscreen = !fullscreen;
450            ui_create_window();
451    
452            XDefineCursor(display, wnd, current_cursor);
453    
454            if (!ownbackstore)
455            {
456                    XCopyArea(display, contents, wnd, gc, 0, 0, width, height, 0, 0);
457                    XFreePixmap(display, contents);
458            }
459    }
460    
461    /* Process all events in Xlib queue */
462  static void  static void
463  xwin_process_events()  xwin_process_events(void)
464  {  {
465          XkbEvent xkbevent;          XEvent xevent;
           
466          KeySym keysym;          KeySym keysym;
         uint8 scancode;  
467          uint16 button, flags;          uint16 button, flags;
468          uint32 ev_time;          uint32 ev_time;
469          uint32 tmpmods;          key_translation tr;
470            char str[256];
471            Status status;
472            unsigned int state;
473            Window wdummy;
474            int dummy;
475    
476          while (XCheckMaskEvent(display, ~0, &xkbevent.core))          while (XPending(display) > 0)
477          {          {
478                  ev_time = time(NULL);                  XNextEvent(display, &xevent);
                 flags = 0;  
479    
480                  switch (xkbevent.type)                  if ((IC != NULL) && (XFilterEvent(&xevent, None) == True))
481                  {                  {
482                          case KeymapNotify:                          DEBUG_KBD(("Filtering event\n"));
483                                  /* TODO:                          continue;
484                                   * read modifier status at focus in, and update the local masks, and the other end as well..                  }
                                  * if not, we may get out of sync.  
                                  * xkbevent.core.xkeymap.key_vector  
                                  * char key_vector[32];  
                                  */  
                                 break;  
485    
486                          case KeyRelease:                  flags = 0;
                                 flags = KBD_FLAG_DOWN | KBD_FLAG_UP;  
                                 /* fall through */  
487    
488                    switch (xevent.type)
489                    {
490                          case KeyPress:                          case KeyPress:
491                                  if( XkbTranslateKeyCode(xkb, xkbevent.core.xkey.keycode, xkbevent.core.xkey.state, &tmpmods, &keysym) == False )                                  if (IC != NULL)
492                                            /* Multi_key compatible version */
493                                    {
494                                            XmbLookupString(IC,
495                                                            (XKeyPressedEvent *) &
496                                                            xevent, str, sizeof(str), &keysym, &status);
497                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
498                                            {
499                                                    error("XmbLookupString failed with status 0x%x\n",
500                                                          status);
501                                                    break;
502                                            }
503                                    }
504                                    else
505                                    {
506                                            /* Plain old XLookupString */
507                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
508                                            XLookupString((XKeyEvent *) & xevent,
509                                                          str, sizeof(str), &keysym, NULL);
510                                    }
511    
512                                    DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
513                                               get_ksname(keysym)));
514    
515                                    ev_time = time(NULL);
516                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
517                                          break;                                          break;
                                 scancode = xkeymap_translate_key(keysym, xkbevent.core.xkey.keycode, &flags);  
518    
519                                  if (scancode == 0 )                                  tr = xkeymap_translate_key(keysym,
520                                                               xevent.xkey.keycode, xevent.xkey.state);
521    
522                                    if (tr.scancode == 0)
523                                          break;                                          break;
524    
525                                  /* keep track of the modifiers -- needed for stickykeys... */                                  ensure_remote_modifiers(ev_time, tr);
526                                  if( xkbevent.type == KeyPress )  
527                                          xwin_press_modifiers( &xkbevent.core.xkey, ev_time, scancode );                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
528                                    break;
529    
530                            case KeyRelease:
531                                    XLookupString((XKeyEvent *) & xevent, str,
532                                                  sizeof(str), &keysym, NULL);
533    
534                                    DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
535                                               get_ksname(keysym)));
536    
537                                    ev_time = time(NULL);
538                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
539                                            break;
540    
541                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, flags, scancode, 0);                                  tr = xkeymap_translate_key(keysym,
542                                                               xevent.xkey.keycode, xevent.xkey.state);
543    
544                                  if( xkbevent.type == KeyRelease )                                  if (tr.scancode == 0)
545                                          xwin_release_modifiers( &xkbevent.core.xkey, ev_time, scancode );                                          break;
546    
547                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
548                                  break;                                  break;
549    
550                          case ButtonPress:                          case ButtonPress:
# Line 441  xwin_process_events() Line 552  xwin_process_events()
552                                  /* fall through */                                  /* fall through */
553    
554                          case ButtonRelease:                          case ButtonRelease:
555                                  button = xkeymap_translate_button(xkbevent.core.xbutton.button);                                  button = xkeymap_translate_button(xevent.xbutton.button);
556                                  if (button == 0)                                  if (button == 0)
557                                          break;                                          break;
558    
559                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
560                                                 flags | button,                                                 flags | button, xevent.xbutton.x, xevent.xbutton.y);
                                                xkbevent.core.xbutton.x,  
                                                xkbevent.core.xbutton.y);  
561                                  break;                                  break;
562    
563                          case MotionNotify:                          case MotionNotify:
564                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
565                                                 MOUSE_FLAG_MOVE,                                                 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
566                                                 xkbevent.core.xmotion.x,                                  break;
567                                                 xkbevent.core.xmotion.y);  
568                            case FocusIn:
569                                    if (xevent.xfocus.mode == NotifyGrab)
570                                            break;
571                                    focused = True;
572                                    XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy,
573                                                  &dummy, &dummy, &state);
574                                    reset_modifier_keys(state);
575                                    if (grab_keyboard && mouse_in_wnd)
576                                            XGrabKeyboard(display, wnd, True,
577                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
578                                    break;
579    
580                            case FocusOut:
581                                    if (xevent.xfocus.mode == NotifyUngrab)
582                                            break;
583                                    focused = False;
584                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
585                                            XUngrabKeyboard(display, CurrentTime);
586                                  break;                                  break;
587    
588                          case EnterNotify:                          case EnterNotify:
589                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,                                  /* we only register for this event when in fullscreen mode */
590                                                GrabModeAsync, CurrentTime);                                  /* or grab_keyboard */
591                                    mouse_in_wnd = True;
592                                    if (fullscreen)
593                                    {
594                                            XSetInputFocus(display, wnd, RevertToPointerRoot,
595                                                           CurrentTime);
596                                            break;
597                                    }
598                                    if (focused)
599                                            XGrabKeyboard(display, wnd, True,
600                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
601                                  break;                                  break;
602    
603                          case LeaveNotify:                          case LeaveNotify:
604                                    /* we only register for this event when grab_keyboard */
605                                    mouse_in_wnd = False;
606                                  XUngrabKeyboard(display, CurrentTime);                                  XUngrabKeyboard(display, CurrentTime);
607                                  break;                                  break;
608    
609                          case Expose:                          case Expose:
610                                  XCopyArea(display, backstore, wnd, gc,                                  XCopyArea(display, backstore, wnd, gc,
611                                            xkbevent.core.xexpose.x, xkbevent.core.xexpose.y,                                            xevent.xexpose.x, xevent.xexpose.y,
612                                            xkbevent.core.xexpose.width, xkbevent.core.xexpose.height,                                            xevent.xexpose.width,
613                                            xkbevent.core.xexpose.x, xkbevent.core.xexpose.y);                                            xevent.xexpose.height,
614                                              xevent.xexpose.x, xevent.xexpose.y);
615                                  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;  
616    
617          switch (scancode) {                          case MappingNotify:
618          case 0x2a:                                  /* Refresh keyboard mapping if it has changed. This is important for
619                  key_down_state |= DShift1Mask;                                     Xvnc, since it allocates keycodes dynamically */
620                  break;                                  if (xevent.xmapping.request == MappingKeyboard
621          case 0x36:                                      || xevent.xmapping.request == MappingModifier)
622                  key_down_state |= DShift2Mask;                                          XRefreshKeyboardMapping(&xevent.xmapping);
                 break;  
         case 0x1d:  
                 key_down_state |= DControl1Mask;  
                 break;  
         case 0x9d:  
                 key_down_state |= DControl2Mask;  
                 break;  
         case 0x38:  
                 key_down_state |= DMod1Mask;  
                 break;  
         case 0xb8:  
                 key_down_state |= DMod2Mask;  
                 break;  
         }  
   
         if( (ShiftMask & ev->state) && !((key_down_state & DShift1Mask) || (key_down_state & DShift2Mask)))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x2a, 0);  
                 key_down_state |= DShift1Mask;  
   
         }  
   
         if( (ControlMask & ev->state) && !((key_down_state & DControl1Mask) || (key_down_state & DControl2Mask)))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x1d, 0);  
                 key_down_state |= DControl1Mask;  
623    
624          }                                  if (xevent.xmapping.request == MappingModifier)
625                                    {
626          if( (Mod1Mask & ev->state) && !(key_down_state & DMod1Mask))                                          XFreeModifiermap(mod_map);
627          {                                          mod_map = XGetModifierMapping(display);
628                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x38, 0);                                  }
629                  key_down_state |= DMod1Mask;                                  break;
   
         }  
   
         if( (Mod2Mask & ev->state) && !(key_down_state & DMod2Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0xb8, 0);  
                 key_down_state |= DMod2Mask;  
630    
631                    }
632          }          }
633  }  }
634    
635  void  void
636  ui_select(int rdp_socket)  ui_select(int rdp_socket)
637  {  {
638          int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
639          fd_set rfds;          fd_set rfds;
640    
641          FD_ZERO(&rfds);          FD_ZERO(&rfds);
642    
643          while (True)          while (True)
644          {          {
645                    /* Process any events already waiting */
646                    xwin_process_events();
647    
648                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
649                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
650                  if (display != NULL)                  FD_SET(x_socket, &rfds);
                 {  
                         FD_SET(x_socket, &rfds);  
                         XFlush(display);  
                 }  
651    
652                  switch (select(n, &rfds, NULL, NULL, NULL))                  switch (select(n, &rfds, NULL, NULL, NULL))
653                  {                  {
# Line 612  ui_select(int rdp_socket) Line 658  ui_select(int rdp_socket)
658                                  continue;                                  continue;
659                  }                  }
660    
                 if (FD_ISSET(x_socket, &rfds))  
                         xwin_process_events();  
   
661                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
662                          return;                          return;
663          }          }
# Line 627  ui_move_pointer(int x, int y) Line 670  ui_move_pointer(int x, int y)
670  }  }
671    
672  HBITMAP  HBITMAP
673  ui_create_bitmap(int width, int height, uint8 *data)  ui_create_bitmap(int width, int height, uint8 * data)
674  {  {
675          XImage *image;          XImage *image;
676          Pixmap bitmap;          Pixmap bitmap;
677          uint8 *tdata;          uint8 *tdata;
678    
679          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = translate_image(width, height, data);
680          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
681          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
682                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, 8, 0);
683    
684          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
685    
686          XFree(image);          XFree(image);
687          if (!owncolmap)          xfree(tdata);
                 xfree(tdata);  
688          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
689  }  }
690    
691  void  void
692  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)  
693  {  {
694          XImage *image;          XImage *image;
695          uint8 *tdata;          uint8 *tdata;
696    
697          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = translate_image(width, height, data);
698          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
699                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, 8, 0);
700    
701          if (ownbackstore)          if (ownbackstore)
702          {          {
# Line 668  ui_paint_bitmap(int x, int y, int cx, in Line 709  ui_paint_bitmap(int x, int y, int cx, in
709          }          }
710    
711          XFree(image);          XFree(image);
712          if (!owncolmap)          xfree(tdata);
                 xfree(tdata);  
713  }  }
714    
715  void  void
716  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
717  {  {
718          XFreePixmap(display, (Pixmap)bmp);          XFreePixmap(display, (Pixmap) bmp);
719  }  }
720    
721  HGLYPH  HGLYPH
722  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 * data)
723  {  {
724          XImage *image;          XImage *image;
725          Pixmap bitmap;          Pixmap bitmap;
# Line 691  ui_create_glyph(int width, int height, u Line 731  ui_create_glyph(int width, int height, u
731          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
732          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
733    
734          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
735                               data, width, height, 8, scanline);                               width, height, 8, scanline);
736          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
737          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
738          XInitImage(image);          XInitImage(image);
# Line 701  ui_create_glyph(int width, int height, u Line 741  ui_create_glyph(int width, int height, u
741    
742          XFree(image);          XFree(image);
743          XFreeGC(display, gc);          XFreeGC(display, gc);
744          return (HGLYPH)bitmap;          return (HGLYPH) bitmap;
745  }  }
746    
747  void  void
748  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
749  {  {
750          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(display, (Pixmap) glyph);
751  }  }
752    
753  HCURSOR  HCURSOR
754  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
755                   int height, uint8 *andmask, uint8 *xormask)                   uint8 * andmask, uint8 * xormask)
756  {  {
757          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
758          XColor bg, fg;          XColor bg, fg;
# Line 769  ui_create_cursor(unsigned int x, unsigne Line 809  ui_create_cursor(unsigned int x, unsigne
809    
810          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
811          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
812            
813          xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,          xcursor =
814                                  (Pixmap)maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(display, (Pixmap) cursorglyph,
815                                        (Pixmap) maskglyph, &fg, &bg, x, y);
816    
817          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
818          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
819          xfree(mask);          xfree(mask);
820          xfree(cursor);          xfree(cursor);
821          return (HCURSOR)xcursor;          return (HCURSOR) xcursor;
822  }  }
823    
824  void  void
825  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
826  {  {
827          XDefineCursor(display, wnd, (Cursor)cursor);          current_cursor = (Cursor) cursor;
828            XDefineCursor(display, wnd, current_cursor);
829  }  }
830    
831  void  void
832  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
833  {  {
834          XFreeCursor(display, (Cursor)cursor);          XFreeCursor(display, (Cursor) cursor);
835  }  }
836    
837  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 799  ui_destroy_cursor(HCURSOR cursor) Line 841  ui_destroy_cursor(HCURSOR cursor)
841                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
842    
843  HCOLOURMAP  HCOLOURMAP
844  ui_create_colourmap(COLOURMAP *colours)  ui_create_colourmap(COLOURMAP * colours)
845  {  {
846          COLOURENTRY *entry;          COLOURENTRY *entry;
847          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
848            uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
849          if (owncolmap)          XColor xentry;
850            XColor xc_cache[256];
851            uint32 colour;
852            int colLookup = 256;
853            for (i = 0; i < ncolours; i++)
854          {          {
855                  XColor *xcolours, *xentry;                  entry = &colours->colours[i];
856                  Colormap map;                  MAKE_XCOLOR(&xentry, entry);
857    
858                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  if (XAllocColor(display, xcolmap, &xentry) == 0)
                 for (i = 0; i < ncolours; i++)  
859                  {                  {
860                          entry = &colours->colours[i];                          /* Allocation failed, find closest match. */
861                          xentry = &xcolours[i];                          int j = 256;
862                          xentry->pixel = i;                          int nMinDist = 3 * 256 * 256;
863                          MAKE_XCOLOR(xentry, entry);                          long nDist = nMinDist;
                 }  
864    
865                  map = XCreateColormap(display, wnd, visual, AllocAll);                          /* only get the colors once */
866                  XStoreColors(display, map, xcolours, ncolours);                          while (colLookup--)
867                            {
868                                    xc_cache[colLookup].pixel = colLookup;
869                                    xc_cache[colLookup].red = xc_cache[colLookup].green =
870                                            xc_cache[colLookup].blue = 0;
871                                    xc_cache[colLookup].flags = 0;
872                                    XQueryColor(display,
873                                                DefaultColormap(display, DefaultScreen(display)),
874                                                &xc_cache[colLookup]);
875                            }
876                            colLookup = 0;
877    
878                  xfree(xcolours);                          /* approximate the pixel */
879                  return (HCOLOURMAP)map;                          while (j--)
880          }                          {
881          else                                  if (xc_cache[j].flags)
882          {                                  {
883                  uint32 *map = xmalloc(sizeof(*colmap) * ncolours);                                          nDist = ((long) (xc_cache[j].red >> 8) -
884                  XColor xentry;                                                   (long) (xentry.red >> 8)) *
885                  uint32 colour;                                                  ((long) (xc_cache[j].red >> 8) -
886                                                     (long) (xentry.red >> 8)) +
887                                                    ((long) (xc_cache[j].green >> 8) -
888                                                     (long) (xentry.green >> 8)) *
889                                                    ((long) (xc_cache[j].green >> 8) -
890                                                     (long) (xentry.green >> 8)) +
891                                                    ((long) (xc_cache[j].blue >> 8) -
892                                                     (long) (xentry.blue >> 8)) *
893                                                    ((long) (xc_cache[j].blue >> 8) -
894                                                     (long) (xentry.blue >> 8));
895                                    }
896                                    if (nDist < nMinDist)
897                                    {
898                                            nMinDist = nDist;
899                                            xentry.pixel = j;
900                                    }
901                            }
902                    }
903                    colour = xentry.pixel;
904    
905                  for (i = 0; i < ncolours; i++)                  /* update our cache */
906                    if (xentry.pixel < 256)
907                  {                  {
908                          entry = &colours->colours[i];                          xc_cache[xentry.pixel].red = xentry.red;
909                          MAKE_XCOLOR(&xentry, entry);                          xc_cache[xentry.pixel].green = xentry.green;
910                            xc_cache[xentry.pixel].blue = xentry.blue;
911    
                         if (XAllocColor(display, xcolmap, &xentry) != 0)  
                                 colour = xentry.pixel;  
                         else  
                                 colour = white;  
   
                         /* byte swap here to make translate_image faster */  
                         map[i] = translate_colour(colour);  
912                  }                  }
913    
914                  return map;  
915                    /* byte swap here to make translate_image faster */
916                    map[i] = translate_colour(colour);
917          }          }
918    
919            return map;
920  }  }
921    
922  void  void
923  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
924  {  {
925          if (owncolmap)          xfree(map);
                 XFreeColormap(display, (Colormap)map);  
         else  
                 xfree(map);  
926  }  }
927    
928  void  void
929  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
930  {  {
931          if (owncolmap)          colmap = map;
                 XSetWindowColormap(display, wnd, (Colormap)map);  
         else  
                 colmap = map;  
932  }  }
933    
934  void  void
# Line 879  ui_set_clip(int x, int y, int cx, int cy Line 944  ui_set_clip(int x, int y, int cx, int cy
944  }  }
945    
946  void  void
947  ui_reset_clip()  ui_reset_clip(void)
948  {  {
949          XRectangle rect;          XRectangle rect;
950    
# Line 891  ui_reset_clip() Line 956  ui_reset_clip()
956  }  }
957    
958  void  void
959  ui_bell()  ui_bell(void)
960  {  {
961          XBell(display, 0);          XBell(display, 0);
962  }  }
# Line 908  ui_destblt(uint8 opcode, Line 973  ui_destblt(uint8 opcode,
973  void  void
974  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
975            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
976            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
977  {  {
978          Pixmap fill;          Pixmap fill;
979            uint8 i, ipattern[8];
980    
981          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
982    
# Line 922  ui_patblt(uint8 opcode, Line 988  ui_patblt(uint8 opcode,
988                          break;                          break;
989    
990                  case 3: /* Pattern */                  case 3: /* Pattern */
991                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);                          for (i = 0; i != 8; i++)
992                                    ipattern[7 - i] = brush->pattern[i];
993                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
994    
995                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
996                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
# Line 933  ui_patblt(uint8 opcode, Line 1001  ui_patblt(uint8 opcode,
1001                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1002    
1003                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
1004                          ui_destroy_glyph((HGLYPH)fill);                          XSetTSOrigin(display, gc, 0, 0);
1005                            ui_destroy_glyph((HGLYPH) fill);
1006                          break;                          break;
1007    
1008                  default:                  default:
# Line 951  ui_screenblt(uint8 opcode, Line 1020  ui_screenblt(uint8 opcode,
1020          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1021          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1022          if (ownbackstore)          if (ownbackstore)
1023                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1024          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1025  }  }
1026    
# Line 962  ui_memblt(uint8 opcode, Line 1030  ui_memblt(uint8 opcode,
1030            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1031  {  {
1032          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1033          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1034          if (ownbackstore)          if (ownbackstore)
1035                  XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1036          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1037  }  }
1038    
# Line 973  void Line 1040  void
1040  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
1041            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1042            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ HBITMAP src, int srcx, int srcy,
1043            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1044  {  {
1045          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
1046             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 982  ui_triblt(uint8 opcode, Line 1049  ui_triblt(uint8 opcode,
1049          {          {
1050                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1051                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1052                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1053                          break;                          break;
1054    
1055                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1056                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1057                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1058                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1059                          break;                          break;
1060    
1061                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1062                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1063                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1064                          break;                          break;
1065    
1066                  default:                  default:
# Line 1009  ui_triblt(uint8 opcode, Line 1072  ui_triblt(uint8 opcode,
1072  void  void
1073  ui_line(uint8 opcode,  ui_line(uint8 opcode,
1074          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
1075          /* pen */ PEN *pen)          /* pen */ PEN * pen)
1076  {  {
1077          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1078          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
# Line 1031  ui_rect( Line 1094  ui_rect(
1094  void  void
1095  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1096                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1097                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1098                int fgcolour)                int bgcolour, int fgcolour)
1099  {  {
1100          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1101          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1102    
1103          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(display, gc,
1104                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1105          XSetStipple(display, gc, (Pixmap)glyph);          XSetStipple(display, gc, (Pixmap) glyph);
1106          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
1107    
1108          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
# Line 1056  ui_draw_glyph(int mixmode, Line 1119  ui_draw_glyph(int mixmode,
1119        if ((xyoffset & 0x80))\        if ((xyoffset & 0x80))\
1120          {\          {\
1121            if (flags & TEXT2_VERTICAL) \            if (flags & TEXT2_VERTICAL) \
1122              y += ttext[++idx] | (ttext[++idx] << 8);\              y += ttext[idx+1] | (ttext[idx+2] << 8);\
1123            else\            else\
1124              x += ttext[++idx] | (ttext[++idx] << 8);\              x += ttext[idx+1] | (ttext[idx+2] << 8);\
1125              idx += 2;\
1126          }\          }\
1127        else\        else\
1128          {\          {\
# Line 1081  ui_draw_glyph(int mixmode, Line 1145  ui_draw_glyph(int mixmode,
1145    
1146  void  void
1147  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,
1148               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1149               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1150               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1151  {  {
1152          FONTGLYPH *glyph;          FONTGLYPH *glyph;
# Line 1101  ui_draw_text(uint8 font, uint8 flags, in Line 1165  ui_draw_text(uint8 font, uint8 flags, in
1165          }          }
1166    
1167          /* Paint text, character by character */          /* Paint text, character by character */
1168          for (i = 0; i < length;) {          for (i = 0; i < length;)
1169                  switch (text[i]) {          {
1170                  case 0xff:                  switch (text[i])
1171                          if (i + 2 < length)                  {
1172                                  cache_put_text(text[i + 1], text, text[i + 2]);                          case 0xff:
1173                          else {                                  if (i + 2 < length)
1174                                  error("this shouldn't be happening\n");                                          cache_put_text(text[i + 1], text, text[i + 2]);
1175                                    else
1176                                    {
1177                                            error("this shouldn't be happening\n");
1178                                            break;
1179                                    }
1180                                    /* this will move pointer from start to first character after FF command */
1181                                    length -= i + 3;
1182                                    text = &(text[i + 3]);
1183                                    i = 0;
1184                                  break;                                  break;
                         }  
                         /* this will move pointer from start to first character after FF command */  
                         length -= i + 3;  
                         text = &(text[i + 3]);  
                         i = 0;  
                         break;  
1185    
1186                  case 0xfe:                          case 0xfe:
1187                          entry = cache_get_text(text[i + 1]);                                  entry = cache_get_text(text[i + 1]);
1188                          if (entry != NULL) {                                  if (entry != NULL)
1189                                  if ((((uint8 *) (entry->data))[1] == 0)                                  {
1190                                      && (!(flags & TEXT2_IMPLICIT_X))) {                                          if ((((uint8 *) (entry->data))[1] ==
1191                                          if (flags & TEXT2_VERTICAL)                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
1192                                                  y += text[i + 2];                                          {
1193                                                    if (flags & TEXT2_VERTICAL)
1194                                                            y += text[i + 2];
1195                                                    else
1196                                                            x += text[i + 2];
1197                                            }
1198                                            if (i + 2 < length)
1199                                                    i += 3;
1200                                          else                                          else
1201                                                  x += text[i + 2];                                                  i += 2;
1202                                            length -= i;
1203                                            /* this will move pointer from start to first character after FE command */
1204                                            text = &(text[i]);
1205                                            i = 0;
1206                                            for (j = 0; j < entry->size; j++)
1207                                                    DO_GLYPH(((uint8 *) (entry->data)), j);
1208                                  }                                  }
1209                                  if (i + 2 < length)                                  break;
                                         i += 3;  
                                 else  
                                         i += 2;  
                                 length -= i;  
                                 /* this will move pointer from start to first character after FE command */  
                                 text = &(text[i]);  
                                 i = 0;  
                                 for (j = 0; j < entry->size; j++)  
                                         DO_GLYPH(((uint8 *) (entry->data)), j);  
                         }  
                         break;  
1210    
1211                  default:                          default:
1212                          DO_GLYPH(text, i);                                  DO_GLYPH(text, i);
1213                          i++;                                  i++;
1214                          break;                                  break;
1215                  }                  }
1216          }          }
1217    
# Line 1157  ui_desktop_save(uint32 offset, int x, in Line 1226  ui_desktop_save(uint32 offset, int x, in
1226    
1227          if (ownbackstore)          if (ownbackstore)
1228          {          {
1229                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1230          }          }
1231          else          else
1232          {          {
1233                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(display, wnd, cx, cy, depth);
1234                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1235                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1236                  XFreePixmap(display, pix);                  XFreePixmap(display, pix);
1237          }          }
1238    
1239          offset *= bpp/8;          offset *= bpp / 8;
1240          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line, bpp / 8, (uint8 *) image->data);
                           bpp/8, (uint8 *)image->data);  
1241    
1242          XDestroyImage(image);          XDestroyImage(image);
1243  }  }
# Line 1182  ui_desktop_restore(uint32 offset, int x, Line 1248  ui_desktop_restore(uint32 offset, int x,
1248          XImage *image;          XImage *image;
1249          uint8 *data;          uint8 *data;
1250    
1251          offset *= bpp/8;          offset *= bpp / 8;
1252          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp / 8);
1253          if (data == NULL)          if (data == NULL)
1254                  return;                  return;
1255    
1256          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1257                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);
                              cx * bpp/8);  
1258    
1259          if (ownbackstore)          if (ownbackstore)
1260          {          {

Legend:
Removed from v.53  
changed lines
  Added in v.262

  ViewVC Help
Powered by ViewVC 1.1.26