/[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 309 by jsorg71, Tue Feb 4 05:32:13 2003 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    extern int server_bpp;
35    BOOL enable_compose = False;
36    BOOL focused;
37    BOOL mouse_in_wnd;
38    
39  Display *display;  Display *display;
 XkbDescPtr xkb;  
40  static int x_socket;  static int x_socket;
41    static Screen *screen;
42  static Window wnd;  static Window wnd;
43  static GC gc;  static GC gc;
44  static Visual *visual;  static Visual *visual;
45  static int depth;  static int depth;
46  static int bpp;  static int bpp;
47    static XIM IM;
48    static XIC IC;
49    static XModifierKeymap *mod_map;
50    static Cursor current_cursor;
51    static Atom protocol_atom, kill_atom;
52    
53  /* endianness */  /* endianness */
54  static BOOL host_be;  static BOOL host_be;
# Line 49  static BOOL xserver_be; Line 58  static BOOL xserver_be;
58  static BOOL ownbackstore;  static BOOL ownbackstore;
59  static Pixmap backstore;  static Pixmap backstore;
60    
61  /* needed to keep track of the modifiers */  /* MWM decorations */
62  static unsigned int numlock_modifier_mask = 0;  #define MWM_HINTS_DECORATIONS   (1L << 1)
63  static unsigned int key_down_state = 0;  #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
64    typedef struct
65    {
66  #define DShift1Mask   (1<<0)          uint32 flags;
67  #define DLockMask     (1<<1)          uint32 functions;
68  #define DControl1Mask (1<<2)          uint32 decorations;
69  #define DMod1Mask     (1<<3)          sint32 inputMode;
70  #define DMod2Mask     (1<<4)          uint32 status;
71  #define DMod3Mask     (1<<5)  }
72  #define DMod4Mask     (1<<6)  PropMotifWmHints;
73  #define DMod5Mask     (1<<7)  
 #define DShift2Mask   (1<<8)  
 #define DControl2Mask (1<<9)  
 #define DNumLockMask  (1<<10)  
74    
75  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
76  { \  { \
# Line 73  static unsigned int key_down_state = 0; Line 79  static unsigned int key_down_state = 0;
79                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \
80  }  }
81    
82    #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\
83    { \
84            XFillRectangle(display, ownbackstore ? backstore : wnd, gc, x, y, cx, cy); \
85    }
86    
87  /* colour maps */  /* colour maps */
88  static BOOL owncolmap;  BOOL owncolmap = False;
89  static Colormap xcolmap;  static Colormap xcolmap;
 static uint32 white;  
90  static uint32 *colmap;  static uint32 *colmap;
91    
92  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )  #define TRANSLATE(col)          ( server_bpp != 8 ? col : owncolmap ? col : translate_colour(colmap[col]) )
93  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));
94  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));
95    
# Line 105  static int rop2_map[] = { Line 115  static int rop2_map[] = {
115  #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]); }
116  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
117    
118  void xwin_get_numlock_mask();  void
119  void xwin_mod_update(uint32 state, uint32 ev_time);  mwm_hide_decorations(void)
120  void xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode);  {
121  void xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode);          PropMotifWmHints motif_hints;
122            Atom hintsatom;
123    
124            /* setup the property */
125            motif_hints.flags = MWM_HINTS_DECORATIONS;
126            motif_hints.decorations = 0;
127    
128            /* get the atom for the property */
129            hintsatom = XInternAtom(display, "_MOTIF_WM_HINTS", False);
130            if (!hintsatom)
131            {
132                    warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");
133                    return;
134            }
135    
136            XChangeProperty(display, wnd, hintsatom, hintsatom, 32, PropModeReplace,
137                            (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
138    }
139    
140  static void  static void
141  translate8(uint8 * data, uint8 * out, uint8 * end)  translate8(uint8 * data, uint8 * out, uint8 * end)
# Line 205  translate_colour(uint32 colour) Line 232  translate_colour(uint32 colour)
232  }  }
233    
234  BOOL  BOOL
235  ui_create_window(char *title)  get_key_state(unsigned int state, uint32 keysym)
236  {  {
237          XSetWindowAttributes attribs;          int modifierpos, key, keysymMask = 0;
238          XClassHint *classhints;          int offset;
         XSizeHints *sizehints;  
         unsigned long input_mask;  
         XPixmapFormatValues *pfm;  
         Screen *screen;  
         uint16 test;  
         int i;  
239    
240          int xkb_minor, xkb_major;          KeyCode keycode = XKeysymToKeycode(display, keysym);
         int xkb_event, xkb_error, xkb_reason;  
241    
242          /* 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");  
243                  return False;                  return False;
         }  
   
244    
245          display =          for (modifierpos = 0; modifierpos < 8; modifierpos++)
                 XkbOpenDisplay(NULL, &xkb_event, &xkb_error, &xkb_major,  
                                &xkb_minor, &xkb_reason);  
         switch (xkb_reason)  
246          {          {
247                  case XkbOD_BadLibraryVersion:                  offset = mod_map->max_keypermod * modifierpos;
248                          error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n");  
249                          break;                  for (key = 0; key < mod_map->max_keypermod; key++)
250                  case XkbOD_ConnectionRefused:                  {
251                          error("XkbOD_ConnectionRefused\n");                          if (mod_map->modifiermap[offset + key] == keycode)
252                          break;                                  keysymMask |= 1 << modifierpos;
253                  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;  
254          }          }
255    
256            return (state & keysymMask) ? True : False;
257    }
258    
259    BOOL
260    ui_init(void)
261    {
262            XPixmapFormatValues *pfm;
263            uint16 test;
264            int i;
265    
266            display = XOpenDisplay(NULL);
267          if (display == NULL)          if (display == NULL)
268          {          {
269                  error("Failed to open display\n");                  error("Failed to open display: %s\n", XDisplayName(NULL));
270                  return False;                  return False;
271          }          }
272    
# Line 269  ui_create_window(char *title) Line 282  ui_create_window(char *title)
282                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
283                  while (i--)                  while (i--)
284                  {                  {
285                          if ((pfm[i].depth == depth)                          if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))
                             && (pfm[i].bits_per_pixel > bpp))  
286                          {                          {
287                                  bpp = pfm[i].bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
288                          }                          }
# Line 285  ui_create_window(char *title) Line 297  ui_create_window(char *title)
297                  return False;                  return False;
298          }          }
299    
300          if (depth <= 8)          if (owncolmap != True)
301                  owncolmap = True;          {
         else  
302                  xcolmap = DefaultColormapOfScreen(screen);                  xcolmap = DefaultColormapOfScreen(screen);
303                    if (depth <= 8)
304                            warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");
305            }
306    
307            gc = XCreateGC(display, RootWindowOfScreen(screen), 0, NULL);
308    
309            if (DoesBackingStore(screen) != Always)
310                    ownbackstore = True;
311    
312          test = 1;          test = 1;
313          host_be = !(BOOL) (*(uint8 *) (&test));          host_be = !(BOOL) (*(uint8 *) (&test));
314          xserver_be = (ImageByteOrder(display) == MSBFirst);          xserver_be = (ImageByteOrder(display) == MSBFirst);
315    
316          white = WhitePixelOfScreen(screen);          if ((width == 0) || (height == 0))
317          attribs.background_pixel = BlackPixelOfScreen(screen);          {
318          attribs.backing_store = DoesBackingStore(screen);                  /* Fetch geometry from _NET_WORKAREA */
319                    uint32 x, y, cx, cy;
320    
321          if (attribs.backing_store == NotUseful)                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)
322                  ownbackstore = True;                  {
323                            width = cx;
324                            height = cy;
325                    }
326                    else
327                    {
328                            warning("Failed to get workarea: probably your window manager does not support extended hints\n");
329                            width = 800;
330                            height = 600;
331                    }
332            }
333    
334          if (fullscreen)          if (fullscreen)
335          {          {
                 attribs.override_redirect = True;  
336                  width = WidthOfScreen(screen);                  width = WidthOfScreen(screen);
337                  height = HeightOfScreen(screen);                  height = HeightOfScreen(screen);
338          }          }
339          else  
340            /* make sure width is a multiple of 4 */
341            width = (width + 3) & ~3;
342    
343            if (ownbackstore)
344          {          {
345                  attribs.override_redirect = False;                  backstore =
346                            XCreatePixmap(display, RootWindowOfScreen(screen), width, height, depth);
347    
348                    /* clear to prevent rubbish being exposed at startup */
349                    XSetForeground(display, gc, BlackPixelOfScreen(screen));
350                    XFillRectangle(display, backstore, gc, 0, 0, width, height);
351          }          }
352    
353          width = (width + 3) & ~3;       /* make width a multiple of 32 bits */          mod_map = XGetModifierMapping(display);
354    
355          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          if (enable_compose)
356                              0, 0, width, height, 0, CopyFromParent,                  IM = XOpenIM(display, NULL, NULL, NULL);
357                              InputOutput, CopyFromParent,  
358                              CWBackingStore | CWBackPixel | CWOverrideRedirect,          xkeymap_init();
359                              &attribs);          return True;
360    }
361    
362    void
363    ui_deinit(void)
364    {
365            if (IM != NULL)
366                    XCloseIM(IM);
367    
368            XFreeModifiermap(mod_map);
369    
370            if (ownbackstore)
371                    XFreePixmap(display, backstore);
372    
373            XFreeGC(display, gc);
374            XCloseDisplay(display);
375            display = NULL;
376    }
377    
378    BOOL
379    ui_create_window(void)
380    {
381            XSetWindowAttributes attribs;
382            XClassHint *classhints;
383            XSizeHints *sizehints;
384            int wndwidth, wndheight;
385            long input_mask, ic_input_mask;
386            XEvent xevent;
387    
388            wndwidth = fullscreen ? WidthOfScreen(screen) : width;
389            wndheight = fullscreen ? HeightOfScreen(screen) : height;
390    
391            attribs.background_pixel = BlackPixelOfScreen(screen);
392            attribs.backing_store = ownbackstore ? NotUseful : Always;
393            attribs.override_redirect = fullscreen;
394    
395            wnd = XCreateWindow(display, RootWindowOfScreen(screen), 0, 0, wndwidth, wndheight,
396                                0, CopyFromParent, InputOutput, CopyFromParent,
397                                CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);
398    
399          XStoreName(display, wnd, title);          XStoreName(display, wnd, title);
400    
401            if (hide_decorations)
402                    mwm_hide_decorations();
403    
404          classhints = XAllocClassHint();          classhints = XAllocClassHint();
405          if (classhints != NULL)          if (classhints != NULL)
406          {          {
# Line 340  ui_create_window(char *title) Line 419  ui_create_window(char *title)
419                  XFree(sizehints);                  XFree(sizehints);
420          }          }
421    
422          xkeymap_init();          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
423                    VisibilityChangeMask | FocusChangeMask;
424    
         input_mask = KeyPressMask | KeyReleaseMask |  
                 ButtonPressMask | ButtonReleaseMask |  
                 EnterWindowMask | LeaveWindowMask;  
425          if (sendmotion)          if (sendmotion)
426                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
   
427          if (ownbackstore)          if (ownbackstore)
428                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
429            if (fullscreen || grab_keyboard)
430                    input_mask |= EnterWindowMask;
431            if (grab_keyboard)
432                    input_mask |= LeaveWindowMask;
433    
434            if (IM != NULL)
435            {
436                    IC = XCreateIC(IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
437                                   XNClientWindow, wnd, XNFocusWindow, wnd, NULL);
438    
439                    if ((IC != NULL)
440                        && (XGetICValues(IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
441                            input_mask |= ic_input_mask;
442            }
443    
444          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);  
   
445          XMapWindow(display, wnd);          XMapWindow(display, wnd);
446    
447          /* TODO: error texts... make them friendly. */          /* wait for VisibilityNotify */
448          xkb = XkbGetKeyboard(display, XkbAllComponentsMask, XkbUseCoreKbd);          do
         if ((int) xkb == BadAlloc || xkb == NULL)  
449          {          {
450                  error("XkbGetKeyboard failed.\n");                  XMaskEvent(display, VisibilityChangeMask, &xevent);
                 exit(0);  
451          }          }
452            while (xevent.type != VisibilityNotify);
453    
454          /* TODO: error texts... make them friendly. */          focused = False;
455          if (XkbSelectEvents          mouse_in_wnd = False;
             (display, xkb->device_spec, XkbAllEventsMask,  
              XkbAllEventsMask) == False)  
         {  
                 error("XkbSelectEvents failed.\n");  
                 exit(0);  
         }  
456    
457          xwin_get_numlock_mask();          /* handle the WM_DELETE_WINDOW protocol */
458            protocol_atom = XInternAtom(display, "WM_PROTOCOLS", True);
459            kill_atom = XInternAtom(display, "WM_DELETE_WINDOW", True);
460            XSetWMProtocols(display, wnd, &kill_atom, 1);
461    
462          return True;          return True;
463  }  }
464    
465  void  void
466  xwin_get_numlock_mask()  ui_destroy_window(void)
467  {  {
468          KeyCode numlockcode;          if (IC != NULL)
469          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");  
470    
471            XDestroyWindow(display, wnd);
472  }  }
473    
474  void  void
475  ui_destroy_window()  xwin_toggle_fullscreen(void)
476  {  {
477          if (xkb != NULL)          Pixmap contents = 0;
                 XkbFreeKeyboard(xkb, XkbAllControlsMask, True);  
478    
479          if (ownbackstore)          if (!ownbackstore)
480                  XFreePixmap(display, backstore);          {
481                    /* need to save contents of window */
482                    contents = XCreatePixmap(display, wnd, width, height, depth);
483                    XCopyArea(display, wnd, contents, gc, 0, 0, width, height, 0, 0);
484            }
485    
486          XFreeGC(display, gc);          ui_destroy_window();
487          XDestroyWindow(display, wnd);          fullscreen = !fullscreen;
488          XCloseDisplay(display);          ui_create_window();
489          display = NULL;  
490            XDefineCursor(display, wnd, current_cursor);
491    
492            if (!ownbackstore)
493            {
494                    XCopyArea(display, contents, wnd, gc, 0, 0, width, height, 0, 0);
495                    XFreePixmap(display, contents);
496            }
497  }  }
498    
499  static void  /* Process all events in Xlib queue
500  xwin_process_events()     Returns 0 after user quit, 1 otherwise */
501    static int
502    xwin_process_events(void)
503  {  {
504          XEvent xevent;          XEvent xevent;
   
505          KeySym keysym;          KeySym keysym;
         uint8 scancode;  
506          uint16 button, flags;          uint16 button, flags;
507          uint32 ev_time;          uint32 ev_time;
508          uint32 tmpmods;          key_translation tr;
509            char str[256];
510            Status status;
511            unsigned int state;
512            Window wdummy;
513            int dummy;
514    
515          while (XCheckMaskEvent(display, ~0, &xevent))          while (XPending(display) > 0)
516          {          {
517                  ev_time = time(NULL);                  XNextEvent(display, &xevent);
518    
519                    if ((IC != NULL) && (XFilterEvent(&xevent, None) == True))
520                    {
521                            DEBUG_KBD(("Filtering event\n"));
522                            continue;
523                    }
524    
525                  flags = 0;                  flags = 0;
526    
527                  switch (xevent.type)                  switch (xevent.type)
528                  {                  {
529                          case KeyRelease:                          case ClientMessage:
530                                  flags = KBD_FLAG_DOWN | KBD_FLAG_UP;                                  /* the window manager told us to quit */
531                                  /* fall through */                                  if ((xevent.xclient.message_type == protocol_atom)
532                                        && (xevent.xclient.data.l[0] == kill_atom))
533                                            /* Quit */
534                                            return 0;
535                                    break;
536    
537                          case KeyPress:                          case KeyPress:
538                                  if (XkbTranslateKeyCode                                  if (IC != NULL)
539                                      (xkb, xevent.xkey.keycode,                                          /* Multi_key compatible version */
540                                       xevent.xkey.state, &tmpmods,                                  {
541                                       &keysym) == False)                                          XmbLookupString(IC,
542                                                            (XKeyPressedEvent *) &
543                                                            xevent, str, sizeof(str), &keysym, &status);
544                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
545                                            {
546                                                    error("XmbLookupString failed with status 0x%x\n",
547                                                          status);
548                                                    break;
549                                            }
550                                    }
551                                    else
552                                    {
553                                            /* Plain old XLookupString */
554                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
555                                            XLookupString((XKeyEvent *) & xevent,
556                                                          str, sizeof(str), &keysym, NULL);
557                                    }
558    
559                                    DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
560                                               get_ksname(keysym)));
561    
562                                    ev_time = time(NULL);
563                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
564                                          break;                                          break;
                                 scancode =  
                                         xkeymap_translate_key(keysym,  
                                                               xevent.xkey.  
                                                               keycode,  
                                                               &flags);  
565    
566                                  if (scancode == 0)                                  tr = xkeymap_translate_key(keysym,
567                                                               xevent.xkey.keycode, xevent.xkey.state);
568    
569                                    if (tr.scancode == 0)
570                                          break;                                          break;
571    
572                                  /* keep track of the modifiers -- needed for stickykeys... */                                  ensure_remote_modifiers(ev_time, tr);
                                 if (xevent.type == KeyPress)  
                                         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);  
573    
574                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
575                                    break;
576    
577                            case KeyRelease:
578                                    XLookupString((XKeyEvent *) & xevent, str,
579                                                  sizeof(str), &keysym, NULL);
580    
581                                    DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
582                                               get_ksname(keysym)));
583    
584                                    ev_time = time(NULL);
585                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
586                                            break;
587    
588                                    tr = xkeymap_translate_key(keysym,
589                                                               xevent.xkey.keycode, xevent.xkey.state);
590    
591                                    if (tr.scancode == 0)
592                                            break;
593    
594                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
595                                  break;                                  break;
596    
597                          case ButtonPress:                          case ButtonPress:
# Line 499  xwin_process_events() Line 599  xwin_process_events()
599                                  /* fall through */                                  /* fall through */
600    
601                          case ButtonRelease:                          case ButtonRelease:
602                                  button = xkeymap_translate_button(xevent.                                  button = xkeymap_translate_button(xevent.xbutton.button);
                                                                   xbutton.  
                                                                   button);  
603                                  if (button == 0)                                  if (button == 0)
604                                          break;                                          break;
605    
606                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
607                                                 flags | button,                                                 flags | button, xevent.xbutton.x, xevent.xbutton.y);
                                                xevent.xbutton.x,  
                                                xevent.xbutton.y);  
608                                  break;                                  break;
609    
610                          case MotionNotify:                          case MotionNotify:
611                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  if (fullscreen && !focused)
612                                                 MOUSE_FLAG_MOVE,                                          XSetInputFocus(display, wnd, RevertToPointerRoot,
613                                                 xevent.xmotion.x,                                                         CurrentTime);
614                                                 xevent.xmotion.y);                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
615                                                   MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
616                                  break;                                  break;
617    
618                          case EnterNotify:                          case FocusIn:
619                                  XGrabKeyboard(display, wnd, True,                                  if (xevent.xfocus.mode == NotifyGrab)
620                                                GrabModeAsync, GrabModeAsync,                                          break;
621                                                CurrentTime);                                  focused = True;
622                                    XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy,
623                                                  &dummy, &dummy, &state);
624                                    reset_modifier_keys(state);
625                                    if (grab_keyboard && mouse_in_wnd)
626                                            XGrabKeyboard(display, wnd, True,
627                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
628                                    break;
629    
630                                  xwin_mod_update(xevent.xcrossing.state,                          case FocusOut:
631                                                  ev_time);                                  if (xevent.xfocus.mode == NotifyUngrab)
632                                            break;
633                                    focused = False;
634                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
635                                            XUngrabKeyboard(display, CurrentTime);
636                                    break;
637    
638                            case EnterNotify:
639                                    /* we only register for this event when in fullscreen mode */
640                                    /* or grab_keyboard */
641                                    mouse_in_wnd = True;
642                                    if (fullscreen)
643                                    {
644                                            XSetInputFocus(display, wnd, RevertToPointerRoot,
645                                                           CurrentTime);
646                                            break;
647                                    }
648                                    if (focused)
649                                            XGrabKeyboard(display, wnd, True,
650                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
651                                  break;                                  break;
652    
653                          case LeaveNotify:                          case LeaveNotify:
654                                    /* we only register for this event when grab_keyboard */
655                                    mouse_in_wnd = False;
656                                  XUngrabKeyboard(display, CurrentTime);                                  XUngrabKeyboard(display, CurrentTime);
657                                  break;                                  break;
658    
# Line 538  xwin_process_events() Line 663  xwin_process_events()
663                                            xevent.xexpose.height,                                            xevent.xexpose.height,
664                                            xevent.xexpose.x, xevent.xexpose.y);                                            xevent.xexpose.x, xevent.xexpose.y);
665                                  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;  
666    
667          }                          case MappingNotify:
668                                    /* Refresh keyboard mapping if it has changed. This is important for
669                                       Xvnc, since it allocates keycodes dynamically */
670          if (!(ShiftMask & state) && (key_down_state & DShift1Mask))                                  if (xevent.xmapping.request == MappingKeyboard
671          {                                      || xevent.xmapping.request == MappingModifier)
672                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a,                                          XRefreshKeyboardMapping(&xevent.xmapping);
                                0);  
                 key_down_state &= ~DShift1Mask;  
   
         }  
673    
674          if (!(ControlMask & state) && (key_down_state & DControl1Mask))                                  if (xevent.xmapping.request == MappingModifier)
675          {                                  {
676                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d,                                          XFreeModifiermap(mod_map);
677                                 0);                                          mod_map = XGetModifierMapping(display);
678                  key_down_state &= ~DControl1Mask;                                  }
679                                    break;
         }  
   
         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;  
   
         }  
   
         if ((Mod2Mask & state) && !(key_down_state & DMod2Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,  
                                0xb8, 0);  
                 key_down_state |= DMod2Mask;  
680    
681                    }
682          }          }
683            /* Keep going */
684            return 1;
685  }  }
686    
687  void  /* Returns 0 after user quit, 1 otherwise */
688    int
689  ui_select(int rdp_socket)  ui_select(int rdp_socket)
690  {  {
691          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
# Line 724  ui_select(int rdp_socket) Line 695  ui_select(int rdp_socket)
695    
696          while (True)          while (True)
697          {          {
698                    /* Process any events already waiting */
699                    if (!xwin_process_events())
700                            /* User quit */
701                            return 0;
702    
703                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
704                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
705                  if (display != NULL)                  FD_SET(x_socket, &rfds);
                 {  
                         FD_SET(x_socket, &rfds);  
                         XFlush(display);  
                 }  
706    
707                  switch (select(n, &rfds, NULL, NULL, NULL))                  switch (select(n, &rfds, NULL, NULL, NULL))
708                  {                  {
# Line 741  ui_select(int rdp_socket) Line 713  ui_select(int rdp_socket)
713                                  continue;                                  continue;
714                  }                  }
715    
                 if (FD_ISSET(x_socket, &rfds))  
                         xwin_process_events();  
   
716                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
717                          return;                          return 1;
718          }          }
719  }  }
720    
# Line 764  ui_create_bitmap(int width, int height, Line 733  ui_create_bitmap(int width, int height,
733    
734          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
735          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
736          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
737                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, 8, 0);
738    
739          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
740    
# Line 776  ui_create_bitmap(int width, int height, Line 745  ui_create_bitmap(int width, int height,
745  }  }
746    
747  void  void
748  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)  
749  {  {
750          XImage *image;          XImage *image;
751          uint8 *tdata;          uint8 *tdata;
752    
753            if (server_bpp == 16)
754            {
755                    image = XCreateImage(display, visual, depth, ZPixmap, 0,
756                                         (char *) data, width, height, 16, 0);
757    
758                    if (ownbackstore)
759                    {
760                            XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
761                            XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
762                    }
763                    else
764                    {
765                            XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
766                    }
767    
768                    XFree(image);
769                    return;
770            }
771          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
772          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
773                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, 8, 0);
774    
775          if (ownbackstore)          if (ownbackstore)
776          {          {
# Line 820  ui_create_glyph(int width, int height, u Line 806  ui_create_glyph(int width, int height, u
806          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
807          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
808    
809          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
810                               data, width, height, 8, scanline);                               width, height, 8, scanline);
811          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
812          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
813          XInitImage(image);          XInitImage(image);
# Line 840  ui_destroy_glyph(HGLYPH glyph) Line 826  ui_destroy_glyph(HGLYPH glyph)
826  }  }
827    
828  HCURSOR  HCURSOR
829  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
830                   int height, uint8 * andmask, uint8 * xormask)                   uint8 * andmask, uint8 * xormask)
831  {  {
832          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
833          XColor bg, fg;          XColor bg, fg;
# Line 899  ui_create_cursor(unsigned int x, unsigne Line 885  ui_create_cursor(unsigned int x, unsigne
885          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
886          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
887    
888          xcursor = XCreatePixmapCursor(display, (Pixmap) cursorglyph,          xcursor =
889                                        (Pixmap) maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(display, (Pixmap) cursorglyph,
890                                        (Pixmap) maskglyph, &fg, &bg, x, y);
891    
892          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
893          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
# Line 912  ui_create_cursor(unsigned int x, unsigne Line 899  ui_create_cursor(unsigned int x, unsigne
899  void  void
900  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
901  {  {
902          XDefineCursor(display, wnd, (Cursor) cursor);          current_cursor = (Cursor) cursor;
903            XDefineCursor(display, wnd, current_cursor);
904  }  }
905    
906  void  void
# Line 927  ui_destroy_cursor(HCURSOR cursor) Line 915  ui_destroy_cursor(HCURSOR cursor)
915                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
916                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
917    
918    
919  HCOLOURMAP  HCOLOURMAP
920  ui_create_colourmap(COLOURMAP * colours)  ui_create_colourmap(COLOURMAP * colours)
921  {  {
922          COLOURENTRY *entry;          COLOURENTRY *entry;
923          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
924            if (!owncolmap)
925            {
926                    uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
927                    XColor xentry;
928                    XColor xc_cache[256];
929                    uint32 colour;
930                    int colLookup = 256;
931                    for (i = 0; i < ncolours; i++)
932                    {
933                            entry = &colours->colours[i];
934                            MAKE_XCOLOR(&xentry, entry);
935    
936          if (owncolmap)                          if (XAllocColor(display, xcolmap, &xentry) == 0)
937                            {
938                                    /* Allocation failed, find closest match. */
939                                    int j = 256;
940                                    int nMinDist = 3 * 256 * 256;
941                                    long nDist = nMinDist;
942    
943                                    /* only get the colors once */
944                                    while (colLookup--)
945                                    {
946                                            xc_cache[colLookup].pixel = colLookup;
947                                            xc_cache[colLookup].red = xc_cache[colLookup].green =
948                                                    xc_cache[colLookup].blue = 0;
949                                            xc_cache[colLookup].flags = 0;
950                                            XQueryColor(display,
951                                                        DefaultColormap(display,
952                                                                        DefaultScreen(display)),
953                                                        &xc_cache[colLookup]);
954                                    }
955                                    colLookup = 0;
956    
957                                    /* approximate the pixel */
958                                    while (j--)
959                                    {
960                                            if (xc_cache[j].flags)
961                                            {
962                                                    nDist = ((long) (xc_cache[j].red >> 8) -
963                                                             (long) (xentry.red >> 8)) *
964                                                            ((long) (xc_cache[j].red >> 8) -
965                                                             (long) (xentry.red >> 8)) +
966                                                            ((long) (xc_cache[j].green >> 8) -
967                                                             (long) (xentry.green >> 8)) *
968                                                            ((long) (xc_cache[j].green >> 8) -
969                                                             (long) (xentry.green >> 8)) +
970                                                            ((long) (xc_cache[j].blue >> 8) -
971                                                             (long) (xentry.blue >> 8)) *
972                                                            ((long) (xc_cache[j].blue >> 8) -
973                                                             (long) (xentry.blue >> 8));
974                                            }
975                                            if (nDist < nMinDist)
976                                            {
977                                                    nMinDist = nDist;
978                                                    xentry.pixel = j;
979                                            }
980                                    }
981                            }
982                            colour = xentry.pixel;
983    
984                            /* update our cache */
985                            if (xentry.pixel < 256)
986                            {
987                                    xc_cache[xentry.pixel].red = xentry.red;
988                                    xc_cache[xentry.pixel].green = xentry.green;
989                                    xc_cache[xentry.pixel].blue = xentry.blue;
990    
991                            }
992    
993    
994                            /* byte swap here to make translate_image faster */
995                            map[i] = translate_colour(colour);
996                    }
997                    return map;
998            }
999            else
1000          {          {
1001                  XColor *xcolours, *xentry;                  XColor *xcolours, *xentry;
1002                  Colormap map;                  Colormap map;
# Line 953  ui_create_colourmap(COLOURMAP * colours) Line 1016  ui_create_colourmap(COLOURMAP * colours)
1016                  xfree(xcolours);                  xfree(xcolours);
1017                  return (HCOLOURMAP) map;                  return (HCOLOURMAP) map;
1018          }          }
         else  
         {  
                 uint32 *map = xmalloc(sizeof(*colmap) * ncolours);  
                 XColor xentry;  
                 uint32 colour;  
   
                 for (i = 0; i < ncolours; i++)  
                 {  
                         entry = &colours->colours[i];  
                         MAKE_XCOLOR(&xentry, entry);  
   
                         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);  
                 }  
   
                 return map;  
         }  
1019  }  }
1020    
1021  void  void
1022  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
1023  {  {
1024          if (owncolmap)          if (!owncolmap)
                 XFreeColormap(display, (Colormap) map);  
         else  
1025                  xfree(map);                  xfree(map);
1026            else
1027                    XFreeColormap(display, (Colormap) map);
1028  }  }
1029    
1030  void  void
1031  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
1032  {  {
1033          if (owncolmap)          if (!owncolmap)
                 XSetWindowColormap(display, wnd, (Colormap) map);  
         else  
1034                  colmap = map;                  colmap = map;
1035            else
1036                    XSetWindowColormap(display, wnd, (Colormap) map);
1037  }  }
1038    
1039  void  void
# Line 1008  ui_set_clip(int x, int y, int cx, int cy Line 1049  ui_set_clip(int x, int y, int cx, int cy
1049  }  }
1050    
1051  void  void
1052  ui_reset_clip()  ui_reset_clip(void)
1053  {  {
1054          XRectangle rect;          XRectangle rect;
1055    
# Line 1020  ui_reset_clip() Line 1061  ui_reset_clip()
1061  }  }
1062    
1063  void  void
1064  ui_bell()  ui_bell(void)
1065  {  {
1066          XBell(display, 0);          XBell(display, 0);
1067  }  }
# Line 1060  ui_patblt(uint8 opcode, Line 1101  ui_patblt(uint8 opcode,
1101                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
1102                          XSetFillStyle(display, gc, FillOpaqueStippled);                          XSetFillStyle(display, gc, FillOpaqueStippled);
1103                          XSetStipple(display, gc, fill);                          XSetStipple(display, gc, fill);
1104                          XSetTSOrigin(display, gc, brush->xorigin,                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
                                      brush->yorigin);  
1105    
1106                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1107    
1108                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
1109                            XSetTSOrigin(display, gc, 0, 0);
1110                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
1111                          break;                          break;
1112    
# Line 1084  ui_screenblt(uint8 opcode, Line 1125  ui_screenblt(uint8 opcode,
1125          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1126          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1127          if (ownbackstore)          if (ownbackstore)
1128                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1129          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1130  }  }
1131    
# Line 1097  ui_memblt(uint8 opcode, Line 1137  ui_memblt(uint8 opcode,
1137          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1138          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1139          if (ownbackstore)          if (ownbackstore)
1140                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy,                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1141          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1142  }  }
1143    
# Line 1115  ui_triblt(uint8 opcode, Line 1154  ui_triblt(uint8 opcode,
1154          {          {
1155                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1156                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1157                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1158                          break;                          break;
1159    
1160                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1161                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1162                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1163                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1164                          break;                          break;
1165    
1166                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1167                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1168                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1169                          break;                          break;
1170    
1171                  default:                  default:
# Line 1161  ui_rect( Line 1196  ui_rect(
1196          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
1197  }  }
1198    
1199    /* warning, this function only draws on wnd or backstore, not both */
1200  void  void
1201  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1202                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1203                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1204                int fgcolour)                int bgcolour, int fgcolour)
1205  {  {
1206          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1207          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1208    
1209          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(display, gc,
1210                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1211          XSetStipple(display, gc, (Pixmap) glyph);          XSetStipple(display, gc, (Pixmap) glyph);
1212          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
1213    
1214          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
1215    
1216          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(display, gc, FillSolid);
1217  }  }
# Line 1189  ui_draw_glyph(int mixmode, Line 1225  ui_draw_glyph(int mixmode,
1225        if ((xyoffset & 0x80))\        if ((xyoffset & 0x80))\
1226          {\          {\
1227            if (flags & TEXT2_VERTICAL) \            if (flags & TEXT2_VERTICAL) \
1228              y += ttext[++idx] | (ttext[++idx] << 8);\              y += ttext[idx+1] | (ttext[idx+2] << 8);\
1229            else\            else\
1230              x += ttext[++idx] | (ttext[++idx] << 8);\              x += ttext[idx+1] | (ttext[idx+2] << 8);\
1231              idx += 2;\
1232          }\          }\
1233        else\        else\
1234          {\          {\
# Line 1203  ui_draw_glyph(int mixmode, Line 1240  ui_draw_glyph(int mixmode,
1240      }\      }\
1241    if (glyph != NULL)\    if (glyph != NULL)\
1242      {\      {\
1243        ui_draw_glyph (mixmode, x + (short) glyph->offset,\        ui_draw_glyph (mixmode, x + glyph->offset,\
1244                       y + (short) glyph->baseline,\                       y + glyph->baseline,\
1245                       glyph->width, glyph->height,\                       glyph->width, glyph->height,\
1246                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1247        if (flags & TEXT2_IMPLICIT_X)\        if (flags & TEXT2_IMPLICIT_X)\
# Line 1214  ui_draw_glyph(int mixmode, Line 1251  ui_draw_glyph(int mixmode,
1251    
1252  void  void
1253  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,
1254               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1255               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1256               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1257  {  {
1258          FONTGLYPH *glyph;          FONTGLYPH *glyph;
# Line 1226  ui_draw_text(uint8 font, uint8 flags, in Line 1263  ui_draw_text(uint8 font, uint8 flags, in
1263    
1264          if (boxcx > 1)          if (boxcx > 1)
1265          {          {
1266                  FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
1267          }          }
1268          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
1269          {          {
1270                  FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
1271          }          }
1272    
1273          /* Paint text, character by character */          /* Paint text, character by character */
# Line 1240  ui_draw_text(uint8 font, uint8 flags, in Line 1277  ui_draw_text(uint8 font, uint8 flags, in
1277                  {                  {
1278                          case 0xff:                          case 0xff:
1279                                  if (i + 2 < length)                                  if (i + 2 < length)
1280                                          cache_put_text(text[i + 1], text,                                          cache_put_text(text[i + 1], text, text[i + 2]);
                                                        text[i + 2]);  
1281                                  else                                  else
1282                                  {                                  {
1283                                          error("this shouldn't be happening\n");                                          error("this shouldn't be happening\n");
1284                                          break;                                          exit(1);
1285                                  }                                  }
1286                                  /* this will move pointer from start to first character after FF command */                                  /* this will move pointer from start to first character after FF command */
1287                                  length -= i + 3;                                  length -= i + 3;
# Line 1258  ui_draw_text(uint8 font, uint8 flags, in Line 1294  ui_draw_text(uint8 font, uint8 flags, in
1294                                  if (entry != NULL)                                  if (entry != NULL)
1295                                  {                                  {
1296                                          if ((((uint8 *) (entry->data))[1] ==                                          if ((((uint8 *) (entry->data))[1] ==
1297                                               0)                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
                                             && (!(flags & TEXT2_IMPLICIT_X)))  
1298                                          {                                          {
1299                                                  if (flags & TEXT2_VERTICAL)                                                  if (flags & TEXT2_VERTICAL)
1300                                                          y += text[i + 2];                                                          y += text[i + 2];
1301                                                  else                                                  else
1302                                                          x += text[i + 2];                                                          x += text[i + 2];
1303                                          }                                          }
                                         if (i + 2 < length)  
                                                 i += 3;  
                                         else  
                                                 i += 2;  
                                         length -= i;  
                                         /* this will move pointer from start to first character after FE command */  
                                         text = &(text[i]);  
                                         i = 0;  
1304                                          for (j = 0; j < entry->size; j++)                                          for (j = 0; j < entry->size; j++)
1305                                                  DO_GLYPH(((uint8 *) (entry->                                                  DO_GLYPH(((uint8 *) (entry->data)), j);
                                                                      data)),  
                                                          j);  
1306                                  }                                  }
1307                                    if (i + 2 < length)
1308                                            i += 3;
1309                                    else
1310                                            i += 2;
1311                                    length -= i;
1312                                    /* this will move pointer from start to first character after FE command */
1313                                    text = &(text[i]);
1314                                    i = 0;
1315                                  break;                                  break;
1316    
1317                          default:                          default:
# Line 1287  ui_draw_text(uint8 font, uint8 flags, in Line 1320  ui_draw_text(uint8 font, uint8 flags, in
1320                                  break;                                  break;
1321                  }                  }
1322          }          }
1323            if (ownbackstore)
1324            {
1325                    if (boxcx > 1)
1326                            XCopyArea(display, backstore, wnd, gc, boxx,
1327                                      boxy, boxcx, boxcy, boxx, boxy);
1328                    else
1329                            XCopyArea(display, backstore, wnd, gc, clipx,
1330                                      clipy, clipcx, clipcy, clipx, clipy);
1331            }
1332  }  }
1333    
1334  void  void
# Line 1299  ui_desktop_save(uint32 offset, int x, in Line 1339  ui_desktop_save(uint32 offset, int x, in
1339    
1340          if (ownbackstore)          if (ownbackstore)
1341          {          {
1342                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1343          }          }
1344          else          else
1345          {          {
1346                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(display, wnd, cx, cy, depth);
1347                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1348                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1349                  XFreePixmap(display, pix);                  XFreePixmap(display, pix);
1350          }          }
1351    
1352          offset *= bpp / 8;          offset *= bpp / 8;
1353          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);  
1354    
1355          XDestroyImage(image);          XDestroyImage(image);
1356  }  }
# Line 1329  ui_desktop_restore(uint32 offset, int x, Line 1366  ui_desktop_restore(uint32 offset, int x,
1366          if (data == NULL)          if (data == NULL)
1367                  return;                  return;
1368    
1369          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1370                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);
                              cx * bpp / 8);  
1371    
1372          if (ownbackstore)          if (ownbackstore)
1373          {          {

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

  ViewVC Help
Powered by ViewVC 1.1.26