/[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 1380 by astrand, Wed Jan 17 07:39:31 2007 UTC revision 1447 by astrand, Fri Mar 7 11:27:12 2008 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 74  typedef struct _seamless_window Line 75  typedef struct _seamless_window
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;
# Line 102  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;
# Line 575  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 1183  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 1260  translate_image(int width, int height, u Line 1276  translate_image(int width, int height, u
1276          return out;          return out;
1277  }  }
1278    
1279    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  RD_BOOL
1296  get_key_state(unsigned int state, uint32 keysym)  get_key_state(unsigned int state, uint32 keysym)
1297  {  {
# Line 1614  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 1877  handle_button_event(XEvent xevent, RD_BO Line 1910  handle_button_event(XEvent xevent, RD_BO
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 1989  xwin_process_events(void) Line 2028  xwin_process_events(void)
2028                                  /* the window manager told us to quit */                                  /* the window manager told us to quit */
2029                                  if ((xevent.xclient.message_type == g_protocol_atom)                                  if ((xevent.xclient.message_type == g_protocol_atom)
2030                                      && ((Atom) xevent.xclient.data.l[0] == g_kill_atom))                                      && ((Atom) xevent.xclient.data.l[0] == g_kill_atom))
2031                                          /* Quit */                                  {
2032                                          return 0;                                          /* When killing a seamless window, close the window on the
2033                                               serverside instead of terminating rdesktop */
2034                                            sw = sw_get_window_by_wnd(xevent.xclient.window);
2035                                            if (!sw)
2036                                                    /* Otherwise, quit */
2037                                                    return 0;
2038                                            /* send seamless destroy process message */
2039                                            seamless_send_destroy(sw->id);
2040                                    }
2041                                  break;                                  break;
2042    
2043                          case KeyPress:                          case KeyPress:
# Line 2164  xwin_process_events(void) Line 2211  xwin_process_events(void)
2211                                          XFreeModifiermap(g_mod_map);                                          XFreeModifiermap(g_mod_map);
2212                                          g_mod_map = XGetModifierMapping(g_display);                                          g_mod_map = XGetModifierMapping(g_display);
2213                                  }                                  }
2214    
2215                                    if (xevent.xmapping.request == MappingPointer)
2216                                    {
2217                                            xwin_refresh_pointer_map();
2218                                    }
2219    
2220                                  break;                                  break;
2221    
2222                                  /* clipboard stuff */                                  /* clipboard stuff */
# Line 3218  ui_desktop_restore(uint32 offset, int x, Line 3271  ui_desktop_restore(uint32 offset, int x,
3271                  return;                  return;
3272    
3273          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
3274                               (char *) data, cx, cy, BitmapPad(g_display), cx * g_bpp / 8);                               (char *) data, cx, cy, g_bpp, 0);
3275    
3276          if (g_ownbackstore)          if (g_ownbackstore)
3277          {          {
# Line 3407  ui_seamless_create_window(unsigned long Line 3460  ui_seamless_create_window(unsigned long
3460                  ewmh_set_window_modal(wnd);                  ewmh_set_window_modal(wnd);
3461          }          }
3462    
3463            if (flags & SEAMLESSRDP_CREATE_TOPMOST)
3464            {
3465                    /* Make window always-on-top */
3466                    ewmh_set_window_above(wnd);
3467            }
3468    
3469          /* FIXME: Support for Input Context:s */          /* FIXME: Support for Input Context:s */
3470    
3471          get_input_mask(&input_mask);          get_input_mask(&input_mask);
# Line 3414  ui_seamless_create_window(unsigned long Line 3473  ui_seamless_create_window(unsigned long
3473    
3474          XSelectInput(g_display, wnd, input_mask);          XSelectInput(g_display, wnd, input_mask);
3475    
3476          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a          /* handle the WM_DELETE_WINDOW protocol. */
            seamless window, we could try to close the window on the  
            serverside, instead of terminating rdesktop */  
3477          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);
3478    
3479          sw = xmalloc(sizeof(seamless_window));          sw = xmalloc(sizeof(seamless_window));
3480    
3481            memset(sw, 0, sizeof(seamless_window));
3482    
3483          sw->wnd = wnd;          sw->wnd = wnd;
3484          sw->id = id;          sw->id = id;
         sw->behind = 0;  
3485          sw->group = sw_find_group(group, False);          sw->group = sw_find_group(group, False);
3486          sw->group->refcnt++;          sw->group->refcnt++;
         sw->xoffset = 0;  
         sw->yoffset = 0;  
         sw->width = 0;  
         sw->height = 0;  
3487          sw->state = SEAMLESSRDP_NOTYETMAPPED;          sw->state = SEAMLESSRDP_NOTYETMAPPED;
3488          sw->desktop = 0;          sw->desktop = 0;
3489          sw->position_timer = xmalloc(sizeof(struct timeval));          sw->position_timer = xmalloc(sizeof(struct timeval));
# Line 3496  ui_seamless_destroy_group(unsigned long Line 3551  ui_seamless_destroy_group(unsigned long
3551    
3552    
3553  void  void
3554    ui_seamless_seticon(unsigned long id, const char *format, int width, int height, int chunk,
3555                        const char *data, int chunk_len)
3556    {
3557            seamless_window *sw;
3558    
3559            if (!g_seamless_active)
3560                    return;
3561    
3562            sw = sw_get_window_by_id(id);
3563            if (!sw)
3564            {
3565                    warning("ui_seamless_seticon: No information for window 0x%lx\n", id);
3566                    return;
3567            }
3568    
3569            if (chunk == 0)
3570            {
3571                    if (sw->icon_size)
3572                            warning("ui_seamless_seticon: New icon started before previous completed\n");
3573    
3574                    if (strcmp(format, "RGBA") != 0)
3575                    {
3576                            warning("ui_seamless_seticon: Uknown icon format \"%s\"\n", format);
3577                            return;
3578                    }
3579    
3580                    sw->icon_size = width * height * 4;
3581                    if (sw->icon_size > 32 * 32 * 4)
3582                    {
3583                            warning("ui_seamless_seticon: Icon too large (%d bytes)\n", sw->icon_size);
3584                            sw->icon_size = 0;
3585                            return;
3586                    }
3587    
3588                    sw->icon_offset = 0;
3589            }
3590            else
3591            {
3592                    if (!sw->icon_size)
3593                            return;
3594            }
3595    
3596            if (chunk_len > (sw->icon_size - sw->icon_offset))
3597            {
3598                    warning("ui_seamless_seticon: Too large chunk received (%d bytes > %d bytes)\n",
3599                            chunk_len, sw->icon_size - sw->icon_offset);
3600                    sw->icon_size = 0;
3601                    return;
3602            }
3603    
3604            memcpy(sw->icon_buffer + sw->icon_offset, data, chunk_len);
3605            sw->icon_offset += chunk_len;
3606    
3607            if (sw->icon_offset == sw->icon_size)
3608            {
3609                    ewmh_set_icon(sw->wnd, width, height, sw->icon_buffer);
3610                    sw->icon_size = 0;
3611            }
3612    }
3613    
3614    
3615    void
3616    ui_seamless_delicon(unsigned long id, const char *format, int width, int height)
3617    {
3618            seamless_window *sw;
3619    
3620            if (!g_seamless_active)
3621                    return;
3622    
3623            sw = sw_get_window_by_id(id);
3624            if (!sw)
3625            {
3626                    warning("ui_seamless_seticon: No information for window 0x%lx\n", id);
3627                    return;
3628            }
3629    
3630            if (strcmp(format, "RGBA") != 0)
3631            {
3632                    warning("ui_seamless_seticon: Uknown icon format \"%s\"\n", format);
3633                    return;
3634            }
3635    
3636            ewmh_del_icon(sw->wnd, width, height);
3637    }
3638    
3639    
3640    void
3641  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)
3642  {  {
3643          seamless_window *sw;          seamless_window *sw;
# Line 3576  ui_seamless_restack_window(unsigned long Line 3718  ui_seamless_restack_window(unsigned long
3718          }          }
3719    
3720          sw_restack_window(sw, behind);          sw_restack_window(sw, behind);
3721    
3722            if (flags & SEAMLESSRDP_CREATE_TOPMOST)
3723            {
3724                    /* Make window always-on-top */
3725                    ewmh_set_window_above(sw->wnd);
3726            }
3727  }  }
3728    
3729    

Legend:
Removed from v.1380  
changed lines
  Added in v.1447

  ViewVC Help
Powered by ViewVC 1.1.26