/[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 101 by astrand, Mon Aug 26 17:12:43 2002 UTC
# 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    #define XK_MISCELLANY
26    #include <X11/keysymdef.h>
27  #include "rdesktop.h"  #include "rdesktop.h"
28    #include "scancodes.h"
29    
 extern char keymapname[16];  
 extern int keylayout;  
30  extern int width;  extern int width;
31  extern int height;  extern int height;
32  extern BOOL sendmotion;  extern BOOL sendmotion;
33  extern BOOL fullscreen;  extern BOOL fullscreen;
34    extern BOOL grab_keyboard;
35    extern char title[];
36    
37  Display *display;  Display *display = NULL;
 XkbDescPtr xkb;  
38  static int x_socket;  static int x_socket;
39  static Window wnd;  static Window wnd;
40  static GC gc;  static GC gc;
41  static Visual *visual;  static Visual *visual;
42  static int depth;  static int depth;
43  static int bpp;  static int bpp;
44    static int dpy_width;
45    static int dpy_height;
46    
47  /* endianness */  /* endianness */
48  static BOOL host_be;  static BOOL host_be;
# Line 49  static BOOL xserver_be; Line 52  static BOOL xserver_be;
52  static BOOL ownbackstore;  static BOOL ownbackstore;
53  static Pixmap backstore;  static Pixmap backstore;
54    
 /* needed to keep track of the modifiers */  
 static unsigned int numlock_modifier_mask = 0;  
 static unsigned int key_down_state = 0;  
   
   
 #define DShift1Mask   (1<<0)  
 #define DLockMask     (1<<1)  
 #define DControl1Mask (1<<2)  
 #define DMod1Mask     (1<<3)  
 #define DMod2Mask     (1<<4)  
 #define DMod3Mask     (1<<5)  
 #define DMod4Mask     (1<<6)  
 #define DMod5Mask     (1<<7)  
 #define DShift2Mask   (1<<8)  
 #define DControl2Mask (1<<9)  
 #define DNumLockMask  (1<<10)  
   
55  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
56  { \  { \
57          XFillRectangle(display, wnd, gc, x, y, cx, cy); \          XFillRectangle(display, wnd, gc, x, y, cx, cy); \
# Line 78  static BOOL owncolmap; Line 64  static BOOL owncolmap;
64  static Colormap xcolmap;  static Colormap xcolmap;
65  static uint32 white;  static uint32 white;
66  static uint32 *colmap;  static uint32 *colmap;
67    static XIM IM = NULL;
68    static XIC IC = NULL;
69    
70    /* Compose support */
71    BOOL enable_compose = False;
72    
73    /* toggle fullscreen globals */
74    static XSetWindowAttributes attribs;
75    static unsigned long input_mask;
76    
77  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )
78  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));
# Line 105  static int rop2_map[] = { Line 100  static int rop2_map[] = {
100  #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]); }
101  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
102    
 void xwin_get_numlock_mask();  
 void xwin_mod_update(uint32 state, uint32 ev_time);  
 void xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode);  
 void xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode);  
   
103  static void  static void
104  translate8(uint8 * data, uint8 * out, uint8 * end)  translate8(uint8 * data, uint8 * out, uint8 * end)
105  {  {
# Line 204  translate_colour(uint32 colour) Line 194  translate_colour(uint32 colour)
194          return colour;          return colour;
195  }  }
196    
197  BOOL  static unsigned long
198  ui_create_window(char *title)  init_inputmethod(void)
199  {  {
200          XSetWindowAttributes attribs;          unsigned long filtered_events = 0;
         XClassHint *classhints;  
         XSizeHints *sizehints;  
         unsigned long input_mask;  
         XPixmapFormatValues *pfm;  
         Screen *screen;  
         uint16 test;  
         int i;  
201    
202          int xkb_minor, xkb_major;          IM = XOpenIM(display, NULL, NULL, NULL);
203          int xkb_event, xkb_error, xkb_reason;          if (IM == NULL)
204            {
205                    error("Failed to open input method\n");
206            }
207    
208          /* compare compiletime libs with runtime libs. */          if (IM != NULL)
         xkb_major = XkbMajorVersion;  
         xkb_minor = XkbMinorVersion;  
         if (XkbLibraryVersion(&xkb_major, &xkb_minor) == False)  
209          {          {
210                  error("please re-compile rdesktop\ncompile time version of xkb is not compatible with\nyour runtime version of the library\n");                  /* Must be done after XCreateWindow */
211                  return False;                  IC = XCreateIC(IM, XNInputStyle,
212                                   (XIMPreeditNothing | XIMStatusNothing),
213                                   XNClientWindow, wnd, XNFocusWindow, wnd, NULL);
214    
215                    if (IC == NULL)
216                    {
217                            error("Failed to create input context\n");
218                            XCloseIM(IM);
219                            IM = NULL;
220                    }
221          }          }
222    
223            /* For correct Multi_key/Compose processing, I guess.
224               It seems to work alright anyway, though. */
225            if (IC != NULL)
226            {
227                    if (XGetICValues(IC, XNFilterEvents, &filtered_events, NULL) != NULL)
228                    {
229                            error("Failed to obtain XNFilterEvents value from IC\n");
230                            filtered_events = 0;
231                    }
232            }
233            return filtered_events;
234    }
235    
236          display =  static void
237                  XkbOpenDisplay(NULL, &xkb_event, &xkb_error, &xkb_major,  close_inputmethod(void)
238                                 &xkb_minor, &xkb_reason);  {
239          switch (xkb_reason)          if (IC != NULL)
240          {          {
241                  case XkbOD_BadLibraryVersion:                  XDestroyIC(IC);
242                          error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n");                  if (IM != NULL)
243                          break;                  {
244                  case XkbOD_ConnectionRefused:                          XCloseIM(IM);
245                          error("XkbOD_ConnectionRefused\n");                          IM = NULL;
246                          break;                  }
                 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;  
247          }          }
248    }
249    
250    BOOL
251    ui_init()
252    {
253            Screen *screen;
254            display = XOpenDisplay(NULL);
255          if (display == NULL)          if (display == NULL)
256          {          {
257                  error("Failed to open display\n");                  error("Failed to open display\n");
258                  return False;                  return False;
259          }          }
260            if (fullscreen)
261            {
262                    screen = DefaultScreenOfDisplay(display);
263                    width = WidthOfScreen(screen);
264                    height = HeightOfScreen(screen);
265            }
266            return True;
267    }
268    
269    BOOL
270    ui_create_window_obj(int xpos, int ypos, int width, int height, int valuemask)
271    {
272            XClassHint *classhints;
273            XSizeHints *sizehints;
274            XEvent xevent;
275            Screen *screen;
276    
277            screen = DefaultScreenOfDisplay(display);
278    
279            wnd = XCreateWindow(display, RootWindowOfScreen(screen), xpos,
280                                ypos, width, height, 0, CopyFromParent,
281                                InputOutput, CopyFromParent, valuemask, &attribs);
282    
283    
284            XStoreName(display, wnd, title);
285    
286            classhints = XAllocClassHint();
287            if (classhints != NULL)
288            {
289                    classhints->res_name = classhints->res_class = "rdesktop";
290                    XSetClassHint(display, wnd, classhints);
291                    XFree(classhints);
292            }
293    
294            sizehints = XAllocSizeHints();
295            if (sizehints)
296            {
297                    sizehints->flags = PMinSize | PMaxSize;
298                    sizehints->min_width = sizehints->max_width = width;
299                    sizehints->min_height = sizehints->max_height = height;
300                    XSetWMNormalHints(display, wnd, sizehints);
301                    XFree(sizehints);
302            }
303    
304            if (enable_compose)
305                    input_mask |= init_inputmethod();
306    
307            XSelectInput(display, wnd, input_mask);
308    
309            gc = XCreateGC(display, wnd, 0, NULL);
310    
311            XMapWindow(display, wnd);
312    
313            /* Wait for VisibilityNotify Event */
314            for (;;)
315            {
316                    XNextEvent(display, &xevent);
317                    if (xevent.type == VisibilityNotify)
318                            break;
319            }
320    
321            if (ownbackstore)
322                    backstore = XCreatePixmap(display, wnd, width, height, depth);
323    
324            /* clear the window so that cached data is not viewed upon start... */
325            XSetBackground(display, gc, 0);
326            XSetForeground(display, gc, 0);
327            FILL_RECTANGLE(0, 0, width, height);
328            /* make sure the window is focused */
329            XSetInputFocus(display, wnd, RevertToPointerRoot, CurrentTime);
330    }
331    
332    BOOL
333    ui_create_window()
334    {
335            XPixmapFormatValues *pfm;
336            Screen *screen;
337            uint16 test;
338            int i;
339    
340          x_socket = ConnectionNumber(display);          x_socket = ConnectionNumber(display);
341          screen = DefaultScreenOfDisplay(display);          screen = DefaultScreenOfDisplay(display);
# Line 269  ui_create_window(char *title) Line 349  ui_create_window(char *title)
349                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
350                  while (i--)                  while (i--)
351                  {                  {
352                          if ((pfm[i].depth == depth)                          if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))
                             && (pfm[i].bits_per_pixel > bpp))  
353                          {                          {
354                                  bpp = pfm[i].bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
355                          }                          }
# Line 301  ui_create_window(char *title) Line 380  ui_create_window(char *title)
380          if (attribs.backing_store == NotUseful)          if (attribs.backing_store == NotUseful)
381                  ownbackstore = True;                  ownbackstore = True;
382    
383            dpy_width = WidthOfScreen(screen);
384            dpy_height = HeightOfScreen(screen);
385    
386          if (fullscreen)          if (fullscreen)
387          {          {
388                  attribs.override_redirect = True;                  attribs.override_redirect = True;
389                  width = WidthOfScreen(screen);                  width = dpy_width;
390                  height = HeightOfScreen(screen);                  height = dpy_height;
391          }          }
392          else          else
393          {          {
# Line 314  ui_create_window(char *title) Line 396  ui_create_window(char *title)
396    
397          width = (width + 3) & ~3;       /* make width a multiple of 32 bits */          width = (width + 3) & ~3;       /* make width a multiple of 32 bits */
398    
         wnd = XCreateWindow(display, RootWindowOfScreen(screen),  
                             0, 0, width, height, 0, CopyFromParent,  
                             InputOutput, CopyFromParent,  
                             CWBackingStore | CWBackPixel | CWOverrideRedirect,  
                             &attribs);  
399    
400          XStoreName(display, wnd, title);          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
401                    VisibilityChangeMask | FocusChangeMask;
         classhints = XAllocClassHint();  
         if (classhints != NULL)  
         {  
                 classhints->res_name = classhints->res_class = "rdesktop";  
                 XSetClassHint(display, wnd, classhints);  
                 XFree(classhints);  
         }  
402    
403          sizehints = XAllocSizeHints();          if (grab_keyboard)
404          if (sizehints)                  input_mask |= EnterWindowMask | LeaveWindowMask;
         {  
                 sizehints->flags = PMinSize | PMaxSize;  
                 sizehints->min_width = sizehints->max_width = width;  
                 sizehints->min_height = sizehints->max_height = height;  
                 XSetWMNormalHints(display, wnd, sizehints);  
                 XFree(sizehints);  
         }  
   
         xkeymap_init();  
   
         input_mask = KeyPressMask | KeyReleaseMask |  
                 ButtonPressMask | ButtonReleaseMask |  
                 EnterWindowMask | LeaveWindowMask;  
405          if (sendmotion)          if (sendmotion)
406                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
407    
408          if (ownbackstore)          if (ownbackstore)
409                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
410    
411          XSelectInput(display, wnd, input_mask);          if (fullscreen)
412          gc = XCreateGC(display, wnd, 0, NULL);                  ui_create_window_obj(0, 0, width, height,
413                                         CWBackingStore | CWBackPixel | CWOverrideRedirect);
414          if (ownbackstore)          else
415                  backstore = XCreatePixmap(display, wnd, width, height, depth);                  ui_create_window_obj(0, 0, width, height, CWBackingStore | CWBackPixel);
   
         XMapWindow(display, wnd);  
   
         /* TODO: error texts... make them friendly. */  
         xkb = XkbGetKeyboard(display, XkbAllComponentsMask, XkbUseCoreKbd);  
         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)  
         {  
                 error("XkbSelectEvents failed.\n");  
                 exit(0);  
         }  
416    
417          xwin_get_numlock_mask();          xkeymap_init2();
418    
419          return True;          return True;
420  }  }
421    
422  void  void
423  xwin_get_numlock_mask()  ui_destroy_window()
424  {  {
425          KeyCode numlockcode;          if (ownbackstore)
426          KeyCode *keycode;                  XFreePixmap(display, backstore);
         XModifierKeymap *modmap;  
         int i, j;  
427    
428          /* Find out if numlock is already defined as a modifier key, and if so where */          XFreeGC(display, gc);
         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);  
                 }  
         }  
429    
430          if (!numlock_modifier_mask)          close_inputmethod();
                 printf("WARNING: Failed to get a numlock modifier mapping.\n");  
431    
432            XDestroyWindow(display, wnd);
433            XCloseDisplay(display);
434            display = NULL;
435  }  }
436    
437  void  void
438  ui_destroy_window()  reset_keys()
439  {  {
440          if (xkb != NULL)          /* reset keys */
441                  XkbFreeKeyboard(xkb, XkbAllControlsMask, True);          uint32 ev_time;
442            ev_time = time(NULL);
443            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
444            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT);
445            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
446            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);
447            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
448            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
449    }
450    
451    void
452    toggle_fullscreen()
453    {
454            /* save window contents */
455            Pixmap pixmap;
456            pixmap = XCreatePixmap(display, wnd, width, height, depth);
457            if (ownbackstore)
458                    XCopyArea(display, backstore, pixmap, gc, 0, 0, width, height, 0, 0);
459            else
460                    XCopyArea(display, wnd, pixmap, gc, 0, 0, width, height, 0, 0);
461            fullscreen = fullscreen ? False : True;
462            close_inputmethod();
463          if (ownbackstore)          if (ownbackstore)
464                  XFreePixmap(display, backstore);                  XFreePixmap(display, backstore);
   
465          XFreeGC(display, gc);          XFreeGC(display, gc);
466          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
467          XCloseDisplay(display);          if (fullscreen)
468          display = NULL;          {
469                    attribs.override_redirect = True;
470                    ui_create_window_obj(0, 0, dpy_width, dpy_height,
471                                         CWBackingStore | CWBackPixel | CWOverrideRedirect);
472            }
473            else
474            {
475                    attribs.override_redirect = False;
476                    ui_create_window_obj(0, 0, width, height, CWBackingStore | CWBackPixel);
477            }
478            ui_set_cursor(cache_get_cursor(0));
479            ui_move_pointer(width / 2, height / 2);
480            reset_keys();
481            /* restore window contents */
482            if (ownbackstore)
483                    XCopyArea(display, pixmap, backstore, gc, 0, 0, width, height, 0, 0);
484            XCopyArea(display, pixmap, wnd, gc, 0, 0, width, height, 0, 0);
485            XFreePixmap(display, pixmap);
486  }  }
487    
488  static void  static void
# Line 450  xwin_process_events() Line 491  xwin_process_events()
491          XEvent xevent;          XEvent xevent;
492    
493          KeySym keysym;          KeySym keysym;
         uint8 scancode;  
494          uint16 button, flags;          uint16 button, flags;
495          uint32 ev_time;          uint32 ev_time;
496          uint32 tmpmods;          key_translation tr;
497            char *ksname = NULL;
498            char str[256];
499            Status status;
500    
501            /* Refresh keyboard mapping if it has changed. This is important for
502               Xvnc, since it allocates keycodes dynamically */
503            if (XCheckTypedEvent(display, MappingNotify, &xevent))
504            {
505                    if (xevent.xmapping.request == MappingKeyboard
506                        || xevent.xmapping.request == MappingModifier)
507                            XRefreshKeyboardMapping(&xevent.xmapping);
508            }
509    
510          while (XCheckMaskEvent(display, ~0, &xevent))          while (XCheckMaskEvent(display, ~0, &xevent))
511          {          {
512                    if (enable_compose && (XFilterEvent(&xevent, None) == True))
513                    {
514                            DEBUG_KBD(("Filtering event\n"));
515                            continue;
516                    }
517    
518                  ev_time = time(NULL);                  ev_time = time(NULL);
519                  flags = 0;                  flags = 0;
520    
521                  switch (xevent.type)                  switch (xevent.type)
522                  {                  {
                         case KeyRelease:  
                                 flags = KBD_FLAG_DOWN | KBD_FLAG_UP;  
                                 /* fall through */  
523                          case KeyPress:                          case KeyPress:
524                                  if (XkbTranslateKeyCode                                  if (IC != NULL)
525                                      (xkb, xevent.xkey.keycode,                                          /* Multi_key compatible version */
526                                       xevent.xkey.state, &tmpmods,                                  {
527                                       &keysym) == False)                                          XmbLookupString(IC,
528                                                            (XKeyPressedEvent *) &
529                                                            xevent, str, sizeof(str), &keysym, &status);
530                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
531                                            {
532                                                    error("XmbLookupString failed with status 0x%x\n",
533                                                          status);
534                                                    break;
535                                            }
536                                    }
537                                    else
538                                    {
539                                            /* Plain old XLookupString */
540                                            DEBUG_KBD(("No input context, using XLookupString\n"));
541                                            XLookupString((XKeyEvent *) & xevent,
542                                                          str, sizeof(str), &keysym, NULL);
543                                    }
544    
545                                    /* FIXME needs alt modifier */
546                                    if (keysym == XK_Break) /* toggle full screen */
547                                    {
548                                            toggle_fullscreen();
549                                            break;
550                                    }
551                                    ksname = get_ksname(keysym);
552                                    DEBUG_KBD(("\nKeyPress for (keysym 0x%lx, %s)\n", keysym, ksname));
553    
554                                    if (inhibit_key(keysym))
555                                    {
556                                            DEBUG_KBD(("Inhibiting key\n"));
557                                            break;
558                                    }
559    
560                                    tr = xkeymap_translate_key(keysym,
561                                                               xevent.xkey.keycode, xevent.xkey.state);
562    
563                                    ensure_remote_modifiers(ev_time, tr);
564    
565                                    if (tr.scancode == 0)
566                                          break;                                          break;
                                 scancode =  
                                         xkeymap_translate_key(keysym,  
                                                               xevent.xkey.  
                                                               keycode,  
                                                               &flags);  
567    
568                                  if (scancode == 0)                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
569                                    break;
570                            case KeyRelease:
571                                    XLookupString((XKeyEvent *) & xevent, str,
572                                                  sizeof(str), &keysym, NULL);
573    
574                                    ksname = get_ksname(keysym);
575                                    DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
576                                               ksname));
577    
578                                    if (inhibit_key(keysym))
579                                          break;                                          break;
580    
581                                  /* keep track of the modifiers -- needed for stickykeys... */                                  tr = xkeymap_translate_key(keysym,
582                                  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);  
583    
584                                    if (tr.scancode == 0)
585                                            break;
586    
587                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
588                                  break;                                  break;
589    
590                          case ButtonPress:                          case ButtonPress:
# Line 499  xwin_process_events() Line 592  xwin_process_events()
592                                  /* fall through */                                  /* fall through */
593    
594                          case ButtonRelease:                          case ButtonRelease:
595                                  button = xkeymap_translate_button(xevent.                                  button = xkeymap_translate_button(xevent.xbutton.button);
                                                                   xbutton.  
                                                                   button);  
596                                  if (button == 0)                                  if (button == 0)
597                                          break;                                          break;
598    
599                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
600                                                 flags | button,                                                 flags | button, xevent.xbutton.x, xevent.xbutton.y);
                                                xevent.xbutton.x,  
                                                xevent.xbutton.y);  
601                                  break;                                  break;
602    
603                          case MotionNotify:                          case MotionNotify:
604                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
605                                                 MOUSE_FLAG_MOVE,                                                 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
                                                xevent.xmotion.x,  
                                                xevent.xmotion.y);  
606                                  break;                                  break;
607    
608                            case FocusIn:
609                                    /* fall through */
610                          case EnterNotify:                          case EnterNotify:
611                                  XGrabKeyboard(display, wnd, True,                                  if (grab_keyboard)
612                                                GrabModeAsync, GrabModeAsync,                                          XGrabKeyboard(display, wnd, True,
613                                                CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
   
                                 xwin_mod_update(xevent.xcrossing.state,  
                                                 ev_time);  
614                                  break;                                  break;
615    
616                            case FocusOut:
617                                    reset_keys();
618                                    /* fall through */
619                          case LeaveNotify:                          case LeaveNotify:
620                                  XUngrabKeyboard(display, CurrentTime);                                  if (grab_keyboard)
621                                            XUngrabKeyboard(display, CurrentTime);
622                                  break;                                  break;
623    
624                          case Expose:                          case Expose:
# Line 543  xwin_process_events() Line 633  xwin_process_events()
633  }  }
634    
635  void  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;  
   
         }  
   
         if ((Mod2Mask & state) && !(key_down_state & DMod2Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,  
                                0xb8, 0);  
                 key_down_state |= DMod2Mask;  
   
         }  
 }  
   
 void  
636  ui_select(int rdp_socket)  ui_select(int rdp_socket)
637  {  {
638          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
# Line 764  ui_create_bitmap(int width, int height, Line 682  ui_create_bitmap(int width, int height,
682    
683          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
684          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
685          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
686                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, 8, 0);
687    
688          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
689    
# Line 776  ui_create_bitmap(int width, int height, Line 694  ui_create_bitmap(int width, int height,
694  }  }
695    
696  void  void
697  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)  
698  {  {
699          XImage *image;          XImage *image;
700          uint8 *tdata;          uint8 *tdata;
701    
702          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
703          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
704                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, 8, 0);
705    
706          if (ownbackstore)          if (ownbackstore)
707          {          {
# Line 820  ui_create_glyph(int width, int height, u Line 737  ui_create_glyph(int width, int height, u
737          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
738          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
739    
740          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
741                               data, width, height, 8, scanline);                               width, height, 8, scanline);
742          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
743          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
744          XInitImage(image);          XInitImage(image);
# Line 840  ui_destroy_glyph(HGLYPH glyph) Line 757  ui_destroy_glyph(HGLYPH glyph)
757  }  }
758    
759  HCURSOR  HCURSOR
760  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
761                   int height, uint8 * andmask, uint8 * xormask)                   uint8 * andmask, uint8 * xormask)
762  {  {
763          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
764          XColor bg, fg;          XColor bg, fg;
# Line 899  ui_create_cursor(unsigned int x, unsigne Line 816  ui_create_cursor(unsigned int x, unsigne
816          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
817          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
818    
819          xcursor = XCreatePixmapCursor(display, (Pixmap) cursorglyph,          xcursor =
820                                        (Pixmap) maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(display, (Pixmap) cursorglyph,
821                                        (Pixmap) maskglyph, &fg, &bg, x, y);
822    
823          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
824          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
# Line 1060  ui_patblt(uint8 opcode, Line 978  ui_patblt(uint8 opcode,
978                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
979                          XSetFillStyle(display, gc, FillOpaqueStippled);                          XSetFillStyle(display, gc, FillOpaqueStippled);
980                          XSetStipple(display, gc, fill);                          XSetStipple(display, gc, fill);
981                          XSetTSOrigin(display, gc, brush->xorigin,                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
                                      brush->yorigin);  
982    
983                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
984    
985                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
986                            XSetTSOrigin(display, gc, 0, 0);
987                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
988                          break;                          break;
989    
# Line 1084  ui_screenblt(uint8 opcode, Line 1002  ui_screenblt(uint8 opcode,
1002          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1003          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1004          if (ownbackstore)          if (ownbackstore)
1005                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1006          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1007  }  }
1008    
# Line 1097  ui_memblt(uint8 opcode, Line 1014  ui_memblt(uint8 opcode,
1014          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1015          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1016          if (ownbackstore)          if (ownbackstore)
1017                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy,                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1018          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1019  }  }
1020    
# Line 1115  ui_triblt(uint8 opcode, Line 1031  ui_triblt(uint8 opcode,
1031          {          {
1032                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1033                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1034                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1035                          break;                          break;
1036    
1037                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1038                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1039                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1040                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1041                          break;                          break;
1042    
1043                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1044                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1045                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1046                          break;                          break;
1047    
1048                  default:                  default:
# Line 1164  ui_rect( Line 1076  ui_rect(
1076  void  void
1077  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1078                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1079                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1080                int fgcolour)                int bgcolour, int fgcolour)
1081  {  {
1082          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1083          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1084    
1085          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(display, gc,
1086                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1087          XSetStipple(display, gc, (Pixmap) glyph);          XSetStipple(display, gc, (Pixmap) glyph);
1088          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
1089    
# Line 1189  ui_draw_glyph(int mixmode, Line 1101  ui_draw_glyph(int mixmode,
1101        if ((xyoffset & 0x80))\        if ((xyoffset & 0x80))\
1102          {\          {\
1103            if (flags & TEXT2_VERTICAL) \            if (flags & TEXT2_VERTICAL) \
1104              y += ttext[++idx] | (ttext[++idx] << 8);\              y += ttext[idx+1] | (ttext[idx+2] << 8);\
1105            else\            else\
1106              x += ttext[++idx] | (ttext[++idx] << 8);\              x += ttext[idx+1] | (ttext[idx+2] << 8);\
1107              idx += 2;\
1108          }\          }\
1109        else\        else\
1110          {\          {\
# Line 1214  ui_draw_glyph(int mixmode, Line 1127  ui_draw_glyph(int mixmode,
1127    
1128  void  void
1129  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,
1130               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1131               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1132               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1133  {  {
1134          FONTGLYPH *glyph;          FONTGLYPH *glyph;
# Line 1240  ui_draw_text(uint8 font, uint8 flags, in Line 1153  ui_draw_text(uint8 font, uint8 flags, in
1153                  {                  {
1154                          case 0xff:                          case 0xff:
1155                                  if (i + 2 < length)                                  if (i + 2 < length)
1156                                          cache_put_text(text[i + 1], text,                                          cache_put_text(text[i + 1], text, text[i + 2]);
                                                        text[i + 2]);  
1157                                  else                                  else
1158                                  {                                  {
1159                                          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 1170  ui_draw_text(uint8 font, uint8 flags, in
1170                                  if (entry != NULL)                                  if (entry != NULL)
1171                                  {                                  {
1172                                          if ((((uint8 *) (entry->data))[1] ==                                          if ((((uint8 *) (entry->data))[1] ==
1173                                               0)                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
                                             && (!(flags & TEXT2_IMPLICIT_X)))  
1174                                          {                                          {
1175                                                  if (flags & TEXT2_VERTICAL)                                                  if (flags & TEXT2_VERTICAL)
1176                                                          y += text[i + 2];                                                          y += text[i + 2];
# Line 1275  ui_draw_text(uint8 font, uint8 flags, in Line 1186  ui_draw_text(uint8 font, uint8 flags, in
1186                                          text = &(text[i]);                                          text = &(text[i]);
1187                                          i = 0;                                          i = 0;
1188                                          for (j = 0; j < entry->size; j++)                                          for (j = 0; j < entry->size; j++)
1189                                                  DO_GLYPH(((uint8 *) (entry->                                                  DO_GLYPH(((uint8 *) (entry->data)), j);
                                                                      data)),  
                                                          j);  
1190                                  }                                  }
1191                                  break;                                  break;
1192    
# Line 1299  ui_desktop_save(uint32 offset, int x, in Line 1208  ui_desktop_save(uint32 offset, int x, in
1208    
1209          if (ownbackstore)          if (ownbackstore)
1210          {          {
1211                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1212          }          }
1213          else          else
1214          {          {
1215                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(display, wnd, cx, cy, depth);
1216                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1217                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1218                  XFreePixmap(display, pix);                  XFreePixmap(display, pix);
1219          }          }
1220    
1221          offset *= bpp / 8;          offset *= bpp / 8;
1222          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);  
1223    
1224          XDestroyImage(image);          XDestroyImage(image);
1225  }  }
# Line 1329  ui_desktop_restore(uint32 offset, int x, Line 1235  ui_desktop_restore(uint32 offset, int x,
1235          if (data == NULL)          if (data == NULL)
1236                  return;                  return;
1237    
1238          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1239                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);
                              cx * bpp / 8);  
1240    
1241          if (ownbackstore)          if (ownbackstore)
1242          {          {

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

  ViewVC Help
Powered by ViewVC 1.1.26