/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/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/branches/seamlessrdp-branch/rdesktop/xwin.c

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

revision 49 by mmihalik, Fri Apr 19 12:06:08 2002 UTC revision 64 by astrand, Thu Jul 18 16:38:31 2002 UTC
# Line 2  Line 2 
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-2001
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
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# Line 20  Line 20 
20    
21  #include <X11/Xlib.h>  #include <X11/Xlib.h>
22  #include <X11/Xutil.h>  #include <X11/Xutil.h>
23    #include <X11/XKBlib.h>
24  #include <time.h>  #include <time.h>
25  #include <errno.h>  #include <errno.h>
26  #include "rdesktop.h"  #include "rdesktop.h"
# Line 31  extern int height; Line 32  extern int height;
32  extern BOOL sendmotion;  extern BOOL sendmotion;
33  extern BOOL fullscreen;  extern BOOL fullscreen;
34    
35  static Display *display;  Display *display;
36    XkbDescPtr xkb;
37  static int x_socket;  static int x_socket;
38  static Window wnd;  static Window wnd;
39  static GC gc;  static GC gc;
# Line 47  static BOOL xserver_be; Line 49  static BOOL xserver_be;
49  static BOOL ownbackstore;  static BOOL ownbackstore;
50  static Pixmap backstore;  static Pixmap backstore;
51    
52    /* needed to keep track of the modifiers */
53    static unsigned int numlock_modifier_mask = 0;
54    static unsigned int key_down_state = 0;
55    
56    
57    #define DShift1Mask   (1<<0)
58    #define DLockMask     (1<<1)
59    #define DControl1Mask (1<<2)
60    #define DMod1Mask     (1<<3)
61    #define DMod2Mask     (1<<4)
62    #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  { \  { \
71          XFillRectangle(display, wnd, gc, x, y, cx, cy); \          XFillRectangle(display, wnd, gc, x, y, cx, cy); \
# Line 86  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_get_numlock_mask();
109    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)
115  {  {
116          while (out < end)          while (out < end)
117                  *(out++) = (uint8)colmap[*(data++)];                  *(out++) = (uint8) colmap[*(data++)];
118  }  }
119    
120  static void  static void
121  translate16(uint8 *data, uint16 *out, uint16 *end)  translate16(uint8 * data, uint16 * out, uint16 * end)
122  {  {
123          while (out < end)          while (out < end)
124                  *(out++) = (uint16)colmap[*(data++)];                  *(out++) = (uint16) colmap[*(data++)];
125  }  }
126    
127  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
128  static void  static void
129  translate24(uint8 *data, uint8 *out, uint8 *end)  translate24(uint8 * data, uint8 * out, uint8 * end)
130  {  {
131          uint32 value;          uint32 value;
132    
# Line 116  translate24(uint8 *data, uint8 *out, uin Line 140  translate24(uint8 *data, uint8 *out, uin
140  }  }
141    
142  static void  static void
143  translate32(uint8 *data, uint32 *out, uint32 *end)  translate32(uint8 * data, uint32 * out, uint32 * end)
144  {  {
145          while (out < end)          while (out < end)
146                  *(out++) = colmap[*(data++)];                  *(out++) = colmap[*(data++)];
147  }  }
148    
149  static uint8 *  static uint8 *
150  translate_image(int width, int height, uint8 *data)  translate_image(int width, int height, uint8 * data)
151  {  {
152          int size = width * height * bpp/8;          int size = width * height * bpp / 8;
153          uint8 *out = xmalloc(size);          uint8 *out = xmalloc(size);
154          uint8 *end = out + size;          uint8 *end = out + size;
155    
# Line 136  translate_image(int width, int height, u Line 160  translate_image(int width, int height, u
160                          break;                          break;
161    
162                  case 16:                  case 16:
163                          translate16(data, (uint16 *)out, (uint16 *)end);                          translate16(data, (uint16 *) out, (uint16 *) end);
164                          break;                          break;
165    
166                  case 24:                  case 24:
# Line 144  translate_image(int width, int height, u Line 168  translate_image(int width, int height, u
168                          break;                          break;
169    
170                  case 32:                  case 32:
171                          translate32(data, (uint32 *)out, (uint32 *)end);                          translate32(data, (uint32 *) out, (uint32 *) end);
172                          break;                          break;
173          }          }
174    
# Line 192  ui_create_window(char *title) Line 216  ui_create_window(char *title)
216          uint16 test;          uint16 test;
217          int i;          int i;
218    
219          display = XOpenDisplay(NULL);          int xkb_minor, xkb_major;
220            int xkb_event, xkb_error, xkb_reason;
221    
222            /* compare compiletime libs with runtime libs. */
223            xkb_major = XkbMajorVersion;
224            xkb_minor = XkbMinorVersion;
225            if (XkbLibraryVersion(&xkb_major, &xkb_minor) == False)
226            {
227                    error("please re-compile rdesktop\ncompile time version of xkb is not compatible with\nyour runtime version of the library\n");
228                    return False;
229            }
230    
231    
232            display =
233                    XkbOpenDisplay(NULL, &xkb_event, &xkb_error, &xkb_major,
234                                   &xkb_minor, &xkb_reason);
235            switch (xkb_reason)
236            {
237                    case XkbOD_BadLibraryVersion:
238                            error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n");
239                            break;
240                    case XkbOD_ConnectionRefused:
241                            error("XkbOD_ConnectionRefused\n");
242                            break;
243                    case XkbOD_BadServerVersion:
244                            error("XkbOD_BadServerVersion\n");
245                            break;
246                    case XkbOD_NonXkbServer:
247                            error("XkbOD_NonXkbServer: XKB extension not present in server\nupdate your X server.\n");
248                            break;
249                    case XkbOD_Success:
250                            DEBUG("XkbOD_Success: Connection established with display\n");
251                            break;
252            }
253    
254          if (display == NULL)          if (display == NULL)
255          {          {
256                  error("Failed to open display\n");                  error("Failed to open display\n");
# Line 233  ui_create_window(char *title) Line 291  ui_create_window(char *title)
291                  xcolmap = DefaultColormapOfScreen(screen);                  xcolmap = DefaultColormapOfScreen(screen);
292    
293          test = 1;          test = 1;
294          host_be = !(BOOL)(*(uint8 *)(&test));          host_be = !(BOOL) (*(uint8 *) (&test));
295          xserver_be = (ImageByteOrder(display) == MSBFirst);          xserver_be = (ImageByteOrder(display) == MSBFirst);
296    
297          white = WhitePixelOfScreen(screen);          white = WhitePixelOfScreen(screen);
# Line 254  ui_create_window(char *title) Line 312  ui_create_window(char *title)
312                  attribs.override_redirect = False;                  attribs.override_redirect = False;
313          }          }
314    
315          width = (width + 3) & ~3; /* make width a multiple of 32 bits */          width = (width + 3) & ~3;       /* make width a multiple of 32 bits */
316    
317          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          wnd = XCreateWindow(display, RootWindowOfScreen(screen),
318                              0, 0, width, height, 0, CopyFromParent,                              0, 0, width, height, 0, CopyFromParent,
# Line 282  ui_create_window(char *title) Line 340  ui_create_window(char *title)
340                  XFree(sizehints);                  XFree(sizehints);
341          }          }
342    
343          xkeymap_init(display);          xkeymap_init();
   
         input_mask = KeyPressMask | KeyReleaseMask  
                         | ButtonPressMask | ButtonReleaseMask  
                         | EnterWindowMask | LeaveWindowMask;  
344    
345            input_mask = KeyPressMask | KeyReleaseMask |
346                    ButtonPressMask | ButtonReleaseMask |
347                    EnterWindowMask | LeaveWindowMask;
348          if (sendmotion)          if (sendmotion)
349                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
350    
# Line 301  ui_create_window(char *title) Line 358  ui_create_window(char *title)
358                  backstore = XCreatePixmap(display, wnd, width, height, depth);                  backstore = XCreatePixmap(display, wnd, width, height, depth);
359    
360          XMapWindow(display, wnd);          XMapWindow(display, wnd);
361    
362            /* TODO: error texts... make them friendly. */
363            xkb = XkbGetKeyboard(display, XkbAllComponentsMask, XkbUseCoreKbd);
364            if ((int) xkb == BadAlloc || xkb == NULL)
365            {
366                    error("XkbGetKeyboard failed.\n");
367                    exit(0);
368            }
369    
370            /* TODO: error texts... make them friendly. */
371            if (XkbSelectEvents
372                (display, xkb->device_spec, XkbAllEventsMask,
373                 XkbAllEventsMask) == False)
374            {
375                    error("XkbSelectEvents failed.\n");
376                    exit(0);
377            }
378    
379            xwin_get_numlock_mask();
380    
381          return True;          return True;
382  }  }
383    
384  void  void
385    xwin_get_numlock_mask()
386    {
387            KeyCode numlockcode;
388            KeyCode *keycode;
389            XModifierKeymap *modmap;
390            int i, j;
391    
392            /* Find out if numlock is already defined as a modifier key, and if so where */
393            numlockcode = XKeysymToKeycode(display, 0xFF7F);        /* XF_Num_Lock = 0xFF7F */
394            if (numlockcode)
395            {
396                    modmap = XGetModifierMapping(display);
397                    if (modmap)
398                    {
399                            keycode = modmap->modifiermap;
400                            for (i = 0; i < 8; i++)
401                                    for (j = modmap->max_keypermod; j--;)
402                                    {
403                                            if (*keycode == numlockcode)
404                                            {
405                                                    numlock_modifier_mask =
406                                                            (1 << i);
407                                                    i = 8;
408                                                    break;
409                                            }
410                                            keycode++;
411                                    }
412                            if (!numlock_modifier_mask)
413                            {
414                                    modmap->modifiermap[7 *
415                                                        modmap->max_keypermod] =
416                                            numlockcode;
417                                    if (XSetModifierMapping(display, modmap) ==
418                                        MappingSuccess)
419                                            numlock_modifier_mask = (1 << 7);
420                                    else
421                                            printf("XSetModifierMapping failed!\n");
422                            }
423                            XFreeModifiermap(modmap);
424                    }
425            }
426    
427            if (!numlock_modifier_mask)
428                    printf("WARNING: Failed to get a numlock modifier mapping.\n");
429    
430    }
431    
432    void
433  ui_destroy_window()  ui_destroy_window()
434  {  {
435            if (xkb != NULL)
436                    XkbFreeKeyboard(xkb, XkbAllControlsMask, True);
437    
438          if (ownbackstore)          if (ownbackstore)
439                  XFreePixmap(display, backstore);                  XFreePixmap(display, backstore);
440    
# Line 319  ui_destroy_window() Line 447  ui_destroy_window()
447  static void  static void
448  xwin_process_events()  xwin_process_events()
449  {  {
450          XEvent event;          XEvent xevent;
451    
452          KeySym keysym;          KeySym keysym;
453          uint8 scancode;          uint8 scancode;
454          uint16 button;          uint16 button, flags;
455          uint32 ev_time;          uint32 ev_time;
456            uint32 tmpmods;
457    
458          if (display == NULL)          while (XCheckMaskEvent(display, ~0, &xevent))
                 return;  
   
         while (XCheckMaskEvent(display, ~0, &event))  
459          {          {
460                  ev_time = time(NULL);                  ev_time = time(NULL);
461                    flags = 0;
462    
463                  switch (event.type)                  switch (xevent.type)
464                  {                  {
465                            case KeyRelease:
466                                    flags = KBD_FLAG_DOWN | KBD_FLAG_UP;
467                                    /* fall through */
468                          case KeyPress:                          case KeyPress:
469                                  keysym = XKeycodeToKeysym(display, event.xkey.keycode, 0);                                  if (XkbTranslateKeyCode
470                                  scancode = xkeymap_translate_key(keysym, event.xkey.keycode);                                      (xkb, xevent.xkey.keycode,
471                                  if (scancode == 0)                                       xevent.xkey.state, &tmpmods,
472                                         &keysym) == False)
473                                          break;                                          break;
474                                    scancode =
475                                            xkeymap_translate_key(keysym,
476                                                                  xevent.xkey.
477                                                                  keycode,
478                                                                  &flags);
479    
                                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,  
                                                scancode, 0);  
                                 break;  
   
                         case KeyRelease:  
                                 keysym = XKeycodeToKeysym(display, event.xkey.keycode, 0);  
                                 scancode = xkeymap_translate_key(keysym, event.xkey.keycode);  
480                                  if (scancode == 0)                                  if (scancode == 0)
481                                          break;                                          break;
482    
483                                    /* keep track of the modifiers -- needed for stickykeys... */
484                                    if (xevent.type == KeyPress)
485                                            xwin_mod_press(xevent.xkey.state,
486                                                           ev_time, scancode);
487    
488                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
489                                                 KBD_FLAG_DOWN | KBD_FLAG_UP,                                                 flags, scancode, 0);
                                                scancode, 0);  
                                 break;  
490    
491                          case ButtonPress:                                  if (xevent.type == KeyRelease)
492                                  button = xkeymap_translate_button(event.xbutton.button);                                          xwin_mod_release(xevent.xkey.state,
493                                  if (button == 0)                                                           ev_time, scancode);
                                         break;  
494    
                                 rdp_send_input(ev_time, RDP_INPUT_MOUSE,  
                                                button | MOUSE_FLAG_DOWN,  
                                                event.xbutton.x,  
                                                event.xbutton.y);  
495                                  break;                                  break;
496    
497                            case ButtonPress:
498                                    flags = MOUSE_FLAG_DOWN;
499                                    /* fall through */
500    
501                          case ButtonRelease:                          case ButtonRelease:
502                                  button = xkeymap_translate_button(event.xbutton.button);                                  button = xkeymap_translate_button(xevent.
503                                                                      xbutton.
504                                                                      button);
505                                  if (button == 0)                                  if (button == 0)
506                                          break;                                          break;
507    
508                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
509                                                 button,                                                 flags | button,
510                                                 event.xbutton.x,                                                 xevent.xbutton.x,
511                                                 event.xbutton.y);                                                 xevent.xbutton.y);
512                                  break;                                  break;
513    
514                          case MotionNotify:                          case MotionNotify:
515                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
516                                                 MOUSE_FLAG_MOVE,                                                 MOUSE_FLAG_MOVE,
517                                                 event.xmotion.x,                                                 xevent.xmotion.x,
518                                                 event.xmotion.y);                                                 xevent.xmotion.y);
519                                  break;                                  break;
520    
521                          case EnterNotify:                          case EnterNotify:
522                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,                                  XGrabKeyboard(display, wnd, True,
523                                                GrabModeAsync, CurrentTime);                                                GrabModeAsync, GrabModeAsync,
524                                                  CurrentTime);
525    
526                                    xwin_mod_update(xevent.xcrossing.state,
527                                                    ev_time);
528                                  break;                                  break;
529    
530                          case LeaveNotify:                          case LeaveNotify:
# Line 395  xwin_process_events() Line 533  xwin_process_events()
533    
534                          case Expose:                          case Expose:
535                                  XCopyArea(display, backstore, wnd, gc,                                  XCopyArea(display, backstore, wnd, gc,
536                                            event.xexpose.x, event.xexpose.y,                                            xevent.xexpose.x, xevent.xexpose.y,
537                                            event.xexpose.width, event.xexpose.height,                                            xevent.xexpose.width,
538                                            event.xexpose.x, event.xexpose.y);                                            xevent.xexpose.height,
539                                              xevent.xexpose.x, xevent.xexpose.y);
540                                  break;                                  break;
541                  }                  }
542          }          }
543  }  }
544    
545  void  void
546    xwin_mod_update(uint32 state, uint32 ev_time)
547    {
548            xwin_mod_press(state, ev_time, 0);
549            xwin_mod_release(state, ev_time, 0);
550    }
551    
552    void
553    xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode)
554    {
555            switch (scancode)
556            {
557                    case 0x2a:
558                            key_down_state &= ~DShift1Mask;
559                            break;
560                    case 0x36:
561                            key_down_state &= ~DShift2Mask;
562                            break;
563                    case 0x1d:
564                            key_down_state &= ~DControl1Mask;
565                            break;
566                    case 0x9d:
567                            key_down_state &= ~DControl2Mask;
568                            break;
569                    case 0x38:
570                            key_down_state &= ~DMod1Mask;
571                            break;
572                    case 0xb8:
573                            key_down_state &= ~DMod2Mask;
574                            break;
575            }
576    
577            if (!(numlock_modifier_mask & state)
578                && (key_down_state & DNumLockMask))
579            {
580                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);
581                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
582                                   KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);
583                    key_down_state &= ~DNumLockMask;
584            }
585    
586            if (!(LockMask & state) && (key_down_state & DLockMask))
587            {
588                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);
589                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
590                                   KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);
591                    key_down_state &= ~DLockMask;
592    
593            }
594    
595    
596            if (!(ShiftMask & state) && (key_down_state & DShift1Mask))
597            {
598                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a,
599                                   0);
600                    key_down_state &= ~DShift1Mask;
601    
602            }
603    
604            if (!(ControlMask & state) && (key_down_state & DControl1Mask))
605            {
606                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d,
607                                   0);
608                    key_down_state &= ~DControl1Mask;
609    
610            }
611    
612            if (!(Mod1Mask & state) && (key_down_state & DMod1Mask))
613            {
614                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38,
615                                   0);
616                    key_down_state &= ~DMod1Mask;
617    
618            }
619    
620            if (!(Mod2Mask & state) && (key_down_state & DMod2Mask))
621            {
622                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8,
623                                   0);
624                    key_down_state &= ~DMod2Mask;
625            }
626    }
627    
628    
629    void
630    xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode)
631    {
632    
633            switch (scancode)
634            {
635                    case 0x2a:
636                            key_down_state |= DShift1Mask;
637                            break;
638                    case 0x36:
639                            key_down_state |= DShift2Mask;
640                            break;
641                    case 0x1d:
642                            key_down_state |= DControl1Mask;
643                            break;
644                    case 0x9d:
645                            key_down_state |= DControl2Mask;
646                            break;
647                    case 0x3a:
648                            key_down_state ^= DLockMask;
649                            break;
650                    case 0x45:
651                            key_down_state ^= DNumLockMask;
652                            break;
653                    case 0x38:
654                            key_down_state |= DMod1Mask;
655                            break;
656                    case 0xb8:
657                            key_down_state |= DMod2Mask;
658                            break;
659            }
660    
661            if ((numlock_modifier_mask && state)
662                && !(key_down_state & DNumLockMask))
663            {
664                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);
665                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
666                                   KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);
667                    key_down_state |= DNumLockMask;
668            }
669    
670            if ((LockMask & state) && !(key_down_state & DLockMask))
671            {
672                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);
673                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
674                                   KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);
675                    key_down_state |= DLockMask;
676    
677            }
678    
679    
680            if ((ShiftMask & state)
681                && !((key_down_state & DShift1Mask)
682                     || (key_down_state & DShift2Mask)))
683            {
684                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,
685                                   0x2a, 0);
686                    key_down_state |= DShift1Mask;
687    
688            }
689    
690            if ((ControlMask & state)
691                && !((key_down_state & DControl1Mask)
692                     || (key_down_state & DControl2Mask)))
693            {
694                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,
695                                   0x1d, 0);
696                    key_down_state |= DControl1Mask;
697    
698            }
699    
700            if ((Mod1Mask & state) && !(key_down_state & DMod1Mask))
701            {
702                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,
703                                   0x38, 0);
704                    key_down_state |= DMod1Mask;
705    
706            }
707    
708            if ((Mod2Mask & state) && !(key_down_state & DMod2Mask))
709            {
710                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,
711                                   0xb8, 0);
712                    key_down_state |= DMod2Mask;
713    
714            }
715    }
716    
717    void
718  ui_select(int rdp_socket)  ui_select(int rdp_socket)
719  {  {
720          int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
721          fd_set rfds;          fd_set rfds;
722    
         XFlush(display);  
   
723          FD_ZERO(&rfds);          FD_ZERO(&rfds);
724    
725          while (True)          while (True)
726          {          {
727                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
728                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
729                  FD_SET(x_socket, &rfds);                  if (display != NULL)
730                    {
731                            FD_SET(x_socket, &rfds);
732                            XFlush(display);
733                    }
734    
735                  switch (select(n, &rfds, NULL, NULL, NULL))                  switch (select(n, &rfds, NULL, NULL, NULL))
736                  {                  {
# Line 443  ui_move_pointer(int x, int y) Line 756  ui_move_pointer(int x, int y)
756  }  }
757    
758  HBITMAP  HBITMAP
759  ui_create_bitmap(int width, int height, uint8 *data)  ui_create_bitmap(int width, int height, uint8 * data)
760  {  {
761          XImage *image;          XImage *image;
762          Pixmap bitmap;          Pixmap bitmap;
# Line 464  ui_create_bitmap(int width, int height, Line 777  ui_create_bitmap(int width, int height,
777    
778  void  void
779  ui_paint_bitmap(int x, int y, int cx, int cy,  ui_paint_bitmap(int x, int y, int cx, int cy,
780                  int width, int height, uint8 *data)                  int width, int height, uint8 * data)
781  {  {
782          XImage *image;          XImage *image;
783          uint8 *tdata;          uint8 *tdata;
# Line 491  ui_paint_bitmap(int x, int y, int cx, in Line 804  ui_paint_bitmap(int x, int y, int cx, in
804  void  void
805  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
806  {  {
807          XFreePixmap(display, (Pixmap)bmp);          XFreePixmap(display, (Pixmap) bmp);
808  }  }
809    
810  HGLYPH  HGLYPH
811  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 * data)
812  {  {
813          XImage *image;          XImage *image;
814          Pixmap bitmap;          Pixmap bitmap;
# Line 517  ui_create_glyph(int width, int height, u Line 830  ui_create_glyph(int width, int height, u
830    
831          XFree(image);          XFree(image);
832          XFreeGC(display, gc);          XFreeGC(display, gc);
833          return (HGLYPH)bitmap;          return (HGLYPH) bitmap;
834  }  }
835    
836  void  void
837  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
838  {  {
839          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(display, (Pixmap) glyph);
840  }  }
841    
842  HCURSOR  HCURSOR
843  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width,
844                   int height, uint8 *andmask, uint8 *xormask)                   int height, uint8 * andmask, uint8 * xormask)
845  {  {
846          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
847          XColor bg, fg;          XColor bg, fg;
# Line 585  ui_create_cursor(unsigned int x, unsigne Line 898  ui_create_cursor(unsigned int x, unsigne
898    
899          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
900          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
901            
902          xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,          xcursor = XCreatePixmapCursor(display, (Pixmap) cursorglyph,
903                                  (Pixmap)maskglyph, &fg, &bg, x, y);                                        (Pixmap) maskglyph, &fg, &bg, x, y);
904    
905          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
906          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
907          xfree(mask);          xfree(mask);
908          xfree(cursor);          xfree(cursor);
909          return (HCURSOR)xcursor;          return (HCURSOR) xcursor;
910  }  }
911    
912  void  void
913  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
914  {  {
915          XDefineCursor(display, wnd, (Cursor)cursor);          XDefineCursor(display, wnd, (Cursor) cursor);
916  }  }
917    
918  void  void
919  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
920  {  {
921          XFreeCursor(display, (Cursor)cursor);          XFreeCursor(display, (Cursor) cursor);
922  }  }
923    
924  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 615  ui_destroy_cursor(HCURSOR cursor) Line 928  ui_destroy_cursor(HCURSOR cursor)
928                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
929    
930  HCOLOURMAP  HCOLOURMAP
931  ui_create_colourmap(COLOURMAP *colours)  ui_create_colourmap(COLOURMAP * colours)
932  {  {
933          COLOURENTRY *entry;          COLOURENTRY *entry;
934          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
# Line 638  ui_create_colourmap(COLOURMAP *colours) Line 951  ui_create_colourmap(COLOURMAP *colours)
951                  XStoreColors(display, map, xcolours, ncolours);                  XStoreColors(display, map, xcolours, ncolours);
952    
953                  xfree(xcolours);                  xfree(xcolours);
954                  return (HCOLOURMAP)map;                  return (HCOLOURMAP) map;
955          }          }
956          else          else
957          {          {
# Line 668  void Line 981  void
981  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
982  {  {
983          if (owncolmap)          if (owncolmap)
984                  XFreeColormap(display, (Colormap)map);                  XFreeColormap(display, (Colormap) map);
985          else          else
986                  xfree(map);                  xfree(map);
987  }  }
# Line 677  void Line 990  void
990  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
991  {  {
992          if (owncolmap)          if (owncolmap)
993                  XSetWindowColormap(display, wnd, (Colormap)map);                  XSetWindowColormap(display, wnd, (Colormap) map);
994          else          else
995                  colmap = map;                  colmap = map;
996  }  }
# Line 724  ui_destblt(uint8 opcode, Line 1037  ui_destblt(uint8 opcode,
1037  void  void
1038  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
1039            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1040            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1041  {  {
1042          Pixmap fill;          Pixmap fill;
1043            uint8 i, ipattern[8];
1044    
1045          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1046    
# Line 738  ui_patblt(uint8 opcode, Line 1052  ui_patblt(uint8 opcode,
1052                          break;                          break;
1053    
1054                  case 3: /* Pattern */                  case 3: /* Pattern */
1055                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);                          for (i = 0; i != 8; i++)
1056                                    ipattern[7 - i] = brush->pattern[i];
1057                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
1058    
1059                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
1060                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
1061                          XSetFillStyle(display, gc, FillOpaqueStippled);                          XSetFillStyle(display, gc, FillOpaqueStippled);
1062                          XSetStipple(display, gc, fill);                          XSetStipple(display, gc, fill);
1063                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(display, gc, brush->xorigin,
1064                                         brush->yorigin);
1065    
1066                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1067    
1068                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
1069                          ui_destroy_glyph((HGLYPH)fill);                          ui_destroy_glyph((HGLYPH) fill);
1070                          break;                          break;
1071    
1072                  default:                  default:
# Line 778  ui_memblt(uint8 opcode, Line 1095  ui_memblt(uint8 opcode,
1095            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1096  {  {
1097          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1098          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1099          if (ownbackstore)          if (ownbackstore)
1100                  XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy,
1101                            cx, cy, x, y);                            cx, cy, x, y);
1102          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1103  }  }
# Line 789  void Line 1106  void
1106  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
1107            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1108            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ HBITMAP src, int srcx, int srcy,
1109            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1110  {  {
1111          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
1112             comes up with a more efficient way of doing it I am using cases. */             comes up with a more efficient way of doing it I am using cases. */
# Line 825  ui_triblt(uint8 opcode, Line 1142  ui_triblt(uint8 opcode,
1142  void  void
1143  ui_line(uint8 opcode,  ui_line(uint8 opcode,
1144          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
1145          /* pen */ PEN *pen)          /* pen */ PEN * pen)
1146  {  {
1147          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1148          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
# Line 855  ui_draw_glyph(int mixmode, Line 1172  ui_draw_glyph(int mixmode,
1172    
1173          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)
1174                        ? FillStippled : FillOpaqueStippled);                        ? FillStippled : FillOpaqueStippled);
1175          XSetStipple(display, gc, (Pixmap)glyph);          XSetStipple(display, gc, (Pixmap) glyph);
1176          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
1177    
1178          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
# Line 917  ui_draw_text(uint8 font, uint8 flags, in Line 1234  ui_draw_text(uint8 font, uint8 flags, in
1234          }          }
1235    
1236          /* Paint text, character by character */          /* Paint text, character by character */
1237          for (i = 0; i < length;) {          for (i = 0; i < length;)
1238                  switch (text[i]) {          {
1239                  case 0xff:                  switch (text[i])
1240                          if (i + 2 < length)                  {
1241                                  cache_put_text(text[i + 1], text, text[i + 2]);                          case 0xff:
1242                          else {                                  if (i + 2 < length)
1243                                  error("this shouldn't be happening\n");                                          cache_put_text(text[i + 1], text,
1244                                                           text[i + 2]);
1245                                    else
1246                                    {
1247                                            error("this shouldn't be happening\n");
1248                                            break;
1249                                    }
1250                                    /* this will move pointer from start to first character after FF command */
1251                                    length -= i + 3;
1252                                    text = &(text[i + 3]);
1253                                    i = 0;
1254                                  break;                                  break;
                         }  
                         /* this will move pointer from start to first character after FF command */  
                         length -= i + 3;  
                         text = &(text[i + 3]);  
                         i = 0;  
                         break;  
1255    
1256                  case 0xfe:                          case 0xfe:
1257                          entry = cache_get_text(text[i + 1]);                                  entry = cache_get_text(text[i + 1]);
1258                          if (entry != NULL) {                                  if (entry != NULL)
1259                                  if ((((uint8 *) (entry->data))[1] == 0)                                  {
1260                                      && (!(flags & TEXT2_IMPLICIT_X))) {                                          if ((((uint8 *) (entry->data))[1] ==
1261                                          if (flags & TEXT2_VERTICAL)                                                     0)
1262                                                  y += text[i + 2];                                              && (!(flags & TEXT2_IMPLICIT_X)))
1263                                            {
1264                                                    if (flags & TEXT2_VERTICAL)
1265                                                            y += text[i + 2];
1266                                                    else
1267                                                            x += text[i + 2];
1268                                            }
1269                                            if (i + 2 < length)
1270                                                    i += 3;
1271                                          else                                          else
1272                                                  x += text[i + 2];                                                  i += 2;
1273                                            length -= i;
1274                                            /* this will move pointer from start to first character after FE command */
1275                                            text = &(text[i]);
1276                                            i = 0;
1277                                            for (j = 0; j < entry->size; j++)
1278                                                    DO_GLYPH(((uint8 *) (entry->
1279                                                                         data)),
1280                                                             j);
1281                                  }                                  }
1282                                  if (i + 2 < length)                                  break;
                                         i += 3;  
                                 else  
                                         i += 2;  
                                 length -= i;    
                                 /* this will move pointer from start to first character after FE command */  
                                 text = &(text[i]);  
                                 i = 0;  
                                 for (j = 0; j < entry->size; j++)  
                                         DO_GLYPH(((uint8 *) (entry->data)), j);  
                         }  
                         break;  
1283    
1284                  default:                          default:
1285                          DO_GLYPH(text, i);                                  DO_GLYPH(text, i);
1286                          i++;                                  i++;
1287                          break;                                  break;
1288                  }                  }
1289          }          }
1290    
# Line 985  ui_desktop_save(uint32 offset, int x, in Line 1311  ui_desktop_save(uint32 offset, int x, in
1311                  XFreePixmap(display, pix);                  XFreePixmap(display, pix);
1312          }          }
1313    
1314          offset *= bpp/8;          offset *= bpp / 8;
1315          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line,
1316                            bpp/8, (uint8 *)image->data);                            bpp / 8, (uint8 *) image->data);
1317    
1318          XDestroyImage(image);          XDestroyImage(image);
1319  }  }
# Line 998  ui_desktop_restore(uint32 offset, int x, Line 1324  ui_desktop_restore(uint32 offset, int x,
1324          XImage *image;          XImage *image;
1325          uint8 *data;          uint8 *data;
1326    
1327          offset *= bpp/8;          offset *= bpp / 8;
1328          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp / 8);
1329          if (data == NULL)          if (data == NULL)
1330                  return;                  return;
1331    
1332          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap,
1333                               0, data, cx, cy, BitmapPad(display),                               0, data, cx, cy, BitmapPad(display),
1334                               cx * bpp/8);                               cx * bpp / 8);
1335    
1336          if (ownbackstore)          if (ownbackstore)
1337          {          {

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

  ViewVC Help
Powered by ViewVC 1.1.26