/[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 1123 by astrand, Wed Mar 15 08:41:48 2006 UTC revision 1154 by ossman_, Fri Mar 17 09:56:20 2006 UTC
# Line 54  typedef struct _seamless_window Line 54  typedef struct _seamless_window
54  {  {
55          Window wnd;          Window wnd;
56          unsigned long id;          unsigned long id;
57            unsigned long parent;
58          int xoffset, yoffset;          int xoffset, yoffset;
59          int width, height;          int width, height;
60          unsigned int state;     /* normal/minimized/maximized */          int state;              /* normal/minimized/maximized. */
61          unsigned int desktop;          unsigned int desktop;
62          struct _seamless_window *next;          struct _seamless_window *next;
63  } seamless_window;  } seamless_window;
64  static seamless_window *g_seamless_windows = NULL;  static seamless_window *g_seamless_windows = NULL;
65    static BOOL g_seamless_started = False; /* Server end is up and running */
66    static BOOL g_seamless_active = False;  /* We are currently in seamless mode */
67  extern BOOL g_seamless_rdp;  extern BOOL g_seamless_rdp;
68    
69  extern uint32 g_embed_wnd;  extern uint32 g_embed_wnd;
# Line 1564  ui_create_window(void) Line 1567  ui_create_window(void)
1567          }          }
1568    
1569          XSelectInput(g_display, g_wnd, input_mask);          XSelectInput(g_display, g_wnd, input_mask);
1570          if (!g_seamless_rdp)  
1571            XMapWindow(g_display, g_wnd);
1572            /* wait for VisibilityNotify */
1573            do
1574          {          {
1575                  XMapWindow(g_display, g_wnd);                  XMaskEvent(g_display, VisibilityChangeMask, &xevent);
                 /* wait for VisibilityNotify */  
                 do  
                 {  
                         XMaskEvent(g_display, VisibilityChangeMask, &xevent);  
                 }  
                 while (xevent.type != VisibilityNotify);  
                 g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;  
1576          }          }
1577            while (xevent.type != VisibilityNotify);
1578            g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1579    
1580          g_focused = False;          g_focused = False;
1581          g_mouse_in_wnd = False;          g_mouse_in_wnd = False;
# Line 1638  xwin_toggle_fullscreen(void) Line 1639  xwin_toggle_fullscreen(void)
1639  {  {
1640          Pixmap contents = 0;          Pixmap contents = 0;
1641    
1642          if (g_seamless_rdp)          if (g_seamless_active)
1643                  /* Turn off SeamlessRDP mode */                  /* Turn off SeamlessRDP mode */
1644                  ui_seamless_toggle();                  ui_seamless_toggle();
1645    
# Line 1743  handle_button_event(XEvent xevent, BOOL Line 1744  handle_button_event(XEvent xevent, BOOL
1744          }          }
1745  }  }
1746    
1747    static void
1748    ui_seamless_handle_restack(seamless_window * sw)
1749    {
1750            Status status;
1751            Window root, parent, *children;
1752            unsigned int nchildren, i;
1753            seamless_window *sw_below;
1754    
1755            status = XQueryTree(g_display, RootWindowOfScreen(g_screen),
1756                                &root, &parent, &children, &nchildren);
1757            if (!status || !nchildren)
1758                    return;
1759    
1760            sw_below = NULL;
1761    
1762            i = 0;
1763            while (children[i] != sw->wnd)
1764            {
1765                    i++;
1766                    if (i >= nchildren)
1767                            return;
1768            }
1769    
1770            for (i++; i < nchildren; i++)
1771            {
1772                    sw_below = seamless_get_window_by_wnd(children[i]);
1773                    if (sw_below)
1774                            break;
1775            }
1776    
1777            if (sw_below)
1778                    seamless_send_zchange(sw->id, sw_below->id, 0);
1779            else
1780                    seamless_send_zchange(sw->id, 0, 0);
1781    }
1782    
1783  /* Process events in Xlib queue  /* Process events in Xlib queue
1784     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1785  static int  static int
# Line 1875  xwin_process_events(void) Line 1912  xwin_process_events(void)
1912                                  if (g_grab_keyboard && g_mouse_in_wnd)                                  if (g_grab_keyboard && g_mouse_in_wnd)
1913                                          XGrabKeyboard(g_display, g_wnd, True,                                          XGrabKeyboard(g_display, g_wnd, True,
1914                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
1915    
1916                                    sw = seamless_get_window_by_wnd(xevent.xfocus.window);
1917                                    if (!sw)
1918                                            break;
1919    
1920                                    seamless_send_focus(sw->id, 0);
1921                                  break;                                  break;
1922    
1923                          case FocusOut:                          case FocusOut:
# Line 1987  xwin_process_events(void) Line 2030  xwin_process_events(void)
2030    
2031                                  break;                                  break;
2032                          case MapNotify:                          case MapNotify:
2033                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2034                                          rdp_send_client_window_status(1);                                          rdp_send_client_window_status(1);
2035                                  break;                                  break;
2036                          case UnmapNotify:                          case UnmapNotify:
2037                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2038                                          rdp_send_client_window_status(0);                                          rdp_send_client_window_status(0);
2039                                  break;                                  break;
2040                            case ConfigureNotify:
2041                                    /* seamless */
2042                                    sw = seamless_get_window_by_wnd(xevent.xconfigure.window);
2043                                    if (!sw)
2044                                            break;
2045    
2046                                    ui_seamless_handle_restack(sw);
2047                  }                  }
2048          }          }
2049          /* Keep going */          /* Keep going */
# Line 3005  ui_end_update(void) Line 3055  ui_end_update(void)
3055  }  }
3056    
3057  void  void
3058    ui_seamless_begin()
3059    {
3060            if (!g_seamless_rdp)
3061                    return;
3062    
3063            if (g_seamless_started)
3064                    return;
3065    
3066            g_seamless_started = True;
3067    
3068            ui_seamless_toggle();
3069    }
3070    
3071    void
3072  ui_seamless_toggle()  ui_seamless_toggle()
3073  {  {
3074          if (g_seamless_rdp)          if (!g_seamless_rdp)
3075                    return;
3076    
3077            if (!g_seamless_started)
3078                    return;
3079    
3080            if (g_seamless_active)
3081          {          {
3082                  /* Deactivate */                  /* Deactivate */
3083                  while (g_seamless_windows)                  while (g_seamless_windows)
# Line 3020  ui_seamless_toggle() Line 3090  ui_seamless_toggle()
3090          else          else
3091          {          {
3092                  /* Activate */                  /* Activate */
                 if (g_win_button_size)  
                 {  
                         error("SeamlessRDP mode cannot be activated when using single application mode\n");  
                         return;  
                 }  
                 if (!g_using_full_workarea)  
                 {  
                         error("SeamlessRDP mode requires a session that covers the whole screen");  
                         return;  
                 }  
   
3093                  XUnmapWindow(g_display, g_wnd);                  XUnmapWindow(g_display, g_wnd);
3094                  seamless_send_sync();                  seamless_send_sync();
3095          }          }
3096    
3097          g_seamless_rdp = !g_seamless_rdp;          g_seamless_active = !g_seamless_active;
3098  }  }
3099    
3100  void  void
# Line 3044  ui_seamless_create_window(unsigned long Line 3103  ui_seamless_create_window(unsigned long
3103          Window wnd;          Window wnd;
3104          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
3105          XClassHint *classhints;          XClassHint *classhints;
3106            XSizeHints *sizehints;
3107          long input_mask;          long input_mask;
3108          seamless_window *sw, *sw_parent;          seamless_window *sw, *sw_parent;
3109    
3110            if (!g_seamless_active)
3111                    return;
3112    
3113          /* Ignore CREATEs for existing windows */          /* Ignore CREATEs for existing windows */
3114          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3115          if (sw)          if (sw)
# Line 3055  ui_seamless_create_window(unsigned long Line 3118  ui_seamless_create_window(unsigned long
3118          get_window_attribs(&attribs);          get_window_attribs(&attribs);
3119          attribs.override_redirect = False;          attribs.override_redirect = False;
3120    
3121          /* 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,  
3122                              InputOutput, g_visual,                              InputOutput, g_visual,
3123                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
3124                              CWBorderPixel, &attribs);                              CWBorderPixel, &attribs);
3125    
3126          XStoreName(g_display, wnd, "rdesktop-seamless");          XStoreName(g_display, wnd, "SeamlessRDP");
3127            ewmh_set_wm_name(wnd, "SeamlessRDP");
3128    
3129          mwm_hide_decorations(wnd);          mwm_hide_decorations(wnd);
3130    
3131          classhints = XAllocClassHint();          classhints = XAllocClassHint();
3132          if (classhints != NULL)          if (classhints != NULL)
3133          {          {
3134                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = "rdesktop";
3135                    classhints->res_class = "SeamlessRDP";
3136                  XSetClassHint(g_display, wnd, classhints);                  XSetClassHint(g_display, wnd, classhints);
3137                  XFree(classhints);                  XFree(classhints);
3138          }          }
3139    
3140            /* WM_NORMAL_HINTS */
3141            sizehints = XAllocSizeHints();
3142            if (sizehints != NULL)
3143            {
3144                    sizehints->flags = USPosition;
3145                    XSetWMNormalHints(g_display, wnd, sizehints);
3146                    XFree(sizehints);
3147            }
3148    
3149          /* Set WM_TRANSIENT_FOR, if necessary */          /* Set WM_TRANSIENT_FOR, if necessary */
3150          if (parent)          if ((parent != 0x00000000) && (parent != 0xFFFFFFFF))
3151          {          {
3152                  sw_parent = seamless_get_window_by_id(parent);                  sw_parent = seamless_get_window_by_id(parent);
3153                  if (sw_parent)                  if (sw_parent)
# Line 3085  ui_seamless_create_window(unsigned long Line 3156  ui_seamless_create_window(unsigned long
3156                          warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);                          warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);
3157          }          }
3158    
3159    
3160          /* FIXME: Support for Input Context:s */          /* FIXME: Support for Input Context:s */
3161    
3162          get_input_mask(&input_mask);          get_input_mask(&input_mask);
# Line 3092  ui_seamless_create_window(unsigned long Line 3164  ui_seamless_create_window(unsigned long
3164    
3165          XSelectInput(g_display, wnd, input_mask);          XSelectInput(g_display, wnd, input_mask);
3166    
         XMapWindow(g_display, wnd);  
   
3167          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a
3168             seamless window, we could try to close the window on the             seamless window, we could try to close the window on the
3169             serverside, instead of terminating rdesktop */             serverside, instead of terminating rdesktop */
# Line 3102  ui_seamless_create_window(unsigned long Line 3172  ui_seamless_create_window(unsigned long
3172          sw = malloc(sizeof(seamless_window));          sw = malloc(sizeof(seamless_window));
3173          sw->wnd = wnd;          sw->wnd = wnd;
3174          sw->id = id;          sw->id = id;
3175            sw->parent = parent;
3176          sw->xoffset = 0;          sw->xoffset = 0;
3177          sw->yoffset = 0;          sw->yoffset = 0;
3178          sw->width = 0;          sw->width = 0;
3179          sw->height = 0;          sw->height = 0;
3180            sw->state = SEAMLESSRDP_NOTYETMAPPED;
3181            sw->desktop = 0;
3182          sw->next = g_seamless_windows;          sw->next = g_seamless_windows;
3183          g_seamless_windows = sw;          g_seamless_windows = sw;
3184  }  }
# Line 3116  ui_seamless_destroy_window(unsigned long Line 3189  ui_seamless_destroy_window(unsigned long
3189  {  {
3190          seamless_window *sw;          seamless_window *sw;
3191    
3192            if (!g_seamless_active)
3193                    return;
3194    
3195          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3196          if (!sw)          if (!sw)
3197          {          {
# Line 3133  ui_seamless_move_window(unsigned long id Line 3209  ui_seamless_move_window(unsigned long id
3209  {  {
3210          seamless_window *sw;          seamless_window *sw;
3211    
3212            if (!g_seamless_active)
3213                    return;
3214    
3215          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3216          if (!sw)          if (!sw)
3217          {          {
# Line 3157  ui_seamless_move_window(unsigned long id Line 3236  ui_seamless_move_window(unsigned long id
3236    
3237          /* If we move the window in a maximized state, then KDE won't          /* If we move the window in a maximized state, then KDE won't
3238             accept restoration */             accept restoration */
3239          if (sw->state != SEAMLESSRDP_NORMAL)          switch (sw->state)
3240                  return;          {
3241                    case SEAMLESSRDP_MINIMIZED:
3242                    case SEAMLESSRDP_MAXIMIZED:
3243                            return;
3244            }
3245    
3246          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */
3247          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);
3248  }  }
3249    
3250    void
3251    ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags)
3252    {
3253            seamless_window *sw;
3254    
3255            if (!g_seamless_active)
3256                    return;
3257    
3258            sw = seamless_get_window_by_id(id);
3259            if (!sw)
3260            {
3261                    warning("ui_seamless_restack_window: No information for window 0x%lx\n", id);
3262                    return;
3263            }
3264    
3265            if (behind)
3266            {
3267                    seamless_window *sw_behind;
3268                    Window wnds[2];
3269    
3270                    sw_behind = seamless_get_window_by_id(behind);
3271                    if (!sw_behind)
3272                    {
3273                            warning("ui_seamless_restack_window: No information for window 0x%lx\n",
3274                                    behind);
3275                            return;
3276                    }
3277    
3278                    wnds[1] = sw_behind->wnd;
3279                    wnds[0] = sw->wnd;
3280    
3281                    XRestackWindows(g_display, wnds, 2);
3282            }
3283            else
3284            {
3285                    XRaiseWindow(g_display, sw->wnd);
3286            }
3287    }
3288    
3289  void  void
3290  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)
3291  {  {
3292          seamless_window *sw;          seamless_window *sw;
3293    
3294            if (!g_seamless_active)
3295                    return;
3296    
3297          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3298          if (!sw)          if (!sw)
3299          {          {
# Line 3177  ui_seamless_settitle(unsigned long id, c Line 3301  ui_seamless_settitle(unsigned long id, c
3301                  return;                  return;
3302          }          }
3303    
3304            /* FIXME: Might want to convert the name for non-EWMH WMs */
3305          XStoreName(g_display, sw->wnd, title);          XStoreName(g_display, sw->wnd, title);
3306            ewmh_set_wm_name(sw->wnd, title);
3307  }  }
3308    
3309    
# Line 3186  ui_seamless_setstate(unsigned long id, u Line 3312  ui_seamless_setstate(unsigned long id, u
3312  {  {
3313          seamless_window *sw;          seamless_window *sw;
3314    
3315            if (!g_seamless_active)
3316                    return;
3317    
3318          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3319          if (!sw)          if (!sw)
3320          {          {
# Line 3193  ui_seamless_setstate(unsigned long id, u Line 3322  ui_seamless_setstate(unsigned long id, u
3322                  return;                  return;
3323          }          }
3324    
         sw->state = state;  
   
3325          switch (state)          switch (state)
3326          {          {
3327                  case SEAMLESSRDP_NORMAL:                  case SEAMLESSRDP_NORMAL:
3328                  case SEAMLESSRDP_MAXIMIZED:                  case SEAMLESSRDP_MAXIMIZED:
3329                          ewmh_change_state(sw->wnd, state);                          ewmh_change_state(sw->wnd, state);
3330                            XMapWindow(g_display, sw->wnd);
3331                          break;                          break;
3332                  case SEAMLESSRDP_MINIMIZED:                  case SEAMLESSRDP_MINIMIZED:
3333                          /* EWMH says: "if an Application asks to toggle _NET_WM_STATE_HIDDEN                          /* EWMH says: "if an Application asks to toggle _NET_WM_STATE_HIDDEN
# Line 3207  ui_seamless_setstate(unsigned long id, u Line 3335  ui_seamless_setstate(unsigned long id, u
3335                             _NET_WM_STATE_HIDDEN is a function of some other aspect of the window                             _NET_WM_STATE_HIDDEN is a function of some other aspect of the window
3336                             such as minimization, rather than an independent state." Besides,                             such as minimization, rather than an independent state." Besides,
3337                             XIconifyWindow is easier. */                             XIconifyWindow is easier. */
3338                          XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));                          if (sw->state == SEAMLESSRDP_NOTYETMAPPED)
3339                            {
3340                                    XWMHints *hints;
3341                                    hints = XAllocWMHints();
3342                                    hints->flags = StateHint;
3343                                    hints->initial_state = IconicState;
3344                                    XSetWMHints(g_display, sw->wnd, hints);
3345                                    XFree(hints);
3346                                    XMapWindow(g_display, sw->wnd);
3347                            }
3348                            else
3349                                    XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));
3350                          break;                          break;
3351                  default:                  default:
3352                          warning("SeamlessRDP: Invalid state %d\n", state);                          warning("SeamlessRDP: Invalid state %d\n", state);
3353                          break;                          break;
3354          }          }
3355    
3356            /* Handle popups without parents through some ewm hints */
3357            if ((sw->state == SEAMLESSRDP_NOTYETMAPPED) && (sw->parent == 0xFFFFFFFF))
3358                    ewmh_set_window_popup(sw->wnd);
3359    
3360            sw->state = state;
3361  }  }
3362    
3363    
3364  void  void
3365  ui_seamless_syncbegin(unsigned long flags)  ui_seamless_syncbegin(unsigned long flags)
3366  {  {
3367            if (!g_seamless_active)
3368                    return;
3369    
3370          /* Destroy all seamless windows */          /* Destroy all seamless windows */
3371          while (g_seamless_windows)          while (g_seamless_windows)
3372          {          {

Legend:
Removed from v.1123  
changed lines
  Added in v.1154

  ViewVC Help
Powered by ViewVC 1.1.26