/[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 1370 by stargo, Thu Jan 4 23:38:35 2007 UTC revision 1417 by jsorg71, Thu Aug 30 04:47:36 2007 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-2007     Copyright (C) Matthew Chapman 1999-2007
5       Copyright 2007 Pierre Ossman <ossman@cendio.se> for Cendio AB
6    
7     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 20  Line 21 
21    
22  #include <X11/Xlib.h>  #include <X11/Xlib.h>
23  #include <X11/Xutil.h>  #include <X11/Xutil.h>
 #define BOOL XPROTO_BOOL  
24  #include <X11/Xproto.h>  #include <X11/Xproto.h>
 #undef BOOL  
25  #include <unistd.h>  #include <unistd.h>
26  #include <sys/time.h>  #include <sys/time.h>
27  #include <time.h>  #include <time.h>
# Line 36  extern int g_height; Line 35  extern int g_height;
35  extern int g_xpos;  extern int g_xpos;
36  extern int g_ypos;  extern int g_ypos;
37  extern int g_pos;  extern int g_pos;
38  extern BOOL g_sendmotion;  extern RD_BOOL g_sendmotion;
39  extern BOOL g_fullscreen;  extern RD_BOOL g_fullscreen;
40  extern BOOL g_grab_keyboard;  extern RD_BOOL g_grab_keyboard;
41  extern BOOL g_hide_decorations;  extern RD_BOOL g_hide_decorations;
42  extern char g_title[];  extern char g_title[];
43  /* Color depth of the RDP session.  /* Color depth of the RDP session.
44     As of RDP 5.1, it may be 8, 15, 16 or 24. */     As of RDP 5.1, it may be 8, 15, 16 or 24. */
# Line 71  typedef struct _seamless_window Line 70  typedef struct _seamless_window
70          unsigned int desktop;          unsigned int desktop;
71          struct timeval *position_timer;          struct timeval *position_timer;
72    
73          BOOL outstanding_position;          RD_BOOL outstanding_position;
74          unsigned int outpos_serial;          unsigned int outpos_serial;
75          int outpos_xoffset, outpos_yoffset;          int outpos_xoffset, outpos_yoffset;
76          int outpos_width, outpos_height;          int outpos_width, outpos_height;
77    
78            unsigned int icon_size;
79            unsigned int icon_offset;
80            char icon_buffer[32 * 32 * 4];
81    
82          struct _seamless_window *next;          struct _seamless_window *next;
83  } seamless_window;  } seamless_window;
84  static seamless_window *g_seamless_windows = NULL;  static seamless_window *g_seamless_windows = NULL;
85  static unsigned long g_seamless_focused = 0;  static unsigned long g_seamless_focused = 0;
86  static BOOL g_seamless_started = False; /* Server end is up and running */  static RD_BOOL g_seamless_started = False;      /* Server end is up and running */
87  static BOOL g_seamless_active = False;  /* We are currently in seamless mode */  static RD_BOOL g_seamless_active = False;       /* We are currently in seamless mode */
88  static BOOL g_seamless_hidden = False;  /* Desktop is hidden on server */  static RD_BOOL g_seamless_hidden = False;       /* Desktop is hidden on server */
89  extern BOOL g_seamless_rdp;  extern RD_BOOL g_seamless_rdp;
90    
91  extern uint32 g_embed_wnd;  extern uint32 g_embed_wnd;
92  BOOL g_enable_compose = False;  RD_BOOL g_enable_compose = False;
93  BOOL g_Unobscured;              /* used for screenblt */  RD_BOOL g_Unobscured;           /* used for screenblt */
94  static GC g_gc = NULL;  static GC g_gc = NULL;
95  static GC g_create_bitmap_gc = NULL;  static GC g_create_bitmap_gc = NULL;
96  static GC g_create_glyph_gc = NULL;  static GC g_create_glyph_gc = NULL;
# Line 104  static int g_bpp; Line 107  static int g_bpp;
107  static XIM g_IM;  static XIM g_IM;
108  static XIC g_IC;  static XIC g_IC;
109  static XModifierKeymap *g_mod_map;  static XModifierKeymap *g_mod_map;
110    /* Maps logical (xmodmap -pp) pointing device buttons (0-based) back
111       to physical (1-based) indices. */
112    static unsigned char g_pointer_log_to_phys_map[16];
113  static Cursor g_current_cursor;  static Cursor g_current_cursor;
114  static RD_HCURSOR g_null_cursor = NULL;  static RD_HCURSOR g_null_cursor = NULL;
115  static Atom g_protocol_atom, g_kill_atom;  static Atom g_protocol_atom, g_kill_atom;
116  extern Atom g_net_wm_state_atom;  extern Atom g_net_wm_state_atom;
117  extern Atom g_net_wm_desktop_atom;  extern Atom g_net_wm_desktop_atom;
118  static BOOL g_focused;  static RD_BOOL g_focused;
119  static BOOL g_mouse_in_wnd;  static RD_BOOL g_mouse_in_wnd;
120  /* Indicates that:  /* Indicates that:
121     1) visual has 15, 16 or 24 depth and the same color channel masks     1) visual has 15, 16 or 24 depth and the same color channel masks
122        as its RDP equivalent (implies X server is LE),        as its RDP equivalent (implies X server is LE),
123     2) host is LE     2) host is LE
124     This will trigger an optimization whose real value is questionable.     This will trigger an optimization whose real value is questionable.
125  */  */
126  static BOOL g_compatible_arch;  static RD_BOOL g_compatible_arch;
127  /* Indicates whether RDP's bitmaps and our XImages have the same  /* Indicates whether RDP's bitmaps and our XImages have the same
128     binary format. If so, we can avoid an expensive translation.     binary format. If so, we can avoid an expensive translation.
129     Note that this can be true when g_compatible_arch is false,     Note that this can be true when g_compatible_arch is false,
# Line 128  static BOOL g_compatible_arch; Line 134  static BOOL g_compatible_arch;
134     ('host' is the machine running rdesktop; the host simply memcpy's     ('host' is the machine running rdesktop; the host simply memcpy's
135      so its endianess doesn't matter)      so its endianess doesn't matter)
136   */   */
137  static BOOL g_no_translate_image = False;  static RD_BOOL g_no_translate_image = False;
138    
139  /* endianness */  /* endianness */
140  static BOOL g_host_be;  static RD_BOOL g_host_be;
141  static BOOL g_xserver_be;  static RD_BOOL g_xserver_be;
142  static int g_red_shift_r, g_blue_shift_r, g_green_shift_r;  static int g_red_shift_r, g_blue_shift_r, g_green_shift_r;
143  static int g_red_shift_l, g_blue_shift_l, g_green_shift_l;  static int g_red_shift_l, g_blue_shift_l, g_green_shift_l;
144    
145  /* software backing store */  /* software backing store */
146  extern BOOL g_ownbackstore;  extern RD_BOOL g_ownbackstore;
147  static Pixmap g_backstore = 0;  static Pixmap g_backstore = 0;
148    
149  /* Moving in single app mode */  /* Moving in single app mode */
150  static BOOL g_moving_wnd;  static RD_BOOL g_moving_wnd;
151  static int g_move_x_offset = 0;  static int g_move_x_offset = 0;
152  static int g_move_y_offset = 0;  static int g_move_y_offset = 0;
153  static BOOL g_using_full_workarea = False;  static RD_BOOL g_using_full_workarea = False;
154    
155  #ifdef WITH_RDPSND  #ifdef WITH_RDPSND
156  extern BOOL g_rdpsnd;  extern RD_BOOL g_rdpsnd;
157  #endif  #endif
158    
159  /* MWM decorations */  /* MWM decorations */
# Line 248  seamless_XDrawLines(Drawable d, XPoint * Line 254  seamless_XDrawLines(Drawable d, XPoint *
254  }  }
255    
256  /* colour maps */  /* colour maps */
257  extern BOOL g_owncolmap;  extern RD_BOOL g_owncolmap;
258  static Colormap g_xcolmap;  static Colormap g_xcolmap;
259  static uint32 *g_colmap = NULL;  static uint32 *g_colmap = NULL;
260    
# Line 472  sw_handle_restack(seamless_window * sw) Line 478  sw_handle_restack(seamless_window * sw)
478    
479    
480  static seamless_group *  static seamless_group *
481  sw_find_group(unsigned long id, BOOL dont_create)  sw_find_group(unsigned long id, RD_BOOL dont_create)
482  {  {
483          seamless_window *sw;          seamless_window *sw;
484          seamless_group *sg;          seamless_group *sg;
# Line 577  translate_colour(uint32 colour) Line 583  translate_colour(uint32 colour)
583                          SPLITCOLOUR16(colour, pc);                          SPLITCOLOUR16(colour, pc);
584                          break;                          break;
585                  case 24:                  case 24:
586                    case 32:
587                          SPLITCOLOUR24(colour, pc);                          SPLITCOLOUR24(colour, pc);
588                          break;                          break;
589                  default:                  default:
# Line 1185  translate_image(int width, int height, u Line 1192  translate_image(int width, int height, u
1192             is only set for compatible depths, but the RDP depth might've             is only set for compatible depths, but the RDP depth might've
1193             changed during connection negotiations.             changed during connection negotiations.
1194           */           */
1195    
1196            /* todo */
1197            if (g_server_depth == 32 && g_depth == 24)
1198            {
1199                    return data;
1200            }
1201    
1202          if (g_no_translate_image)          if (g_no_translate_image)
1203          {          {
1204                  if ((g_depth == 15 && g_server_depth == 15) ||                  if ((g_depth == 15 && g_server_depth == 15) ||
# Line 1262  translate_image(int width, int height, u Line 1276  translate_image(int width, int height, u
1276          return out;          return out;
1277  }  }
1278    
1279  BOOL  static void
1280    xwin_refresh_pointer_map(void)
1281    {
1282            unsigned char phys_to_log_map[sizeof(g_pointer_log_to_phys_map)];
1283            int i, pointer_buttons;
1284    
1285            pointer_buttons = XGetPointerMapping(g_display, phys_to_log_map, sizeof(phys_to_log_map));
1286            for (i = 0; i < pointer_buttons; ++i)
1287            {
1288                    /* This might produce multiple logical buttons mapping
1289                       to a single physical one, but hey, that's
1290                       life... */
1291                    g_pointer_log_to_phys_map[phys_to_log_map[i] - 1] = i + 1;
1292            }
1293    }
1294    
1295    RD_BOOL
1296  get_key_state(unsigned int state, uint32 keysym)  get_key_state(unsigned int state, uint32 keysym)
1297  {  {
1298          int modifierpos, key, keysymMask = 0;          int modifierpos, key, keysymMask = 0;
# Line 1310  calculate_mask_weight(uint32 mask) Line 1340  calculate_mask_weight(uint32 mask)
1340          return weight;          return weight;
1341  }  }
1342    
1343  static BOOL  static RD_BOOL
1344  select_visual(int screen_num)  select_visual(int screen_num)
1345  {  {
1346          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
# Line 1349  select_visual(int screen_num) Line 1379  select_visual(int screen_num)
1379                  for (i = 0; i < visuals_count; ++i)                  for (i = 0; i < visuals_count; ++i)
1380                  {                  {
1381                          XVisualInfo *visual_info = &vmatches[i];                          XVisualInfo *visual_info = &vmatches[i];
1382                          BOOL can_translate_to_bpp = False;                          RD_BOOL can_translate_to_bpp = False;
1383                          int j;                          int j;
1384    
1385                          /* Try to find a no-translation visual that'll                          /* Try to find a no-translation visual that'll
# Line 1521  error_handler(Display * dpy, XErrorEvent Line 1551  error_handler(Display * dpy, XErrorEvent
1551          return g_old_error_handler(dpy, eev);          return g_old_error_handler(dpy, eev);
1552  }  }
1553    
1554  BOOL  RD_BOOL
1555  ui_init(void)  ui_init(void)
1556  {  {
1557          int screen_num;          int screen_num;
# Line 1535  ui_init(void) Line 1565  ui_init(void)
1565    
1566          {          {
1567                  uint16 endianess_test = 1;                  uint16 endianess_test = 1;
1568                  g_host_be = !(BOOL) (*(uint8 *) (&endianess_test));                  g_host_be = !(RD_BOOL) (*(uint8 *) (&endianess_test));
1569          }          }
1570    
1571          g_old_error_handler = XSetErrorHandler(error_handler);          g_old_error_handler = XSetErrorHandler(error_handler);
# Line 1616  ui_init(void) Line 1646  ui_init(void)
1646          g_width = (g_width + 3) & ~3;          g_width = (g_width + 3) & ~3;
1647    
1648          g_mod_map = XGetModifierMapping(g_display);          g_mod_map = XGetModifierMapping(g_display);
1649            xwin_refresh_pointer_map();
1650    
1651          xkeymap_init();          xkeymap_init();
1652    
# Line 1687  get_input_mask(long *input_mask) Line 1718  get_input_mask(long *input_mask)
1718                  *input_mask |= LeaveWindowMask;                  *input_mask |= LeaveWindowMask;
1719  }  }
1720    
1721  BOOL  RD_BOOL
1722  ui_create_window(void)  ui_create_window(void)
1723  {  {
1724          uint8 null_pointer_mask[1] = { 0x80 };          uint8 null_pointer_mask[1] = { 0x80 };
# Line 1735  ui_create_window(void) Line 1766  ui_create_window(void)
1766          }          }
1767    
1768          XStoreName(g_display, g_wnd, g_title);          XStoreName(g_display, g_wnd, g_title);
1769            ewmh_set_wm_name(g_wnd, g_title);
1770    
1771          if (g_hide_decorations)          if (g_hide_decorations)
1772                  mwm_hide_decorations(g_wnd);                  mwm_hide_decorations(g_wnd);
# Line 1874  xwin_toggle_fullscreen(void) Line 1906  xwin_toggle_fullscreen(void)
1906  }  }
1907    
1908  static void  static void
1909  handle_button_event(XEvent xevent, BOOL down)  handle_button_event(XEvent xevent, RD_BOOL down)
1910  {  {
1911          uint16 button, flags = 0;          uint16 button, flags = 0;
1912          g_last_gesturetime = xevent.xbutton.time;          g_last_gesturetime = xevent.xbutton.time;
1913            /* Reverse the pointer button mapping, e.g. in the case of
1914               "left-handed mouse mode"; the RDP session expects to
1915               receive physical buttons (true in mstsc as well) and
1916               logical button behavior depends on the remote desktop's own
1917               mouse settings */
1918            xevent.xbutton.button = g_pointer_log_to_phys_map[xevent.xbutton.button - 1];
1919          button = xkeymap_translate_button(xevent.xbutton.button);          button = xkeymap_translate_button(xevent.xbutton.button);
1920          if (button == 0)          if (button == 0)
1921                  return;                  return;
# Line 2165  xwin_process_events(void) Line 2203  xwin_process_events(void)
2203                                          XFreeModifiermap(g_mod_map);                                          XFreeModifiermap(g_mod_map);
2204                                          g_mod_map = XGetModifierMapping(g_display);                                          g_mod_map = XGetModifierMapping(g_display);
2205                                  }                                  }
2206    
2207                                    if (xevent.xmapping.request == MappingPointer)
2208                                    {
2209                                            xwin_refresh_pointer_map();
2210                                    }
2211    
2212                                  break;                                  break;
2213    
2214                                  /* clipboard stuff */                                  /* clipboard stuff */
# Line 2248  ui_select(int rdp_socket) Line 2292  ui_select(int rdp_socket)
2292          int n;          int n;
2293          fd_set rfds, wfds;          fd_set rfds, wfds;
2294          struct timeval tv;          struct timeval tv;
2295          BOOL s_timeout = False;          RD_BOOL s_timeout = False;
2296    
2297          while (True)          while (True)
2298          {          {
# Line 2292  ui_select(int rdp_socket) Line 2336  ui_select(int rdp_socket)
2336    
2337                                  /* Abort serial read calls */                                  /* Abort serial read calls */
2338                                  if (s_timeout)                                  if (s_timeout)
2339                                          rdpdr_check_fds(&rfds, &wfds, (BOOL) True);                                          rdpdr_check_fds(&rfds, &wfds, (RD_BOOL) True);
2340                                  continue;                                  continue;
2341                  }                  }
2342    
# Line 2300  ui_select(int rdp_socket) Line 2344  ui_select(int rdp_socket)
2344                  rdpsnd_check_fds(&rfds, &wfds);                  rdpsnd_check_fds(&rfds, &wfds);
2345  #endif  #endif
2346    
2347                  rdpdr_check_fds(&rfds, &wfds, (BOOL) False);                  rdpdr_check_fds(&rfds, &wfds, (RD_BOOL) False);
2348    
2349                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
2350                          return 1;                          return 1;
# Line 3219  ui_desktop_restore(uint32 offset, int x, Line 3263  ui_desktop_restore(uint32 offset, int x,
3263                  return;                  return;
3264    
3265          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
3266                               (char *) data, cx, cy, BitmapPad(g_display), cx * g_bpp / 8);                               (char *) data, cx, cy, g_bpp, 0);
3267    
3268          if (g_ownbackstore)          if (g_ownbackstore)
3269          {          {
# Line 3253  ui_end_update(void) Line 3297  ui_end_update(void)
3297    
3298    
3299  void  void
3300  ui_seamless_begin(BOOL hidden)  ui_seamless_begin(RD_BOOL hidden)
3301  {  {
3302          if (!g_seamless_rdp)          if (!g_seamless_rdp)
3303                  return;                  return;
# Line 3421  ui_seamless_create_window(unsigned long Line 3465  ui_seamless_create_window(unsigned long
3465          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);
3466    
3467          sw = xmalloc(sizeof(seamless_window));          sw = xmalloc(sizeof(seamless_window));
3468    
3469            memset(sw, 0, sizeof(seamless_window));
3470    
3471          sw->wnd = wnd;          sw->wnd = wnd;
3472          sw->id = id;          sw->id = id;
         sw->behind = 0;  
3473          sw->group = sw_find_group(group, False);          sw->group = sw_find_group(group, False);
3474          sw->group->refcnt++;          sw->group->refcnt++;
         sw->xoffset = 0;  
         sw->yoffset = 0;  
         sw->width = 0;  
         sw->height = 0;  
3475          sw->state = SEAMLESSRDP_NOTYETMAPPED;          sw->state = SEAMLESSRDP_NOTYETMAPPED;
3476          sw->desktop = 0;          sw->desktop = 0;
3477          sw->position_timer = xmalloc(sizeof(struct timeval));          sw->position_timer = xmalloc(sizeof(struct timeval));
# Line 3496  ui_seamless_destroy_group(unsigned long Line 3538  ui_seamless_destroy_group(unsigned long
3538  }  }
3539    
3540    
3541    void
3542    ui_seamless_seticon(unsigned long id, const char *format, int width, int height, int chunk,
3543                        const char *data, int chunk_len)
3544    {
3545            seamless_window *sw;
3546    
3547            if (!g_seamless_active)
3548                    return;
3549    
3550            sw = sw_get_window_by_id(id);
3551            if (!sw)
3552            {
3553                    warning("ui_seamless_seticon: No information for window 0x%lx\n", id);
3554                    return;
3555            }
3556    
3557            if (chunk == 0)
3558            {
3559                    if (sw->icon_size)
3560                            warning("ui_seamless_seticon: New icon started before previous completed\n");
3561    
3562                    if (strcmp(format, "RGBA") != 0)
3563                    {
3564                            warning("ui_seamless_seticon: Uknown icon format \"%s\"\n", format);
3565                            return;
3566                    }
3567    
3568                    sw->icon_size = width * height * 4;
3569                    if (sw->icon_size > 32 * 32 * 4)
3570                    {
3571                            warning("ui_seamless_seticon: Icon too large (%d bytes)\n", sw->icon_size);
3572                            sw->icon_size = 0;
3573                            return;
3574                    }
3575    
3576                    sw->icon_offset = 0;
3577            }
3578            else
3579            {
3580                    if (!sw->icon_size)
3581                            return;
3582            }
3583    
3584            if (chunk_len > (sw->icon_size - sw->icon_offset))
3585            {
3586                    warning("ui_seamless_seticon: Too large chunk received (%d bytes > %d bytes)\n",
3587                            chunk_len, sw->icon_size - sw->icon_offset);
3588                    sw->icon_size = 0;
3589                    return;
3590            }
3591    
3592            memcpy(sw->icon_buffer + sw->icon_offset, data, chunk_len);
3593            sw->icon_offset += chunk_len;
3594    
3595            if (sw->icon_offset == sw->icon_size)
3596            {
3597                    ewmh_set_icon(sw->wnd, width, height, sw->icon_buffer);
3598                    sw->icon_size = 0;
3599            }
3600    }
3601    
3602    
3603    void
3604    ui_seamless_delicon(unsigned long id, const char *format, int width, int height)
3605    {
3606            seamless_window *sw;
3607    
3608            if (!g_seamless_active)
3609                    return;
3610    
3611            sw = sw_get_window_by_id(id);
3612            if (!sw)
3613            {
3614                    warning("ui_seamless_seticon: No information for window 0x%lx\n", id);
3615                    return;
3616            }
3617    
3618            if (strcmp(format, "RGBA") != 0)
3619            {
3620                    warning("ui_seamless_seticon: Uknown icon format \"%s\"\n", format);
3621                    return;
3622            }
3623    
3624            ewmh_del_icon(sw->wnd, width, height);
3625    }
3626    
3627    
3628  void  void
3629  ui_seamless_move_window(unsigned long id, int x, int y, int width, int height, unsigned long flags)  ui_seamless_move_window(unsigned long id, int x, int y, int width, int height, unsigned long flags)
3630  {  {

Legend:
Removed from v.1370  
changed lines
  Added in v.1417

  ViewVC Help
Powered by ViewVC 1.1.26