/[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 1122 by astrand, Wed Mar 15 08:35:13 2006 UTC revision 1151 by ossman_, Fri Mar 17 08:52:29 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 1987  xwin_process_events(void) Line 2024  xwin_process_events(void)
2024    
2025                                  break;                                  break;
2026                          case MapNotify:                          case MapNotify:
2027                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2028                                          rdp_send_client_window_status(1);                                          rdp_send_client_window_status(1);
2029                                  break;                                  break;
2030                          case UnmapNotify:                          case UnmapNotify:
2031                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2032                                          rdp_send_client_window_status(0);                                          rdp_send_client_window_status(0);
2033                                  break;                                  break;
2034                            case ConfigureNotify:
2035                                    /* seamless */
2036                                    sw = seamless_get_window_by_wnd(xevent.xconfigure.window);
2037                                    if (!sw)
2038                                            break;
2039    
2040                                    ui_seamless_handle_restack(sw);
2041                  }                  }
2042          }          }
2043          /* Keep going */          /* Keep going */
# Line 3005  ui_end_update(void) Line 3049  ui_end_update(void)
3049  }  }
3050    
3051  void  void
3052    ui_seamless_begin()
3053    {
3054            if (!g_seamless_rdp)
3055                    return;
3056    
3057            if (g_seamless_started)
3058                    return;
3059    
3060            g_seamless_started = True;
3061    
3062            ui_seamless_toggle();
3063    }
3064    
3065    void
3066  ui_seamless_toggle()  ui_seamless_toggle()
3067  {  {
3068          if (g_seamless_rdp)          if (!g_seamless_rdp)
3069                    return;
3070    
3071            if (!g_seamless_started)
3072                    return;
3073    
3074            if (g_seamless_active)
3075          {          {
3076                  /* Deactivate */                  /* Deactivate */
3077                  while (g_seamless_windows)                  while (g_seamless_windows)
# Line 3020  ui_seamless_toggle() Line 3084  ui_seamless_toggle()
3084          else          else
3085          {          {
3086                  /* 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;  
                 }  
   
3087                  XUnmapWindow(g_display, g_wnd);                  XUnmapWindow(g_display, g_wnd);
3088                  seamless_send_sync();                  seamless_send_sync();
3089          }          }
3090    
3091          g_seamless_rdp = !g_seamless_rdp;          g_seamless_active = !g_seamless_active;
3092  }  }
3093    
3094  void  void
# Line 3044  ui_seamless_create_window(unsigned long Line 3097  ui_seamless_create_window(unsigned long
3097          Window wnd;          Window wnd;
3098          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
3099          XClassHint *classhints;          XClassHint *classhints;
3100            XSizeHints *sizehints;
3101          long input_mask;          long input_mask;
3102          seamless_window *sw, *sw_parent;          seamless_window *sw, *sw_parent;
3103    
3104            if (!g_seamless_active)
3105                    return;
3106    
3107          /* Ignore CREATEs for existing windows */          /* Ignore CREATEs for existing windows */
3108          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3109          if (sw)          if (sw)
# Line 3055  ui_seamless_create_window(unsigned long Line 3112  ui_seamless_create_window(unsigned long
3112          get_window_attribs(&attribs);          get_window_attribs(&attribs);
3113          attribs.override_redirect = False;          attribs.override_redirect = False;
3114    
3115          /* 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,  
3116                              InputOutput, g_visual,                              InputOutput, g_visual,
3117                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
3118                              CWBorderPixel, &attribs);                              CWBorderPixel, &attribs);
3119    
3120          XStoreName(g_display, wnd, "rdesktop-seamless");          XStoreName(g_display, wnd, "SeamlessRDP");
3121            ewmh_set_wm_name(wnd, "SeamlessRDP");
3122    
3123          mwm_hide_decorations(wnd);          mwm_hide_decorations(wnd);
3124    
3125          classhints = XAllocClassHint();          classhints = XAllocClassHint();
3126          if (classhints != NULL)          if (classhints != NULL)
3127          {          {
3128                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = "rdesktop";
3129                    classhints->res_class = "SeamlessRDP";
3130                  XSetClassHint(g_display, wnd, classhints);                  XSetClassHint(g_display, wnd, classhints);
3131                  XFree(classhints);                  XFree(classhints);
3132          }          }
3133    
3134            /* WM_NORMAL_HINTS */
3135            sizehints = XAllocSizeHints();
3136            if (sizehints != NULL)
3137            {
3138                    sizehints->flags = USPosition;
3139                    XSetWMNormalHints(g_display, wnd, sizehints);
3140                    XFree(sizehints);
3141            }
3142    
3143          /* Set WM_TRANSIENT_FOR, if necessary */          /* Set WM_TRANSIENT_FOR, if necessary */
3144          if (parent)          if ((parent != 0x00000000) && (parent != 0xFFFFFFFF))
3145          {          {
3146                  sw_parent = seamless_get_window_by_id(parent);                  sw_parent = seamless_get_window_by_id(parent);
3147                  if (sw_parent)                  if (sw_parent)
# Line 3085  ui_seamless_create_window(unsigned long Line 3150  ui_seamless_create_window(unsigned long
3150                          warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);                          warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);
3151          }          }
3152    
3153    
3154          /* FIXME: Support for Input Context:s */          /* FIXME: Support for Input Context:s */
3155    
3156          get_input_mask(&input_mask);          get_input_mask(&input_mask);
# Line 3092  ui_seamless_create_window(unsigned long Line 3158  ui_seamless_create_window(unsigned long
3158    
3159          XSelectInput(g_display, wnd, input_mask);          XSelectInput(g_display, wnd, input_mask);
3160    
         XMapWindow(g_display, wnd);  
   
3161          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a
3162             seamless window, we could try to close the window on the             seamless window, we could try to close the window on the
3163             serverside, instead of terminating rdesktop */             serverside, instead of terminating rdesktop */
# Line 3102  ui_seamless_create_window(unsigned long Line 3166  ui_seamless_create_window(unsigned long
3166          sw = malloc(sizeof(seamless_window));          sw = malloc(sizeof(seamless_window));
3167          sw->wnd = wnd;          sw->wnd = wnd;
3168          sw->id = id;          sw->id = id;
3169            sw->parent = parent;
3170          sw->xoffset = 0;          sw->xoffset = 0;
3171          sw->yoffset = 0;          sw->yoffset = 0;
3172          sw->width = 0;          sw->width = 0;
3173          sw->height = 0;          sw->height = 0;
3174            sw->state = SEAMLESSRDP_NOTYETMAPPED;
3175            sw->desktop = 0;
3176          sw->next = g_seamless_windows;          sw->next = g_seamless_windows;
3177          g_seamless_windows = sw;          g_seamless_windows = sw;
3178  }  }
# Line 3116  ui_seamless_destroy_window(unsigned long Line 3183  ui_seamless_destroy_window(unsigned long
3183  {  {
3184          seamless_window *sw;          seamless_window *sw;
3185    
3186            if (!g_seamless_active)
3187                    return;
3188    
3189          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3190          if (!sw)          if (!sw)
3191          {          {
# Line 3133  ui_seamless_move_window(unsigned long id Line 3203  ui_seamless_move_window(unsigned long id
3203  {  {
3204          seamless_window *sw;          seamless_window *sw;
3205    
3206            if (!g_seamless_active)
3207                    return;
3208    
3209          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3210          if (!sw)          if (!sw)
3211          {          {
# Line 3157  ui_seamless_move_window(unsigned long id Line 3230  ui_seamless_move_window(unsigned long id
3230    
3231          /* 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
3232             accept restoration */             accept restoration */
3233          if (sw->state != SEAMLESSRDP_NORMAL)          switch (sw->state)
3234                  return;          {
3235                    case SEAMLESSRDP_MINIMIZED:
3236                    case SEAMLESSRDP_MAXIMIZED:
3237                            return;
3238            }
3239    
3240          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */
3241          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);
3242  }  }
3243    
3244    void
3245    ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags)
3246    {
3247            seamless_window *sw;
3248    
3249            if (!g_seamless_active)
3250                    return;
3251    
3252            sw = seamless_get_window_by_id(id);
3253            if (!sw)
3254            {
3255                    warning("ui_seamless_restack_window: No information for window 0x%lx\n", id);
3256                    return;
3257            }
3258    
3259            if (behind)
3260            {
3261                    seamless_window *sw_behind;
3262                    Window wnds[2];
3263    
3264                    sw_behind = seamless_get_window_by_id(behind);
3265                    if (!sw_behind)
3266                    {
3267                            warning("ui_seamless_restack_window: No information for window 0x%lx\n",
3268                                    behind);
3269                            return;
3270                    }
3271    
3272                    wnds[1] = sw_behind->wnd;
3273                    wnds[0] = sw->wnd;
3274    
3275                    XRestackWindows(g_display, wnds, 2);
3276            }
3277            else
3278            {
3279                    XRaiseWindow(g_display, sw->wnd);
3280            }
3281    }
3282    
3283  void  void
3284  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)
3285  {  {
3286          seamless_window *sw;          seamless_window *sw;
3287    
3288            if (!g_seamless_active)
3289                    return;
3290    
3291          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3292          if (!sw)          if (!sw)
3293          {          {
# Line 3177  ui_seamless_settitle(unsigned long id, c Line 3295  ui_seamless_settitle(unsigned long id, c
3295                  return;                  return;
3296          }          }
3297    
3298            /* FIXME: Might want to convert the name for non-EWMH WMs */
3299          XStoreName(g_display, sw->wnd, title);          XStoreName(g_display, sw->wnd, title);
3300            ewmh_set_wm_name(sw->wnd, title);
3301  }  }
3302    
3303    
# Line 3186  ui_seamless_setstate(unsigned long id, u Line 3306  ui_seamless_setstate(unsigned long id, u
3306  {  {
3307          seamless_window *sw;          seamless_window *sw;
3308    
3309            if (!g_seamless_active)
3310                    return;
3311    
3312          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3313          if (!sw)          if (!sw)
3314          {          {
# Line 3193  ui_seamless_setstate(unsigned long id, u Line 3316  ui_seamless_setstate(unsigned long id, u
3316                  return;                  return;
3317          }          }
3318    
         sw->state = state;  
   
3319          switch (state)          switch (state)
3320          {          {
3321                  case SEAMLESSRDP_NORMAL:                  case SEAMLESSRDP_NORMAL:
3322                  case SEAMLESSRDP_MAXIMIZED:                  case SEAMLESSRDP_MAXIMIZED:
3323                          ewmh_change_state(sw->wnd, state);                          ewmh_change_state(sw->wnd, state);
3324                            XMapWindow(g_display, sw->wnd);
3325                          break;                          break;
3326                  case SEAMLESSRDP_MINIMIZED:                  case SEAMLESSRDP_MINIMIZED:
3327                          /* 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 3329  ui_seamless_setstate(unsigned long id, u
3329                             _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
3330                             such as minimization, rather than an independent state." Besides,                             such as minimization, rather than an independent state." Besides,
3331                             XIconifyWindow is easier. */                             XIconifyWindow is easier. */
3332                          XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));                          if (sw->state == SEAMLESSRDP_NOTYETMAPPED)
3333                            {
3334                                    XWMHints *hints;
3335                                    hints = XAllocWMHints();
3336                                    hints->flags = StateHint;
3337                                    hints->initial_state = IconicState;
3338                                    XSetWMHints(g_display, sw->wnd, hints);
3339                                    XFree(hints);
3340                                    XMapWindow(g_display, sw->wnd);
3341                            }
3342                            else
3343                                    XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));
3344                          break;                          break;
3345                  default:                  default:
3346                          warning("SeamlessRDP: Invalid state %d\n", state);                          warning("SeamlessRDP: Invalid state %d\n", state);
3347                          break;                          break;
3348          }          }
3349    
3350            /* Handle popups without parents through some ewm hints */
3351            if ((sw->state == SEAMLESSRDP_NOTYETMAPPED) && (sw->parent == 0xFFFFFFFF))
3352                    ewmh_set_window_popup(sw->wnd);
3353    
3354            sw->state = state;
3355    }
3356    
3357    
3358    void
3359    ui_seamless_syncbegin(unsigned long flags)
3360    {
3361            if (!g_seamless_active)
3362                    return;
3363    
3364            /* Destroy all seamless windows */
3365            while (g_seamless_windows)
3366            {
3367                    XDestroyWindow(g_display, g_seamless_windows->wnd);
3368                    seamless_remove_window(g_seamless_windows);
3369            }
3370  }  }

Legend:
Removed from v.1122  
changed lines
  Added in v.1151

  ViewVC Help
Powered by ViewVC 1.1.26