/[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 64 by astrand, Thu Jul 18 16:38:31 2002 UTC revision 263 by astrand, Mon Nov 18 18:12:49 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 numlock_modifier_mask = 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    {
64  #define DShift1Mask   (1<<0)          unsigned long flags;
65  #define DLockMask     (1<<1)          unsigned long functions;
66  #define DControl1Mask (1<<2)          unsigned long decorations;
67  #define DMod1Mask     (1<<3)          long inputMode;
68  #define DMod2Mask     (1<<4)          unsigned long status;
69  #define DMod3Mask     (1<<5)  }
70  #define DMod4Mask     (1<<6)  PropMotifWmHints;
71  #define DMod5Mask     (1<<7)  
 #define DShift2Mask   (1<<8)  
 #define DControl2Mask (1<<9)  
 #define DNumLockMask  (1<<10)  
72    
73  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
74  { \  { \
# Line 74  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 105  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_get_numlock_mask();  void
110  void xwin_mod_update(uint32 state, uint32 ev_time);  mwm_hide_decorations(void)
111  void xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode);  {
112  void xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode);          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)
# Line 205  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;
         XSizeHints *sizehints;  
         unsigned long input_mask;  
         XPixmapFormatValues *pfm;  
         Screen *screen;  
         uint16 test;  
         int i;  
230    
231          int xkb_minor, xkb_major;          KeyCode keycode = XKeysymToKeycode(display, keysym);
         int xkb_event, xkb_error, xkb_reason;  
232    
233          /* compare compiletime libs with runtime libs. */          if (keycode == NoSymbol)
         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");  
234                  return False;                  return False;
         }  
235    
236            for (modifierpos = 0; modifierpos < 8; modifierpos++)
         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 269  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 285  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    
301          white = WhitePixelOfScreen(screen);          if ((width == 0) || (height == 0))
302          attribs.background_pixel = BlackPixelOfScreen(screen);          {
303          attribs.backing_store = DoesBackingStore(screen);                  /* Fetch geometry from _NET_WORKAREA */
304                    uint32 xpos, ypos;
305    
306          if (attribs.backing_store == NotUseful)                  if (get_current_workarea(&xpos, &ypos, &width, &height) < 0)
307                  ownbackstore = True;                  {
308                            error("Failed to get workarea.\n");
309                            error("Perhaps your window manager does not support EWMH?\n");
310                            exit(1);
311                    }
312            }
313    
314          if (fullscreen)          if (fullscreen)
315          {          {
                 attribs.override_redirect = True;  
316                  width = WidthOfScreen(screen);                  width = WidthOfScreen(screen);
317                  height = HeightOfScreen(screen);                  height = HeightOfScreen(screen);
318          }          }
319          else  
320            /* make sure width is a multiple of 4 */
321            width = (width + 3) & ~3;
322    
323            if (ownbackstore)
324          {          {
325                  attribs.override_redirect = False;                  backstore =
326                            XCreatePixmap(display, RootWindowOfScreen(screen), width, height, depth);
327    
328                    /* clear to prevent rubbish being exposed at startup */
329                    XSetForeground(display, gc, BlackPixelOfScreen(screen));
330                    XFillRectangle(display, backstore, gc, 0, 0, width, height);
331          }          }
332    
333          width = (width + 3) & ~3;       /* make width a multiple of 32 bits */          mod_map = XGetModifierMapping(display);
334    
335            if (enable_compose)
336                    IM = XOpenIM(display, NULL, NULL, NULL);
337    
338            xkeymap_init();
339            return True;
340    }
341    
342    void
343    ui_deinit(void)
344    {
345            if (IM != NULL)
346                    XCloseIM(IM);
347    
348            XFreeModifiermap(mod_map);
349    
350          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          if (ownbackstore)
351                              0, 0, width, height, 0, CopyFromParent,                  XFreePixmap(display, backstore);
352                              InputOutput, CopyFromParent,  
353                              CWBackingStore | CWBackPixel | CWOverrideRedirect,          XFreeGC(display, gc);
354                              &attribs);          XCloseDisplay(display);
355            display = NULL;
356    }
357    
358    BOOL
359    ui_create_window(void)
360    {
361            XSetWindowAttributes attribs;
362            XClassHint *classhints;
363            XSizeHints *sizehints;
364            int wndwidth, wndheight;
365            long input_mask, ic_input_mask;
366            XEvent xevent;
367    
368            wndwidth = fullscreen ? WidthOfScreen(screen) : width;
369            wndheight = fullscreen ? HeightOfScreen(screen) : height;
370    
371            attribs.background_pixel = BlackPixelOfScreen(screen);
372            attribs.backing_store = ownbackstore ? NotUseful : Always;
373            attribs.override_redirect = fullscreen;
374    
375            wnd = XCreateWindow(display, RootWindowOfScreen(screen), 0, 0, wndwidth, wndheight,
376                                0, CopyFromParent, InputOutput, CopyFromParent,
377                                CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);
378    
379          XStoreName(display, wnd, title);          XStoreName(display, wnd, title);
380    
381            if (hide_decorations)
382                    mwm_hide_decorations();
383    
384          classhints = XAllocClassHint();          classhints = XAllocClassHint();
385          if (classhints != NULL)          if (classhints != NULL)
386          {          {
# Line 340  ui_create_window(char *title) Line 399  ui_create_window(char *title)
399                  XFree(sizehints);                  XFree(sizehints);
400          }          }
401    
402          xkeymap_init();          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
403                    VisibilityChangeMask | FocusChangeMask;
404    
         input_mask = KeyPressMask | KeyReleaseMask |  
                 ButtonPressMask | ButtonReleaseMask |  
                 EnterWindowMask | LeaveWindowMask;  
405          if (sendmotion)          if (sendmotion)
406                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
   
407          if (ownbackstore)          if (ownbackstore)
408                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
409            if (fullscreen || grab_keyboard)
410                    input_mask |= EnterWindowMask;
411            if (grab_keyboard)
412                    input_mask |= LeaveWindowMask;
413    
414            if (IM != NULL)
415            {
416                    IC = XCreateIC(IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
417                                   XNClientWindow, wnd, XNFocusWindow, wnd, NULL);
418    
419                    if ((IC != NULL)
420                        && (XGetICValues(IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
421                            input_mask |= ic_input_mask;
422            }
423    
424          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);  
   
425          XMapWindow(display, wnd);          XMapWindow(display, wnd);
426    
427          /* TODO: error texts... make them friendly. */          /* wait for VisibilityNotify */
428          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)  
429          {          {
430                  error("XkbSelectEvents failed.\n");                  XMaskEvent(display, VisibilityChangeMask, &xevent);
                 exit(0);  
431          }          }
432            while (xevent.type != VisibilityNotify);
433    
434          xwin_get_numlock_mask();          focused = False;
435            mouse_in_wnd = False;
436    
437          return True;          return True;
438  }  }
439    
440  void  void
441  xwin_get_numlock_mask()  ui_destroy_window(void)
442  {  {
443          KeyCode numlockcode;          if (IC != NULL)
444          KeyCode *keycode;                  XDestroyIC(IC);
         XModifierKeymap *modmap;  
         int i, j;  
   
         /* Find out if numlock is already defined as a modifier key, and if so where */  
         numlockcode = XKeysymToKeycode(display, 0xFF7F);        /* XF_Num_Lock = 0xFF7F */  
         if (numlockcode)  
         {  
                 modmap = XGetModifierMapping(display);  
                 if (modmap)  
                 {  
                         keycode = modmap->modifiermap;  
                         for (i = 0; i < 8; i++)  
                                 for (j = modmap->max_keypermod; j--;)  
                                 {  
                                         if (*keycode == numlockcode)  
                                         {  
                                                 numlock_modifier_mask =  
                                                         (1 << i);  
                                                 i = 8;  
                                                 break;  
                                         }  
                                         keycode++;  
                                 }  
                         if (!numlock_modifier_mask)  
                         {  
                                 modmap->modifiermap[7 *  
                                                     modmap->max_keypermod] =  
                                         numlockcode;  
                                 if (XSetModifierMapping(display, modmap) ==  
                                     MappingSuccess)  
                                         numlock_modifier_mask = (1 << 7);  
                                 else  
                                         printf("XSetModifierMapping failed!\n");  
                         }  
                         XFreeModifiermap(modmap);  
                 }  
         }  
   
         if (!numlock_modifier_mask)  
                 printf("WARNING: Failed to get a numlock modifier mapping.\n");  
445    
446            XDestroyWindow(display, wnd);
447  }  }
448    
449  void  void
450  ui_destroy_window()  xwin_toggle_fullscreen(void)
451  {  {
452          if (xkb != NULL)          Pixmap contents = 0;
                 XkbFreeKeyboard(xkb, XkbAllControlsMask, True);  
453    
454          if (ownbackstore)          if (!ownbackstore)
455                  XFreePixmap(display, backstore);          {
456                    /* need to save contents of window */
457                    contents = XCreatePixmap(display, wnd, width, height, depth);
458                    XCopyArea(display, wnd, contents, gc, 0, 0, width, height, 0, 0);
459            }
460    
461          XFreeGC(display, gc);          ui_destroy_window();
462          XDestroyWindow(display, wnd);          fullscreen = !fullscreen;
463          XCloseDisplay(display);          ui_create_window();
464          display = NULL;  
465            XDefineCursor(display, wnd, current_cursor);
466    
467            if (!ownbackstore)
468            {
469                    XCopyArea(display, contents, wnd, gc, 0, 0, width, height, 0, 0);
470                    XFreePixmap(display, contents);
471            }
472  }  }
473    
474    /* Process all events in Xlib queue */
475  static void  static void
476  xwin_process_events()  xwin_process_events(void)
477  {  {
478          XEvent xevent;          XEvent xevent;
   
479          KeySym keysym;          KeySym keysym;
         uint8 scancode;  
480          uint16 button, flags;          uint16 button, flags;
481          uint32 ev_time;          uint32 ev_time;
482          uint32 tmpmods;          key_translation tr;
483            char str[256];
484            Status status;
485            unsigned int state;
486            Window wdummy;
487            int dummy;
488    
489          while (XCheckMaskEvent(display, ~0, &xevent))          while (XPending(display) > 0)
490          {          {
491                  ev_time = time(NULL);                  XNextEvent(display, &xevent);
492    
493                    if ((IC != NULL) && (XFilterEvent(&xevent, None) == True))
494                    {
495                            DEBUG_KBD(("Filtering event\n"));
496                            continue;
497                    }
498    
499                  flags = 0;                  flags = 0;
500    
501                  switch (xevent.type)                  switch (xevent.type)
502                  {                  {
                         case KeyRelease:  
                                 flags = KBD_FLAG_DOWN | KBD_FLAG_UP;  
                                 /* fall through */  
503                          case KeyPress:                          case KeyPress:
504                                  if (XkbTranslateKeyCode                                  if (IC != NULL)
505                                      (xkb, xevent.xkey.keycode,                                          /* Multi_key compatible version */
506                                       xevent.xkey.state, &tmpmods,                                  {
507                                       &keysym) == False)                                          XmbLookupString(IC,
508                                                            (XKeyPressedEvent *) &
509                                                            xevent, str, sizeof(str), &keysym, &status);
510                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
511                                            {
512                                                    error("XmbLookupString failed with status 0x%x\n",
513                                                          status);
514                                                    break;
515                                            }
516                                    }
517                                    else
518                                    {
519                                            /* Plain old XLookupString */
520                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
521                                            XLookupString((XKeyEvent *) & xevent,
522                                                          str, sizeof(str), &keysym, NULL);
523                                    }
524    
525                                    DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
526                                               get_ksname(keysym)));
527    
528                                    ev_time = time(NULL);
529                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
530                                            break;
531    
532                                    tr = xkeymap_translate_key(keysym,
533                                                               xevent.xkey.keycode, xevent.xkey.state);
534    
535                                    if (tr.scancode == 0)
536                                          break;                                          break;
                                 scancode =  
                                         xkeymap_translate_key(keysym,  
                                                               xevent.xkey.  
                                                               keycode,  
                                                               &flags);  
537    
538                                  if (scancode == 0)                                  ensure_remote_modifiers(ev_time, tr);
539    
540                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
541                                    break;
542    
543                            case KeyRelease:
544                                    XLookupString((XKeyEvent *) & xevent, str,
545                                                  sizeof(str), &keysym, NULL);
546    
547                                    DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
548                                               get_ksname(keysym)));
549    
550                                    ev_time = time(NULL);
551                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
552                                          break;                                          break;
553    
554                                  /* keep track of the modifiers -- needed for stickykeys... */                                  tr = xkeymap_translate_key(keysym,
555                                  if (xevent.type == KeyPress)                                                             xevent.xkey.keycode, xevent.xkey.state);
                                         xwin_mod_press(xevent.xkey.state,  
                                                        ev_time, scancode);  
   
                                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                                flags, scancode, 0);  
   
                                 if (xevent.type == KeyRelease)  
                                         xwin_mod_release(xevent.xkey.state,  
                                                          ev_time, scancode);  
556    
557                                    if (tr.scancode == 0)
558                                            break;
559    
560                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
561                                  break;                                  break;
562    
563                          case ButtonPress:                          case ButtonPress:
# Line 499  xwin_process_events() Line 565  xwin_process_events()
565                                  /* fall through */                                  /* fall through */
566    
567                          case ButtonRelease:                          case ButtonRelease:
568                                  button = xkeymap_translate_button(xevent.                                  button = xkeymap_translate_button(xevent.xbutton.button);
                                                                   xbutton.  
                                                                   button);  
569                                  if (button == 0)                                  if (button == 0)
570                                          break;                                          break;
571    
572                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
573                                                 flags | button,                                                 flags | button, xevent.xbutton.x, xevent.xbutton.y);
                                                xevent.xbutton.x,  
                                                xevent.xbutton.y);  
574                                  break;                                  break;
575    
576                          case MotionNotify:                          case MotionNotify:
577                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
578                                                 MOUSE_FLAG_MOVE,                                                 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
                                                xevent.xmotion.x,  
                                                xevent.xmotion.y);  
579                                  break;                                  break;
580    
581                          case EnterNotify:                          case FocusIn:
582                                  XGrabKeyboard(display, wnd, True,                                  if (xevent.xfocus.mode == NotifyGrab)
583                                                GrabModeAsync, GrabModeAsync,                                          break;
584                                                CurrentTime);                                  focused = True;
585                                    XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy,
586                                                  &dummy, &dummy, &state);
587                                    reset_modifier_keys(state);
588                                    if (grab_keyboard && mouse_in_wnd)
589                                            XGrabKeyboard(display, wnd, True,
590                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
591                                    break;
592    
593                            case FocusOut:
594                                    if (xevent.xfocus.mode == NotifyUngrab)
595                                            break;
596                                    focused = False;
597                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
598                                            XUngrabKeyboard(display, CurrentTime);
599                                    break;
600    
601                                  xwin_mod_update(xevent.xcrossing.state,                          case EnterNotify:
602                                                  ev_time);                                  /* we only register for this event when in fullscreen mode */
603                                    /* or grab_keyboard */
604                                    mouse_in_wnd = True;
605                                    if (fullscreen)
606                                    {
607                                            XSetInputFocus(display, wnd, RevertToPointerRoot,
608                                                           CurrentTime);
609                                            break;
610                                    }
611                                    if (focused)
612                                            XGrabKeyboard(display, wnd, True,
613                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
614                                  break;                                  break;
615    
616                          case LeaveNotify:                          case LeaveNotify:
617                                    /* we only register for this event when grab_keyboard */
618                                    mouse_in_wnd = False;
619                                  XUngrabKeyboard(display, CurrentTime);                                  XUngrabKeyboard(display, CurrentTime);
620                                  break;                                  break;
621    
# Line 538  xwin_process_events() Line 626  xwin_process_events()
626                                            xevent.xexpose.height,                                            xevent.xexpose.height,
627                                            xevent.xexpose.x, xevent.xexpose.y);                                            xevent.xexpose.x, xevent.xexpose.y);
628                                  break;                                  break;
                 }  
         }  
 }  
   
 void  
 xwin_mod_update(uint32 state, uint32 ev_time)  
 {  
         xwin_mod_press(state, ev_time, 0);  
         xwin_mod_release(state, ev_time, 0);  
 }  
   
 void  
 xwin_mod_release(uint32 state, 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 (!(numlock_modifier_mask & state)  
             && (key_down_state & DNumLockMask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);  
                 key_down_state &= ~DNumLockMask;  
         }  
   
         if (!(LockMask & state) && (key_down_state & DLockMask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);  
                 key_down_state &= ~DLockMask;  
   
         }  
   
   
         if (!(ShiftMask & state) && (key_down_state & DShift1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a,  
                                0);  
                 key_down_state &= ~DShift1Mask;  
   
         }  
   
         if (!(ControlMask & state) && (key_down_state & DControl1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d,  
                                0);  
                 key_down_state &= ~DControl1Mask;  
   
         }  
   
         if (!(Mod1Mask & state) && (key_down_state & DMod1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38,  
                                0);  
                 key_down_state &= ~DMod1Mask;  
   
         }  
   
         if (!(Mod2Mask & state) && (key_down_state & DMod2Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8,  
                                0);  
                 key_down_state &= ~DMod2Mask;  
         }  
 }  
   
   
 void  
 xwin_mod_press(uint32 state, 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 0x3a:  
                         key_down_state ^= DLockMask;  
                         break;  
                 case 0x45:  
                         key_down_state ^= DNumLockMask;  
                         break;  
                 case 0x38:  
                         key_down_state |= DMod1Mask;  
                         break;  
                 case 0xb8:  
                         key_down_state |= DMod2Mask;  
                         break;  
         }  
   
         if ((numlock_modifier_mask && state)  
             && !(key_down_state & DNumLockMask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);  
                 key_down_state |= DNumLockMask;  
         }  
   
         if ((LockMask & state) && !(key_down_state & DLockMask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);  
                 key_down_state |= DLockMask;  
   
         }  
   
   
         if ((ShiftMask & 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 & state)  
             && !((key_down_state & DControl1Mask)  
                  || (key_down_state & DControl2Mask)))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,  
                                0x1d, 0);  
                 key_down_state |= DControl1Mask;  
   
         }  
   
         if ((Mod1Mask & state) && !(key_down_state & DMod1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,  
                                0x38, 0);  
                 key_down_state |= DMod1Mask;  
629    
630          }                          case MappingNotify:
631                                    /* Refresh keyboard mapping if it has changed. This is important for
632                                       Xvnc, since it allocates keycodes dynamically */
633                                    if (xevent.xmapping.request == MappingKeyboard
634                                        || xevent.xmapping.request == MappingModifier)
635                                            XRefreshKeyboardMapping(&xevent.xmapping);
636    
637          if ((Mod2Mask & state) && !(key_down_state & DMod2Mask))                                  if (xevent.xmapping.request == MappingModifier)
638          {                                  {
639                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,                                          XFreeModifiermap(mod_map);
640                                 0xb8, 0);                                          mod_map = XGetModifierMapping(display);
641                  key_down_state |= DMod2Mask;                                  }
642                                    break;
643    
644                    }
645          }          }
646  }  }
647    
# Line 724  ui_select(int rdp_socket) Line 655  ui_select(int rdp_socket)
655    
656          while (True)          while (True)
657          {          {
658                    /* Process any events already waiting */
659                    xwin_process_events();
660    
661                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
662                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
663                  if (display != NULL)                  FD_SET(x_socket, &rfds);
                 {  
                         FD_SET(x_socket, &rfds);  
                         XFlush(display);  
                 }  
664    
665                  switch (select(n, &rfds, NULL, NULL, NULL))                  switch (select(n, &rfds, NULL, NULL, NULL))
666                  {                  {
# Line 741  ui_select(int rdp_socket) Line 671  ui_select(int rdp_socket)
671                                  continue;                                  continue;
672                  }                  }
673    
                 if (FD_ISSET(x_socket, &rfds))  
                         xwin_process_events();  
   
674                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
675                          return;                          return;
676          }          }
# Line 762  ui_create_bitmap(int width, int height, Line 689  ui_create_bitmap(int width, int height,
689          Pixmap bitmap;          Pixmap bitmap;
690          uint8 *tdata;          uint8 *tdata;
691    
692          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = translate_image(width, height, data);
693          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
694          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
695                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, 8, 0);
696    
697          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
698    
699          XFree(image);          XFree(image);
700          if (!owncolmap)          xfree(tdata);
                 xfree(tdata);  
701          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
702  }  }
703    
704  void  void
705  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)  
706  {  {
707          XImage *image;          XImage *image;
708          uint8 *tdata;          uint8 *tdata;
709    
710          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = translate_image(width, height, data);
711          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
712                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, 8, 0);
713    
714          if (ownbackstore)          if (ownbackstore)
715          {          {
# Line 797  ui_paint_bitmap(int x, int y, int cx, in Line 722  ui_paint_bitmap(int x, int y, int cx, in
722          }          }
723    
724          XFree(image);          XFree(image);
725          if (!owncolmap)          xfree(tdata);
                 xfree(tdata);  
726  }  }
727    
728  void  void
# Line 820  ui_create_glyph(int width, int height, u Line 744  ui_create_glyph(int width, int height, u
744          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
745          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
746    
747          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
748                               data, width, height, 8, scanline);                               width, height, 8, scanline);
749          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
750          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
751          XInitImage(image);          XInitImage(image);
# Line 840  ui_destroy_glyph(HGLYPH glyph) Line 764  ui_destroy_glyph(HGLYPH glyph)
764  }  }
765    
766  HCURSOR  HCURSOR
767  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
768                   int height, uint8 * andmask, uint8 * xormask)                   uint8 * andmask, uint8 * xormask)
769  {  {
770          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
771          XColor bg, fg;          XColor bg, fg;
# Line 899  ui_create_cursor(unsigned int x, unsigne Line 823  ui_create_cursor(unsigned int x, unsigne
823          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
824          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
825    
826          xcursor = XCreatePixmapCursor(display, (Pixmap) cursorglyph,          xcursor =
827                                        (Pixmap) maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(display, (Pixmap) cursorglyph,
828                                        (Pixmap) maskglyph, &fg, &bg, x, y);
829    
830          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
831          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
# Line 912  ui_create_cursor(unsigned int x, unsigne Line 837  ui_create_cursor(unsigned int x, unsigne
837  void  void
838  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
839  {  {
840          XDefineCursor(display, wnd, (Cursor) cursor);          current_cursor = (Cursor) cursor;
841            XDefineCursor(display, wnd, current_cursor);
842  }  }
843    
844  void  void
# Line 932  ui_create_colourmap(COLOURMAP * colours) Line 858  ui_create_colourmap(COLOURMAP * colours)
858  {  {
859          COLOURENTRY *entry;          COLOURENTRY *entry;
860          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
861            uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
862          if (owncolmap)          XColor xentry;
863            XColor xc_cache[256];
864            uint32 colour;
865            int colLookup = 256;
866            for (i = 0; i < ncolours; i++)
867          {          {
868                  XColor *xcolours, *xentry;                  entry = &colours->colours[i];
869                  Colormap map;                  MAKE_XCOLOR(&xentry, entry);
870    
871                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  if (XAllocColor(display, xcolmap, &xentry) == 0)
                 for (i = 0; i < ncolours; i++)  
872                  {                  {
873                          entry = &colours->colours[i];                          /* Allocation failed, find closest match. */
874                          xentry = &xcolours[i];                          int j = 256;
875                          xentry->pixel = i;                          int nMinDist = 3 * 256 * 256;
876                          MAKE_XCOLOR(xentry, entry);                          long nDist = nMinDist;
                 }  
877    
878                  map = XCreateColormap(display, wnd, visual, AllocAll);                          /* only get the colors once */
879                  XStoreColors(display, map, xcolours, ncolours);                          while (colLookup--)
880                            {
881                                    xc_cache[colLookup].pixel = colLookup;
882                                    xc_cache[colLookup].red = xc_cache[colLookup].green =
883                                            xc_cache[colLookup].blue = 0;
884                                    xc_cache[colLookup].flags = 0;
885                                    XQueryColor(display,
886                                                DefaultColormap(display, DefaultScreen(display)),
887                                                &xc_cache[colLookup]);
888                            }
889                            colLookup = 0;
890    
891                  xfree(xcolours);                          /* approximate the pixel */
892                  return (HCOLOURMAP) map;                          while (j--)
893          }                          {
894          else                                  if (xc_cache[j].flags)
895          {                                  {
896                  uint32 *map = xmalloc(sizeof(*colmap) * ncolours);                                          nDist = ((long) (xc_cache[j].red >> 8) -
897                  XColor xentry;                                                   (long) (xentry.red >> 8)) *
898                  uint32 colour;                                                  ((long) (xc_cache[j].red >> 8) -
899                                                     (long) (xentry.red >> 8)) +
900                                                    ((long) (xc_cache[j].green >> 8) -
901                                                     (long) (xentry.green >> 8)) *
902                                                    ((long) (xc_cache[j].green >> 8) -
903                                                     (long) (xentry.green >> 8)) +
904                                                    ((long) (xc_cache[j].blue >> 8) -
905                                                     (long) (xentry.blue >> 8)) *
906                                                    ((long) (xc_cache[j].blue >> 8) -
907                                                     (long) (xentry.blue >> 8));
908                                    }
909                                    if (nDist < nMinDist)
910                                    {
911                                            nMinDist = nDist;
912                                            xentry.pixel = j;
913                                    }
914                            }
915                    }
916                    colour = xentry.pixel;
917    
918                  for (i = 0; i < ncolours; i++)                  /* update our cache */
919                    if (xentry.pixel < 256)
920                  {                  {
921                          entry = &colours->colours[i];                          xc_cache[xentry.pixel].red = xentry.red;
922                          MAKE_XCOLOR(&xentry, entry);                          xc_cache[xentry.pixel].green = xentry.green;
923                            xc_cache[xentry.pixel].blue = xentry.blue;
                         if (XAllocColor(display, xcolmap, &xentry) != 0)  
                                 colour = xentry.pixel;  
                         else  
                                 colour = white;  
924    
                         /* byte swap here to make translate_image faster */  
                         map[i] = translate_colour(colour);  
925                  }                  }
926    
927                  return map;  
928                    /* byte swap here to make translate_image faster */
929                    map[i] = translate_colour(colour);
930          }          }
931    
932            return map;
933  }  }
934    
935  void  void
936  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
937  {  {
938          if (owncolmap)          xfree(map);
                 XFreeColormap(display, (Colormap) map);  
         else  
                 xfree(map);  
939  }  }
940    
941  void  void
942  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
943  {  {
944          if (owncolmap)          colmap = map;
                 XSetWindowColormap(display, wnd, (Colormap) map);  
         else  
                 colmap = map;  
945  }  }
946    
947  void  void
# Line 1008  ui_set_clip(int x, int y, int cx, int cy Line 957  ui_set_clip(int x, int y, int cx, int cy
957  }  }
958    
959  void  void
960  ui_reset_clip()  ui_reset_clip(void)
961  {  {
962          XRectangle rect;          XRectangle rect;
963    
# Line 1020  ui_reset_clip() Line 969  ui_reset_clip()
969  }  }
970    
971  void  void
972  ui_bell()  ui_bell(void)
973  {  {
974          XBell(display, 0);          XBell(display, 0);
975  }  }
# Line 1060  ui_patblt(uint8 opcode, Line 1009  ui_patblt(uint8 opcode,
1009                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
1010                          XSetFillStyle(display, gc, FillOpaqueStippled);                          XSetFillStyle(display, gc, FillOpaqueStippled);
1011                          XSetStipple(display, gc, fill);                          XSetStipple(display, gc, fill);
1012                          XSetTSOrigin(display, gc, brush->xorigin,                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
                                      brush->yorigin);  
1013    
1014                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1015    
1016                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
1017                            XSetTSOrigin(display, gc, 0, 0);
1018                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
1019                          break;                          break;
1020    
# Line 1084  ui_screenblt(uint8 opcode, Line 1033  ui_screenblt(uint8 opcode,
1033          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1034          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1035          if (ownbackstore)          if (ownbackstore)
1036                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1037          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1038  }  }
1039    
# Line 1097  ui_memblt(uint8 opcode, Line 1045  ui_memblt(uint8 opcode,
1045          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1046          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1047          if (ownbackstore)          if (ownbackstore)
1048                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy,                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1049          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1050  }  }
1051    
# Line 1115  ui_triblt(uint8 opcode, Line 1062  ui_triblt(uint8 opcode,
1062          {          {
1063                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1064                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1065                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1066                          break;                          break;
1067    
1068                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1069                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1070                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1071                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1072                          break;                          break;
1073    
1074                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1075                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1076                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1077                          break;                          break;
1078    
1079                  default:                  default:
# Line 1164  ui_rect( Line 1107  ui_rect(
1107  void  void
1108  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1109                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1110                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1111                int fgcolour)                int bgcolour, int fgcolour)
1112  {  {
1113          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1114          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1115    
1116          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(display, gc,
1117                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1118          XSetStipple(display, gc, (Pixmap) glyph);          XSetStipple(display, gc, (Pixmap) glyph);
1119          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
1120    
# Line 1189  ui_draw_glyph(int mixmode, Line 1132  ui_draw_glyph(int mixmode,
1132        if ((xyoffset & 0x80))\        if ((xyoffset & 0x80))\
1133          {\          {\
1134            if (flags & TEXT2_VERTICAL) \            if (flags & TEXT2_VERTICAL) \
1135              y += ttext[++idx] | (ttext[++idx] << 8);\              y += ttext[idx+1] | (ttext[idx+2] << 8);\
1136            else\            else\
1137              x += ttext[++idx] | (ttext[++idx] << 8);\              x += ttext[idx+1] | (ttext[idx+2] << 8);\
1138              idx += 2;\
1139          }\          }\
1140        else\        else\
1141          {\          {\
# Line 1214  ui_draw_glyph(int mixmode, Line 1158  ui_draw_glyph(int mixmode,
1158    
1159  void  void
1160  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,
1161               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1162               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1163               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1164  {  {
1165          FONTGLYPH *glyph;          FONTGLYPH *glyph;
# Line 1240  ui_draw_text(uint8 font, uint8 flags, in Line 1184  ui_draw_text(uint8 font, uint8 flags, in
1184                  {                  {
1185                          case 0xff:                          case 0xff:
1186                                  if (i + 2 < length)                                  if (i + 2 < length)
1187                                          cache_put_text(text[i + 1], text,                                          cache_put_text(text[i + 1], text, text[i + 2]);
                                                        text[i + 2]);  
1188                                  else                                  else
1189                                  {                                  {
1190                                          error("this shouldn't be happening\n");                                          error("this shouldn't be happening\n");
# Line 1258  ui_draw_text(uint8 font, uint8 flags, in Line 1201  ui_draw_text(uint8 font, uint8 flags, in
1201                                  if (entry != NULL)                                  if (entry != NULL)
1202                                  {                                  {
1203                                          if ((((uint8 *) (entry->data))[1] ==                                          if ((((uint8 *) (entry->data))[1] ==
1204                                               0)                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
                                             && (!(flags & TEXT2_IMPLICIT_X)))  
1205                                          {                                          {
1206                                                  if (flags & TEXT2_VERTICAL)                                                  if (flags & TEXT2_VERTICAL)
1207                                                          y += text[i + 2];                                                          y += text[i + 2];
# Line 1275  ui_draw_text(uint8 font, uint8 flags, in Line 1217  ui_draw_text(uint8 font, uint8 flags, in
1217                                          text = &(text[i]);                                          text = &(text[i]);
1218                                          i = 0;                                          i = 0;
1219                                          for (j = 0; j < entry->size; j++)                                          for (j = 0; j < entry->size; j++)
1220                                                  DO_GLYPH(((uint8 *) (entry->                                                  DO_GLYPH(((uint8 *) (entry->data)), j);
                                                                      data)),  
                                                          j);  
1221                                  }                                  }
1222                                  break;                                  break;
1223    
# Line 1299  ui_desktop_save(uint32 offset, int x, in Line 1239  ui_desktop_save(uint32 offset, int x, in
1239    
1240          if (ownbackstore)          if (ownbackstore)
1241          {          {
1242                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1243          }          }
1244          else          else
1245          {          {
1246                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(display, wnd, cx, cy, depth);
1247                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1248                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1249                  XFreePixmap(display, pix);                  XFreePixmap(display, pix);
1250          }          }
1251    
1252          offset *= bpp / 8;          offset *= bpp / 8;
1253          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);  
1254    
1255          XDestroyImage(image);          XDestroyImage(image);
1256  }  }
# Line 1329  ui_desktop_restore(uint32 offset, int x, Line 1266  ui_desktop_restore(uint32 offset, int x,
1266          if (data == NULL)          if (data == NULL)
1267                  return;                  return;
1268    
1269          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1270                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);
                              cx * bpp / 8);  
1271    
1272          if (ownbackstore)          if (ownbackstore)
1273          {          {

Legend:
Removed from v.64  
changed lines
  Added in v.263

  ViewVC Help
Powered by ViewVC 1.1.26