/[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 1089 by astrand, Fri Mar 10 08:50:43 2006 UTC revision 1133 by astrand, Wed Mar 15 13:15:51 2006 UTC
# Line 56  typedef struct _seamless_window Line 56  typedef struct _seamless_window
56          unsigned long id;          unsigned long id;
57          int xoffset, yoffset;          int xoffset, yoffset;
58          int width, height;          int width, height;
59            int state;              /* normal/minimized/maximized. */
60            unsigned int desktop;
61          struct _seamless_window *next;          struct _seamless_window *next;
62  } seamless_window;  } seamless_window;
63  static seamless_window *g_seamless_windows = NULL;  static seamless_window *g_seamless_windows = NULL;
# Line 83  static XModifierKeymap *g_mod_map; Line 85  static XModifierKeymap *g_mod_map;
85  static Cursor g_current_cursor;  static Cursor g_current_cursor;
86  static HCURSOR g_null_cursor = NULL;  static HCURSOR g_null_cursor = NULL;
87  static Atom g_protocol_atom, g_kill_atom;  static Atom g_protocol_atom, g_kill_atom;
88    extern Atom g_net_wm_state_atom;
89    extern Atom g_net_wm_desktop_atom;
90  static BOOL g_focused;  static BOOL g_focused;
91  static BOOL g_mouse_in_wnd;  static BOOL g_mouse_in_wnd;
92  /* Indicates that:  /* Indicates that:
# Line 298  seamless_remove_window(seamless_window * Line 302  seamless_remove_window(seamless_window *
302  }  }
303    
304    
305    /* Move all windows except wnd to new desktop */
306    static void
307    seamless_all_to_desktop(Window wnd, unsigned int desktop)
308    {
309            seamless_window *sw;
310            for (sw = g_seamless_windows; sw; sw = sw->next)
311            {
312                    if (sw->wnd == wnd)
313                            continue;
314                    if (sw->desktop != desktop)
315                    {
316                            ewmh_move_to_desktop(sw->wnd, desktop);
317                            sw->desktop = desktop;
318                    }
319            }
320    }
321    
322    
323  static void  static void
324  mwm_hide_decorations(Window wnd)  mwm_hide_decorations(Window wnd)
325  {  {
# Line 1396  ui_init(void) Line 1418  ui_init(void)
1418                  g_IM = XOpenIM(g_display, NULL, NULL, NULL);                  g_IM = XOpenIM(g_display, NULL, NULL, NULL);
1419    
1420          xclip_init();          xclip_init();
1421            ewmh_init();
1422          if (g_seamless_rdp)          if (g_seamless_rdp)
1423                  seamless_init();                  seamless_init();
1424    
# Line 1731  xwin_process_events(void) Line 1754  xwin_process_events(void)
1754          char str[256];          char str[256];
1755          Status status;          Status status;
1756          int events = 0;          int events = 0;
1757            seamless_window *sw;
1758    
1759          while ((XPending(g_display) > 0) && events++ < 20)          while ((XPending(g_display) > 0) && events++ < 20)
1760          {          {
# Line 1893  xwin_process_events(void) Line 1917  xwin_process_events(void)
1917                                  }                                  }
1918                                  else                                  else
1919                                  {                                  {
                                         seamless_window *sw;  
1920                                          sw = seamless_get_window_by_wnd(xevent.xexpose.window);                                          sw = seamless_get_window_by_wnd(xevent.xexpose.window);
1921                                          if (sw)                                          if (sw)
1922                                                  XCopyArea(g_display, g_backstore,                                                  XCopyArea(g_display, g_backstore,
# Line 1903  xwin_process_events(void) Line 1926  xwin_process_events(void)
1926                                                            xevent.xexpose.width,                                                            xevent.xexpose.width,
1927                                                            xevent.xexpose.height, xevent.xexpose.x,                                                            xevent.xexpose.height, xevent.xexpose.x,
1928                                                            xevent.xexpose.y);                                                            xevent.xexpose.y);
1929                                            else
1930                                            {
1931                                                    error("Expose for unknown window 0x%lx\n",
1932                                                          xevent.xexpose.window);
1933                                            }
1934                                  }                                  }
1935    
1936                                  break;                                  break;
# Line 1933  xwin_process_events(void) Line 1961  xwin_process_events(void)
1961                                  break;                                  break;
1962                          case PropertyNotify:                          case PropertyNotify:
1963                                  xclip_handle_PropertyNotify(&xevent.xproperty);                                  xclip_handle_PropertyNotify(&xevent.xproperty);
1964                                    if (xevent.xproperty.window == g_wnd)
1965                                            break;
1966                                    if (xevent.xproperty.window == DefaultRootWindow(g_display))
1967                                            break;
1968    
1969                                    /* seamless */
1970                                    sw = seamless_get_window_by_wnd(xevent.xproperty.window);
1971                                    if (!sw)
1972                                            break;
1973    
1974                                    if ((xevent.xproperty.atom == g_net_wm_state_atom)
1975                                        && (xevent.xproperty.state == PropertyNewValue))
1976                                    {
1977                                            sw->state = ewmh_get_window_state(sw->wnd);
1978                                            seamless_send_state(sw->id, sw->state, 0);
1979                                    }
1980    
1981                                    if ((xevent.xproperty.atom == g_net_wm_desktop_atom)
1982                                        && (xevent.xproperty.state == PropertyNewValue))
1983                                    {
1984                                            sw->desktop = ewmh_get_window_desktop(sw->wnd);
1985                                            seamless_all_to_desktop(sw->wnd, sw->desktop);
1986                                    }
1987    
1988                                  break;                                  break;
1989                          case MapNotify:                          case MapNotify:
1990                                  if (!g_seamless_rdp)                                  if (!g_seamless_rdp)
# Line 2987  ui_seamless_toggle() Line 3039  ui_seamless_toggle()
3039  }  }
3040    
3041  void  void
3042  ui_seamless_create_window(unsigned long id, unsigned long flags)  ui_seamless_create_window(unsigned long id, unsigned long parent, unsigned long flags)
3043  {  {
3044          Window wnd;          Window wnd;
3045          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
3046          XClassHint *classhints;          XClassHint *classhints;
3047            XSizeHints *sizehints;
3048          long input_mask;          long input_mask;
3049          seamless_window *sw;          seamless_window *sw, *sw_parent;
3050    
3051          get_window_attribs(&attribs);          /* Ignore CREATEs for existing windows */
3052            sw = seamless_get_window_by_id(id);
3053            if (sw)
3054                    return;
3055    
3056            get_window_attribs(&attribs);
3057          attribs.override_redirect = False;          attribs.override_redirect = False;
3058    
3059          /* FIXME: Do not assume that -1, -1 is outside screen Consider          wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), -1, -1, 1, 1, 0, g_depth,
            wait with showing the window until STATE and others have  
            been recieved. */  
         wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), -1, -1, 1, 1, 0, 0,  
3060                              InputOutput, g_visual,                              InputOutput, g_visual,
3061                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
3062                              CWBorderPixel, &attribs);                              CWBorderPixel, &attribs);
3063    
3064          XStoreName(g_display, wnd, "rdesktop-seamless");          XStoreName(g_display, wnd, "SeamlessRDP");
3065    
3066          mwm_hide_decorations(wnd);          mwm_hide_decorations(wnd);
3067    
3068          classhints = XAllocClassHint();          classhints = XAllocClassHint();
3069          if (classhints != NULL)          if (classhints != NULL)
3070          {          {
3071                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = "rdesktop";
3072                    classhints->res_class = "SeamlessRDP";
3073                  XSetClassHint(g_display, wnd, classhints);                  XSetClassHint(g_display, wnd, classhints);
3074                  XFree(classhints);                  XFree(classhints);
3075          }          }
3076    
3077            /* WM_NORMAL_HINTS */
3078            sizehints = XAllocSizeHints();
3079            if (sizehints != NULL)
3080            {
3081                    sizehints->flags = USPosition;
3082                    XSetWMNormalHints(g_display, wnd, sizehints);
3083                    XFree(sizehints);
3084            }
3085    
3086            /* Set WM_TRANSIENT_FOR, if necessary */
3087            if (parent)
3088            {
3089                    sw_parent = seamless_get_window_by_id(parent);
3090                    if (sw_parent)
3091                            XSetTransientForHint(g_display, wnd, sw_parent->wnd);
3092                    else
3093                            warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);
3094            }
3095    
3096          /* FIXME: Support for Input Context:s */          /* FIXME: Support for Input Context:s */
3097    
3098          get_input_mask(&input_mask);          get_input_mask(&input_mask);
3099            input_mask |= PropertyChangeMask;
3100    
3101          XSelectInput(g_display, wnd, input_mask);          XSelectInput(g_display, wnd, input_mask);
3102    
         XMapWindow(g_display, wnd);  
   
3103          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a
3104             seamless window, we could try to close the window on the             seamless window, we could try to close the window on the
3105             serverside, instead of terminating rdesktop */             serverside, instead of terminating rdesktop */
# Line 3039  ui_seamless_create_window(unsigned long Line 3112  ui_seamless_create_window(unsigned long
3112          sw->yoffset = 0;          sw->yoffset = 0;
3113          sw->width = 0;          sw->width = 0;
3114          sw->height = 0;          sw->height = 0;
3115            sw->state = SEAMLESSRDP_NOTYETMAPPED;
3116            sw->desktop = 0;
3117          sw->next = g_seamless_windows;          sw->next = g_seamless_windows;
3118          g_seamless_windows = sw;          g_seamless_windows = sw;
3119  }  }
# Line 3048  void Line 3123  void
3123  ui_seamless_destroy_window(unsigned long id, unsigned long flags)  ui_seamless_destroy_window(unsigned long id, unsigned long flags)
3124  {  {
3125          seamless_window *sw;          seamless_window *sw;
         sw = seamless_get_window_by_id(id);  
3126    
3127            sw = seamless_get_window_by_id(id);
3128          if (!sw)          if (!sw)
3129          {          {
3130                  warning("ui_seamless_destroy_window: No information for window 0x%lx\n", id);                  warning("ui_seamless_destroy_window: No information for window 0x%lx\n", id);
# Line 3067  ui_seamless_move_window(unsigned long id Line 3142  ui_seamless_move_window(unsigned long id
3142          seamless_window *sw;          seamless_window *sw;
3143    
3144          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
   
3145          if (!sw)          if (!sw)
3146          {          {
3147                  warning("ui_seamless_move_window: No information for window 0x%lx\n", id);                  warning("ui_seamless_move_window: No information for window 0x%lx\n", id);
# Line 3089  ui_seamless_move_window(unsigned long id Line 3163  ui_seamless_move_window(unsigned long id
3163          sw->width = MIN(MIN(width, width + x), g_width - sw->xoffset);          sw->width = MIN(MIN(width, width + x), g_width - sw->xoffset);
3164          sw->height = MIN(MIN(height, height + y), g_height - sw->yoffset);          sw->height = MIN(MIN(height, height + y), g_height - sw->yoffset);
3165    
3166            /* If we move the window in a maximized state, then KDE won't
3167               accept restoration */
3168            switch (sw->state)
3169            {
3170                    case SEAMLESSRDP_MINIMIZED:
3171                    case SEAMLESSRDP_MAXIMIZED:
3172                            return;
3173            }
3174    
3175          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */
3176          XMoveResizeWindow(g_display, sw->wnd, sw->xoffset, sw->yoffset, sw->width, sw->height);          XMoveResizeWindow(g_display, sw->wnd, sw->xoffset, sw->yoffset, sw->width, sw->height);
3177  }  }
3178    
3179    
3180  void  void
3181  ui_seamless_settitle(unsigned long id, const char *title)  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)
3182  {  {
3183          seamless_window *sw;          seamless_window *sw;
3184    
3185          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3186            if (!sw)
3187            {
3188                    warning("ui_seamless_settitle: No information for window 0x%lx\n", id);
3189                    return;
3190            }
3191    
3192          XStoreName(g_display, sw->wnd, title);          XStoreName(g_display, sw->wnd, title);
3193  }  }
# Line 3111  ui_seamless_setstate(unsigned long id, u Line 3199  ui_seamless_setstate(unsigned long id, u
3199          seamless_window *sw;          seamless_window *sw;
3200    
3201          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3202            if (!sw)
3203            {
3204                    warning("ui_seamless_setstate: No information for window 0x%lx\n", id);
3205                    return;
3206            }
3207    
3208            if (sw->state == SEAMLESSRDP_NOTYETMAPPED)
3209            {
3210                    XMapWindow(g_display, sw->wnd);
3211            }
3212    
3213            sw->state = state;
3214    
3215          switch (state)          switch (state)
3216          {          {
3217                  case SEAMLESSRDP_NORMAL:                  case SEAMLESSRDP_NORMAL:
3218                  case SEAMLESSRDP_MAXIMIZED:                  case SEAMLESSRDP_MAXIMIZED:
3219                          /* FIXME */                          ewmh_change_state(sw->wnd, state);
3220                          break;                          break;
3221                  case SEAMLESSRDP_MINIMIZED:                  case SEAMLESSRDP_MINIMIZED:
3222                            /* EWMH says: "if an Application asks to toggle _NET_WM_STATE_HIDDEN
3223                               the Window Manager should probably just ignore the request, since
3224                               _NET_WM_STATE_HIDDEN is a function of some other aspect of the window
3225                               such as minimization, rather than an independent state." Besides,
3226                               XIconifyWindow is easier. */
3227                          XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));                          XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));
3228                          break;                          break;
3229                  default:                  default:
# Line 3126  ui_seamless_setstate(unsigned long id, u Line 3231  ui_seamless_setstate(unsigned long id, u
3231                          break;                          break;
3232          }          }
3233  }  }
3234    
3235    
3236    void
3237    ui_seamless_syncbegin(unsigned long flags)
3238    {
3239            /* Destroy all seamless windows */
3240            while (g_seamless_windows)
3241            {
3242                    XDestroyWindow(g_display, g_seamless_windows->wnd);
3243                    seamless_remove_window(g_seamless_windows);
3244            }
3245    }

Legend:
Removed from v.1089  
changed lines
  Added in v.1133

  ViewVC Help
Powered by ViewVC 1.1.26