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

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

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

revision 53 by matthewc, Tue May 28 11:48:55 2002 UTC revision 54 by n-ki, Fri Jun 7 07:49:59 2002 UTC
# Line 50  static BOOL ownbackstore; Line 50  static BOOL ownbackstore;
50  static Pixmap backstore;  static Pixmap backstore;
51    
52  /* needed to keep track of the modifiers */  /* needed to keep track of the modifiers */
53  static unsigned int key_modifier_state = 0;  static unsigned int numlock_modifier_mask = 0;
54  static unsigned int key_down_state = 0;  static unsigned int key_down_state = 0;
55    
56    
57  #define DShift1Mask   (1<<0)  #define DShift1Mask   (1<<0)
58  #define DShift2Mask   (1<<1)  #define DLockMask     (1<<1)
59  #define DControl1Mask (1<<2)  #define DControl1Mask (1<<2)
60  #define DControl2Mask (1<<3)  #define DMod1Mask     (1<<3)
61  #define DMod1Mask     (1<<4)  #define DMod2Mask     (1<<4)
62  #define DMod2Mask     (1<<5)  #define DMod3Mask     (1<<5)
63    #define DMod4Mask     (1<<6)
64    #define DMod5Mask     (1<<7)
65    #define DShift2Mask   (1<<8)
66    #define DControl2Mask (1<<9)
67    #define DNumLockMask  (1<<10)
68    
69  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
70  { \  { \
# Line 99  static int rop2_map[] = { Line 105  static int rop2_map[] = {
105  #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]); }
106  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
107    
108  void xwin_release_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode);  void xwin_get_numlock_mask();
109  void xwin_press_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode);  void xwin_mod_update(uint32 state, uint32 ev_time );
110    void xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode);
111    void xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode);
112    
113  static void  static void
114  translate8(uint8 *data, uint8 *out, uint8 *end)  translate8(uint8 *data, uint8 *out, uint8 *end)
# Line 221  ui_create_window(char *title) Line 229  ui_create_window(char *title)
229          }          }
230    
231    
         /* XKB is the 'new' keyboard handler in x.. ( the xkb code in Xfree86 originates from SGI, years 1993 and 1995 from what I could tell. )  
          * it makes it possible for people with disabilities to use rdesktop, stickykeys, bouncekeys etc. VERY MUCH useful.  
          * XFree86 has had support for it since it's earliest incarnation. I believe it is a reasonable dependency.  
          */  
232          display = XkbOpenDisplay( NULL, &xkb_event, &xkb_error, &xkb_major, &xkb_minor, &xkb_reason );          display = XkbOpenDisplay( NULL, &xkb_event, &xkb_error, &xkb_major, &xkb_minor, &xkb_reason );
233          switch(xkb_reason)          switch(xkb_reason)
234          {          {
# Line 338  ui_create_window(char *title) Line 342  ui_create_window(char *title)
342    
343          input_mask = KeyPressMask | KeyReleaseMask |          input_mask = KeyPressMask | KeyReleaseMask |
344                           ButtonPressMask | ButtonReleaseMask |                           ButtonPressMask | ButtonReleaseMask |
345                           EnterWindowMask | LeaveWindowMask | KeymapStateMask;                           EnterWindowMask | LeaveWindowMask;
346          if (sendmotion)          if (sendmotion)
347                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
348    
# Line 367  ui_create_window(char *title) Line 371  ui_create_window(char *title)
371                          error( "XkbSelectEvents failed.\n");                          error( "XkbSelectEvents failed.\n");
372                          exit(0);                          exit(0);
373          }          }
374            
375            xwin_get_numlock_mask();
376    
377          return True;          return True;
378  }  }
379    
380  void  void
381    xwin_get_numlock_mask()
382    {
383            KeyCode numlockcode;
384            KeyCode* keycode;
385            XModifierKeymap *modmap;
386            int i,j;
387    
388            /* Find out if numlock is already defined as a modifier key, and if so where */
389            numlockcode = XKeysymToKeycode(display, 0xFF7F);        /* XF_Num_Lock = 0xFF7F */
390            if (numlockcode) {
391                    modmap = XGetModifierMapping(display);
392                    if (modmap) {
393                            keycode = modmap->modifiermap;
394                            for (i = 0; i < 8; i++)
395                                    for (j = modmap->max_keypermod; j--;) {
396                                            if (*keycode == numlockcode) {
397                                                    numlock_modifier_mask = (1 << i);
398                                                    i = 8;
399                                                    break;
400                                            }
401                                            keycode++;
402                                    }
403                    if (!numlock_modifier_mask) {
404                                    modmap->modifiermap[7 * modmap->max_keypermod] = numlockcode;
405                                    if (XSetModifierMapping(display, modmap) == MappingSuccess)
406                                            numlock_modifier_mask = (1 << 7);
407                                    else
408                                            printf("XSetModifierMapping failed!\n");
409                            }
410                            XFreeModifiermap(modmap);
411                    }
412            }
413    
414            if (!numlock_modifier_mask)
415                    printf("WARNING: Failed to get a numlock modifier mapping.\n");
416                    
417    }
418    
419    void
420  ui_destroy_window()  ui_destroy_window()
421  {  {
422          if( xkb != NULL )          if( xkb != NULL )
# Line 389  ui_destroy_window() Line 434  ui_destroy_window()
434  static void  static void
435  xwin_process_events()  xwin_process_events()
436  {  {
437          XkbEvent xkbevent;          XEvent xevent;
438            
439          KeySym keysym;          KeySym keysym;
440          uint8 scancode;          uint8 scancode;
441          uint16 button, flags;          uint16 button, flags;
442          uint32 ev_time;          uint32 ev_time;
443          uint32 tmpmods;          uint32 tmpmods;
444    
445          while (XCheckMaskEvent(display, ~0, &xkbevent.core))          while (XCheckMaskEvent(display, ~0, &xevent))
446          {          {
447                  ev_time = time(NULL);                  ev_time = time(NULL);
448                  flags = 0;                  flags = 0;
449    
450                  switch (xkbevent.type)                  switch (xevent.type)
451                  {                  {
                         case KeymapNotify:  
                                 /* TODO:  
                                  * read modifier status at focus in, and update the local masks, and the other end as well..  
                                  * if not, we may get out of sync.  
                                  * xkbevent.core.xkeymap.key_vector  
                                  * char key_vector[32];  
                                  */  
                                 break;  
   
452                          case KeyRelease:                          case KeyRelease:
453                                  flags = KBD_FLAG_DOWN | KBD_FLAG_UP;                                  flags = KBD_FLAG_DOWN | KBD_FLAG_UP;
454                                  /* fall through */                                  /* fall through */
   
455                          case KeyPress:                          case KeyPress:
456                                  if( XkbTranslateKeyCode(xkb, xkbevent.core.xkey.keycode, xkbevent.core.xkey.state, &tmpmods, &keysym) == False )                                  if( XkbTranslateKeyCode(xkb, xevent.xkey.keycode, xevent.xkey.state, &tmpmods, &keysym) == False )
457                                          break;                                          break;
458                                  scancode = xkeymap_translate_key(keysym, xkbevent.core.xkey.keycode, &flags);                                  scancode = xkeymap_translate_key(keysym, xevent.xkey.keycode, &flags);
459    
460                                  if (scancode == 0 )                                  if (scancode == 0 )
461                                          break;                                          break;
462    
463                                  /* keep track of the modifiers -- needed for stickykeys... */                                  /* keep track of the modifiers -- needed for stickykeys... */
464                                  if( xkbevent.type == KeyPress )                                  if( xevent.type == KeyPress )
465                                          xwin_press_modifiers( &xkbevent.core.xkey, ev_time, scancode );                                          xwin_mod_press( xevent.xkey.state, ev_time, scancode );
466    
467                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, flags, scancode, 0);                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, flags, scancode, 0);
468    
469                                  if( xkbevent.type == KeyRelease )                                  if( xevent.type == KeyRelease )
470                                          xwin_release_modifiers( &xkbevent.core.xkey, ev_time, scancode );                                          xwin_mod_release( xevent.xkey.state, ev_time, scancode );
471    
472                                  break;                                  break;
473    
# Line 441  xwin_process_events() Line 476  xwin_process_events()
476                                  /* fall through */                                  /* fall through */
477    
478                          case ButtonRelease:                          case ButtonRelease:
479                                  button = xkeymap_translate_button(xkbevent.core.xbutton.button);                                  button = xkeymap_translate_button(xevent.xbutton.button);
480                                  if (button == 0)                                  if (button == 0)
481                                          break;                                          break;
482    
483                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
484                                                 flags | button,                                                 flags | button,
485                                                 xkbevent.core.xbutton.x,                                                 xevent.xbutton.x,
486                                                 xkbevent.core.xbutton.y);                                                 xevent.xbutton.y);
487                                  break;                                  break;
488    
489                          case MotionNotify:                          case MotionNotify:
490                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
491                                                 MOUSE_FLAG_MOVE,                                                 MOUSE_FLAG_MOVE,
492                                                 xkbevent.core.xmotion.x,                                                 xevent.xmotion.x,
493                                                 xkbevent.core.xmotion.y);                                                 xevent.xmotion.y);
494                                  break;                                  break;
495    
496                          case EnterNotify:                          case EnterNotify:
497                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,
498                                                GrabModeAsync, CurrentTime);                                                GrabModeAsync, CurrentTime);
499    
500                                     xwin_mod_update( xevent.xcrossing.state, ev_time );
501                                  break;                                  break;
502    
503                          case LeaveNotify:                          case LeaveNotify:
# Line 469  xwin_process_events() Line 506  xwin_process_events()
506    
507                          case Expose:                          case Expose:
508                                  XCopyArea(display, backstore, wnd, gc,                                  XCopyArea(display, backstore, wnd, gc,
509                                            xkbevent.core.xexpose.x, xkbevent.core.xexpose.y,                                            xevent.xexpose.x, xevent.xexpose.y,
510                                            xkbevent.core.xexpose.width, xkbevent.core.xexpose.height,                                            xevent.xexpose.width, xevent.xexpose.height,
511                                            xkbevent.core.xexpose.x, xkbevent.core.xexpose.y);                                            xevent.xexpose.x, xevent.xexpose.y);
512                                  break;                                  break;
513                  }                  }
514          }          }
515  }  }
516    
517  void  void
518  xwin_release_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode)  xwin_mod_update(uint32 state, uint32 ev_time )
519    {
520            xwin_mod_press(state, ev_time, 0);
521            xwin_mod_release(state, ev_time, 0);
522    }
523    
524    void
525    xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode)
526  {  {
527          switch (scancode) {          switch (scancode) {
528          case 0x2a:          case 0x2a:
# Line 501  xwin_release_modifiers(XKeyEvent* ev, ui Line 545  xwin_release_modifiers(XKeyEvent* ev, ui
545                  break;                  break;
546          }          }
547    
548          if( !(ShiftMask & ev->state) && (key_down_state & DShift1Mask))          if( !(numlock_modifier_mask & state) && (key_down_state & DNumLockMask) )
549            {
550                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);
551                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);
552                    key_down_state &= ~DNumLockMask;
553            }
554    
555            if( !(LockMask & state) && (key_down_state & DLockMask))
556            {
557                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);
558                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);
559                    key_down_state &= ~DLockMask;
560    
561            }
562    
563    
564            if( !(ShiftMask & state) && (key_down_state & DShift1Mask))
565          {          {
566                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a, 0);                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a, 0);
567                  key_down_state &= ~DShift1Mask;                  key_down_state &= ~DShift1Mask;
568    
569          }          }
570    
571          if( !(ControlMask & ev->state) && (key_down_state & DControl1Mask))          if( !(ControlMask & state) && (key_down_state & DControl1Mask))
572          {          {
573                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d, 0);                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d, 0);
574                  key_down_state &= ~DControl1Mask;                  key_down_state &= ~DControl1Mask;
575    
576          }          }
577            
578          if( !(Mod1Mask & ev->state) && (key_down_state & DMod1Mask))          if( !(Mod1Mask & state) && (key_down_state & DMod1Mask))
579          {          {
580                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38, 0);                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38, 0);
581                  key_down_state &= ~DMod1Mask;                  key_down_state &= ~DMod1Mask;
582    
583          }          }
584            
585          if( !(Mod2Mask & ev->state) && (key_down_state & DMod2Mask))          if( !(Mod2Mask & state) && (key_down_state & DMod2Mask))
586          {          {
587                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8, 0);                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8, 0);
588                  key_down_state &= ~DMod2Mask;                  key_down_state &= ~DMod2Mask;
# Line 531  xwin_release_modifiers(XKeyEvent* ev, ui Line 591  xwin_release_modifiers(XKeyEvent* ev, ui
591    
592    
593  void  void
594  xwin_press_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode)  xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode)
595  {  {
         key_modifier_state = ev->state;  
596    
597          switch (scancode) {          switch (scancode) {
598          case 0x2a:          case 0x2a:
# Line 548  xwin_press_modifiers(XKeyEvent* ev, uint Line 607  xwin_press_modifiers(XKeyEvent* ev, uint
607          case 0x9d:          case 0x9d:
608                  key_down_state |= DControl2Mask;                  key_down_state |= DControl2Mask;
609                  break;                  break;
610            case 0x3a:
611                    key_down_state ^= DLockMask;
612                    break;
613            case 0x45:
614                    key_down_state ^= DNumLockMask;
615                    break;
616          case 0x38:          case 0x38:
617                  key_down_state |= DMod1Mask;                  key_down_state |= DMod1Mask;
618                  break;                  break;
# Line 556  xwin_press_modifiers(XKeyEvent* ev, uint Line 621  xwin_press_modifiers(XKeyEvent* ev, uint
621                  break;                  break;
622          }          }
623    
624          if( (ShiftMask & ev->state) && !((key_down_state & DShift1Mask) || (key_down_state & DShift2Mask)))          if( (numlock_modifier_mask && state) && !(key_down_state & DNumLockMask) )
625            {
626                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);
627                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);
628                    key_down_state |= DNumLockMask;
629            }
630    
631            if( (LockMask & state) && !(key_down_state & DLockMask))
632            {
633                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);
634                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);
635                    key_down_state |= DLockMask;
636    
637            }
638    
639    
640            if( (ShiftMask & state) && !((key_down_state & DShift1Mask) || (key_down_state & DShift2Mask)))
641          {          {
642                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x2a, 0);                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x2a, 0);
643                  key_down_state |= DShift1Mask;                  key_down_state |= DShift1Mask;
644    
645          }          }
646    
647          if( (ControlMask & ev->state) && !((key_down_state & DControl1Mask) || (key_down_state & DControl2Mask)))          if( (ControlMask & state) && !((key_down_state & DControl1Mask) || (key_down_state & DControl2Mask)))
648          {          {
649                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x1d, 0);                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x1d, 0);
650                  key_down_state |= DControl1Mask;                  key_down_state |= DControl1Mask;
651    
652          }          }
653    
654          if( (Mod1Mask & ev->state) && !(key_down_state & DMod1Mask))          if( (Mod1Mask & state) && !(key_down_state & DMod1Mask))
655          {          {
656                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x38, 0);                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x38, 0);
657                  key_down_state |= DMod1Mask;                  key_down_state |= DMod1Mask;
658    
659          }          }
660    
661          if( (Mod2Mask & ev->state) && !(key_down_state & DMod2Mask))          if( (Mod2Mask & state) && !(key_down_state & DMod2Mask))
662          {          {
663                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0xb8, 0);                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0xb8, 0);
664                  key_down_state |= DMod2Mask;                  key_down_state |= DMod2Mask;

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

  ViewVC Help
Powered by ViewVC 1.1.26