/[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 1171 by astrand, Mon Mar 20 15:55:18 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 behind;
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 timeval *position_timer;
63    
64            BOOL outstanding_position;
65            unsigned int outpos_serial;
66            int outpos_xoffset, outpos_yoffset;
67            int outpos_width, outpos_height;
68    
69          struct _seamless_window *next;          struct _seamless_window *next;
70  } seamless_window;  } seamless_window;
71  static seamless_window *g_seamless_windows = NULL;  static seamless_window *g_seamless_windows = NULL;
72    static unsigned long g_seamless_focused = 0;
73    static BOOL g_seamless_started = False; /* Server end is up and running */
74    static BOOL g_seamless_active = False;  /* We are currently in seamless mode */
75  extern BOOL g_seamless_rdp;  extern BOOL g_seamless_rdp;
76    
77  extern uint32 g_embed_wnd;  extern uint32 g_embed_wnd;
# Line 259  static int rop2_map[] = { Line 270  static int rop2_map[] = {
270  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); }
271    
272  static seamless_window *  static seamless_window *
273  seamless_get_window_by_id(unsigned long id)  sw_get_window_by_id(unsigned long id)
274  {  {
275          seamless_window *sw;          seamless_window *sw;
276          for (sw = g_seamless_windows; sw; sw = sw->next)          for (sw = g_seamless_windows; sw; sw = sw->next)
# Line 272  seamless_get_window_by_id(unsigned long Line 283  seamless_get_window_by_id(unsigned long
283    
284    
285  static seamless_window *  static seamless_window *
286  seamless_get_window_by_wnd(Window wnd)  sw_get_window_by_wnd(Window wnd)
287  {  {
288          seamless_window *sw;          seamless_window *sw;
289          for (sw = g_seamless_windows; sw; sw = sw->next)          for (sw = g_seamless_windows; sw; sw = sw->next)
# Line 285  seamless_get_window_by_wnd(Window wnd) Line 296  seamless_get_window_by_wnd(Window wnd)
296    
297    
298  static void  static void
299  seamless_remove_window(seamless_window * win)  sw_remove_window(seamless_window * win)
300  {  {
301          seamless_window *sw, **prevnext = &g_seamless_windows;          seamless_window *sw, **prevnext = &g_seamless_windows;
302          for (sw = g_seamless_windows; sw; sw = sw->next)          for (sw = g_seamless_windows; sw; sw = sw->next)
# Line 304  seamless_remove_window(seamless_window * Line 315  seamless_remove_window(seamless_window *
315    
316  /* Move all windows except wnd to new desktop */  /* Move all windows except wnd to new desktop */
317  static void  static void
318  seamless_all_to_desktop(Window wnd, unsigned int desktop)  sw_all_to_desktop(Window wnd, unsigned int desktop)
319  {  {
320          seamless_window *sw;          seamless_window *sw;
321          for (sw = g_seamless_windows; sw; sw = sw->next)          for (sw = g_seamless_windows; sw; sw = sw->next)
# Line 320  seamless_all_to_desktop(Window wnd, unsi Line 331  seamless_all_to_desktop(Window wnd, unsi
331  }  }
332    
333    
334    /* Send our position */
335    static void
336    sw_update_position(seamless_window * sw)
337    {
338            XWindowAttributes wa;
339            int x, y;
340            Window child_return;
341            unsigned int serial;
342    
343            XGetWindowAttributes(g_display, sw->wnd, &wa);
344            XTranslateCoordinates(g_display, sw->wnd, wa.root,
345                                  -wa.border_width, -wa.border_width, &x, &y, &child_return);
346    
347            serial = seamless_send_position(sw->id, x, y, wa.width, wa.height, 0);
348    
349            sw->outstanding_position = True;
350            sw->outpos_serial = serial;
351    
352            sw->outpos_xoffset = x;
353            sw->outpos_yoffset = y;
354            sw->outpos_width = wa.width;
355            sw->outpos_height = wa.height;
356    }
357    
358    
359    /* Check if it's time to send our position */
360    static void
361    sw_check_timers()
362    {
363            seamless_window *sw;
364            struct timeval now;
365    
366            gettimeofday(&now, NULL);
367            for (sw = g_seamless_windows; sw; sw = sw->next)
368            {
369                    if (timerisset(sw->position_timer) && timercmp(sw->position_timer, &now, <))
370                    {
371                            timerclear(sw->position_timer);
372                            sw_update_position(sw);
373                    }
374            }
375    }
376    
377    
378    static void
379    sw_restack_window(seamless_window * sw, unsigned long behind)
380    {
381            seamless_window *sw_above;
382    
383            /* Remove window from stack */
384            for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)
385            {
386                    if (sw_above->behind == sw->id)
387                            break;
388            }
389    
390            if (sw_above)
391                    sw_above->behind = sw->behind;
392    
393            /* And then add it at the new position */
394    
395            for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)
396            {
397                    if (sw_above->behind == behind)
398                            break;
399            }
400    
401            if (sw_above)
402                    sw_above->behind = sw->id;
403    
404            sw->behind = behind;
405    }
406    
407    
408    static void
409    sw_handle_restack(seamless_window * sw)
410    {
411            Status status;
412            Window root, parent, *children;
413            unsigned int nchildren, i;
414            seamless_window *sw_below;
415    
416            status = XQueryTree(g_display, RootWindowOfScreen(g_screen),
417                                &root, &parent, &children, &nchildren);
418            if (!status || !nchildren)
419                    return;
420    
421            sw_below = NULL;
422    
423            i = 0;
424            while (children[i] != sw->wnd)
425            {
426                    i++;
427                    if (i >= nchildren)
428                            return;
429            }
430    
431            for (i++; i < nchildren; i++)
432            {
433                    sw_below = sw_get_window_by_wnd(children[i]);
434                    if (sw_below)
435                            break;
436            }
437    
438            if (!sw_below && !sw->behind)
439                    return;
440            if (sw_below && (sw_below->id == sw->behind))
441                    return;
442    
443            if (sw_below)
444            {
445                    seamless_send_zchange(sw->id, sw_below->id, 0);
446                    sw_restack_window(sw, sw_below->id);
447            }
448            else
449            {
450                    seamless_send_zchange(sw->id, 0, 0);
451                    sw_restack_window(sw, 0);
452            }
453    }
454    
455    
456  static void  static void
457  mwm_hide_decorations(Window wnd)  mwm_hide_decorations(Window wnd)
458  {  {
# Line 1564  ui_create_window(void) Line 1697  ui_create_window(void)
1697          }          }
1698    
1699          XSelectInput(g_display, g_wnd, input_mask);          XSelectInput(g_display, g_wnd, input_mask);
1700          if (!g_seamless_rdp)  
1701            XMapWindow(g_display, g_wnd);
1702            /* wait for VisibilityNotify */
1703            do
1704          {          {
1705                  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;  
1706          }          }
1707            while (xevent.type != VisibilityNotify);
1708            g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1709    
1710          g_focused = False;          g_focused = False;
1711          g_mouse_in_wnd = False;          g_mouse_in_wnd = False;
# Line 1638  xwin_toggle_fullscreen(void) Line 1769  xwin_toggle_fullscreen(void)
1769  {  {
1770          Pixmap contents = 0;          Pixmap contents = 0;
1771    
1772          if (g_seamless_rdp)          if (g_seamless_active)
1773                  /* Turn off SeamlessRDP mode */                  /* Turn off SeamlessRDP mode */
1774                  ui_seamless_toggle();                  ui_seamless_toggle();
1775    
# Line 1743  handle_button_event(XEvent xevent, BOOL Line 1874  handle_button_event(XEvent xevent, BOOL
1874          }          }
1875  }  }
1876    
1877    
1878  /* Process events in Xlib queue  /* Process events in Xlib queue
1879     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1880  static int  static int
# Line 1875  xwin_process_events(void) Line 2007  xwin_process_events(void)
2007                                  if (g_grab_keyboard && g_mouse_in_wnd)                                  if (g_grab_keyboard && g_mouse_in_wnd)
2008                                          XGrabKeyboard(g_display, g_wnd, True,                                          XGrabKeyboard(g_display, g_wnd, True,
2009                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
2010    
2011                                    sw = sw_get_window_by_wnd(xevent.xfocus.window);
2012                                    if (!sw)
2013                                            break;
2014    
2015                                    if (sw->id != g_seamless_focused)
2016                                    {
2017                                            seamless_send_focus(sw->id, 0);
2018                                            g_seamless_focused = sw->id;
2019                                    }
2020                                  break;                                  break;
2021    
2022                          case FocusOut:                          case FocusOut:
# Line 1917  xwin_process_events(void) Line 2059  xwin_process_events(void)
2059                                  }                                  }
2060                                  else                                  else
2061                                  {                                  {
2062                                          sw = seamless_get_window_by_wnd(xevent.xexpose.window);                                          sw = sw_get_window_by_wnd(xevent.xexpose.window);
2063                                          if (sw)                                          if (sw)
2064                                                  XCopyArea(g_display, g_backstore,                                                  XCopyArea(g_display, g_backstore,
2065                                                            xevent.xexpose.window, g_gc,                                                            xevent.xexpose.window, g_gc,
# Line 1967  xwin_process_events(void) Line 2109  xwin_process_events(void)
2109                                          break;                                          break;
2110    
2111                                  /* seamless */                                  /* seamless */
2112                                  sw = seamless_get_window_by_wnd(xevent.xproperty.window);                                  sw = sw_get_window_by_wnd(xevent.xproperty.window);
2113                                  if (!sw)                                  if (!sw)
2114                                          break;                                          break;
2115    
# Line 1982  xwin_process_events(void) Line 2124  xwin_process_events(void)
2124                                      && (xevent.xproperty.state == PropertyNewValue))                                      && (xevent.xproperty.state == PropertyNewValue))
2125                                  {                                  {
2126                                          sw->desktop = ewmh_get_window_desktop(sw->wnd);                                          sw->desktop = ewmh_get_window_desktop(sw->wnd);
2127                                          seamless_all_to_desktop(sw->wnd, sw->desktop);                                          sw_all_to_desktop(sw->wnd, sw->desktop);
2128                                  }                                  }
2129    
2130                                  break;                                  break;
2131                          case MapNotify:                          case MapNotify:
2132                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2133                                          rdp_send_client_window_status(1);                                          rdp_send_client_window_status(1);
2134                                  break;                                  break;
2135                          case UnmapNotify:                          case UnmapNotify:
2136                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2137                                          rdp_send_client_window_status(0);                                          rdp_send_client_window_status(0);
2138                                  break;                                  break;
2139                            case ConfigureNotify:
2140                                    if (!g_seamless_active)
2141                                            break;
2142    
2143                                    sw = sw_get_window_by_wnd(xevent.xconfigure.window);
2144                                    if (!sw)
2145                                    {
2146                                            error("ConfigureNotify for unknown window 0x%lx\n",
2147                                                  xevent.xconfigure.window);
2148                                    }
2149    
2150                                    gettimeofday(sw->position_timer, NULL);
2151                                    if (sw->position_timer->tv_usec + SEAMLESSRDP_POSITION_TIMER >=
2152                                        1000000)
2153                                    {
2154                                            sw->position_timer->tv_usec +=
2155                                                    SEAMLESSRDP_POSITION_TIMER - 1000000;
2156                                            sw->position_timer->tv_sec += 1;
2157                                    }
2158                                    else
2159                                    {
2160                                            sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER;
2161                                    }
2162    
2163                                    sw_handle_restack(sw);
2164                                    break;
2165                  }                  }
2166          }          }
2167          /* Keep going */          /* Keep going */
# Line 2017  ui_select(int rdp_socket) Line 2185  ui_select(int rdp_socket)
2185                          /* User quit */                          /* User quit */
2186                          return 0;                          return 0;
2187    
2188                    if (g_seamless_active)
2189                            sw_check_timers();
2190    
2191                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
2192                  FD_ZERO(&wfds);                  FD_ZERO(&wfds);
2193                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
# Line 2036  ui_select(int rdp_socket) Line 2207  ui_select(int rdp_socket)
2207    
2208                  /* add redirection handles */                  /* add redirection handles */
2209                  rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);                  rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
2210                    seamless_select_timeout(&tv);
2211    
2212                  n++;                  n++;
2213    
# Line 3004  ui_end_update(void) Line 3176  ui_end_update(void)
3176  {  {
3177  }  }
3178    
3179    
3180    void
3181    ui_seamless_begin()
3182    {
3183            if (!g_seamless_rdp)
3184                    return;
3185    
3186            if (g_seamless_started)
3187                    return;
3188    
3189            g_seamless_started = True;
3190            ui_seamless_toggle();
3191    }
3192    
3193    
3194  void  void
3195  ui_seamless_toggle()  ui_seamless_toggle()
3196  {  {
3197          if (g_seamless_rdp)          if (!g_seamless_rdp)
3198                    return;
3199    
3200            if (!g_seamless_started)
3201                    return;
3202    
3203            if (g_seamless_active)
3204          {          {
3205                  /* Deactivate */                  /* Deactivate */
3206                  while (g_seamless_windows)                  while (g_seamless_windows)
3207                  {                  {
3208                          XDestroyWindow(g_display, g_seamless_windows->wnd);                          XDestroyWindow(g_display, g_seamless_windows->wnd);
3209                          seamless_remove_window(g_seamless_windows);                          sw_remove_window(g_seamless_windows);
3210                  }                  }
3211                  XMapWindow(g_display, g_wnd);                  XMapWindow(g_display, g_wnd);
3212          }          }
3213          else          else
3214          {          {
3215                  /* 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;  
                 }  
   
3216                  XUnmapWindow(g_display, g_wnd);                  XUnmapWindow(g_display, g_wnd);
3217                  seamless_send_sync();                  seamless_send_sync();
3218          }          }
3219    
3220          g_seamless_rdp = !g_seamless_rdp;          g_seamless_active = !g_seamless_active;
3221  }  }
3222    
3223    
3224  void  void
3225  ui_seamless_create_window(unsigned long id, unsigned long parent, unsigned long flags)  ui_seamless_create_window(unsigned long id, unsigned long parent, unsigned long flags)
3226  {  {
3227          Window wnd;          Window wnd;
3228          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
3229          XClassHint *classhints;          XClassHint *classhints;
3230            XSizeHints *sizehints;
3231          long input_mask;          long input_mask;
3232          seamless_window *sw, *sw_parent;          seamless_window *sw, *sw_parent;
3233    
3234            if (!g_seamless_active)
3235                    return;
3236    
3237          /* Ignore CREATEs for existing windows */          /* Ignore CREATEs for existing windows */
3238          sw = seamless_get_window_by_id(id);          sw = sw_get_window_by_id(id);
3239          if (sw)          if (sw)
3240                  return;                  return;
3241    
3242          get_window_attribs(&attribs);          get_window_attribs(&attribs);
3243          attribs.override_redirect = False;          wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), -1, -1, 1, 1, 0, g_depth,
   
         /* FIXME: Do not assume that -1, -1 is outside screen Consider  
            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,  
3244                              InputOutput, g_visual,                              InputOutput, g_visual,
3245                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |                              CWBackPixel | CWBackingStore | CWColormap | CWBorderPixel, &attribs);
                             CWBorderPixel, &attribs);  
3246    
3247          XStoreName(g_display, wnd, "rdesktop-seamless");          XStoreName(g_display, wnd, "SeamlessRDP");
3248            ewmh_set_wm_name(wnd, "SeamlessRDP");
3249    
3250          mwm_hide_decorations(wnd);          mwm_hide_decorations(wnd);
3251    
3252          classhints = XAllocClassHint();          classhints = XAllocClassHint();
3253          if (classhints != NULL)          if (classhints != NULL)
3254          {          {
3255                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = "rdesktop";
3256                    classhints->res_class = "SeamlessRDP";
3257                  XSetClassHint(g_display, wnd, classhints);                  XSetClassHint(g_display, wnd, classhints);
3258                  XFree(classhints);                  XFree(classhints);
3259          }          }
3260    
3261            /* WM_NORMAL_HINTS */
3262            sizehints = XAllocSizeHints();
3263            if (sizehints != NULL)
3264            {
3265                    sizehints->flags = USPosition;
3266                    XSetWMNormalHints(g_display, wnd, sizehints);
3267                    XFree(sizehints);
3268            }
3269    
3270            /* Handle popups without parents through some ewm hints */
3271            if (parent == 0xFFFFFFFF)
3272                    ewmh_set_window_popup(wnd);
3273          /* Set WM_TRANSIENT_FOR, if necessary */          /* Set WM_TRANSIENT_FOR, if necessary */
3274          if (parent)          else if (parent != 0x00000000)
3275          {          {
3276                  sw_parent = seamless_get_window_by_id(parent);                  sw_parent = sw_get_window_by_id(parent);
3277                  if (sw_parent)                  if (sw_parent)
3278                          XSetTransientForHint(g_display, wnd, sw_parent->wnd);                          XSetTransientForHint(g_display, wnd, sw_parent->wnd);
3279                  else                  else
3280                          warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);                          warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);
3281          }          }
3282    
3283    
3284          /* FIXME: Support for Input Context:s */          /* FIXME: Support for Input Context:s */
3285    
3286          get_input_mask(&input_mask);          get_input_mask(&input_mask);
# Line 3092  ui_seamless_create_window(unsigned long Line 3288  ui_seamless_create_window(unsigned long
3288    
3289          XSelectInput(g_display, wnd, input_mask);          XSelectInput(g_display, wnd, input_mask);
3290    
         XMapWindow(g_display, wnd);  
   
3291          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a
3292             seamless window, we could try to close the window on the             seamless window, we could try to close the window on the
3293             serverside, instead of terminating rdesktop */             serverside, instead of terminating rdesktop */
3294          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);
3295    
3296          sw = malloc(sizeof(seamless_window));          sw = xmalloc(sizeof(seamless_window));
3297          sw->wnd = wnd;          sw->wnd = wnd;
3298          sw->id = id;          sw->id = id;
3299            sw->behind = 0;
3300          sw->xoffset = 0;          sw->xoffset = 0;
3301          sw->yoffset = 0;          sw->yoffset = 0;
3302          sw->width = 0;          sw->width = 0;
3303          sw->height = 0;          sw->height = 0;
3304            sw->state = SEAMLESSRDP_NOTYETMAPPED;
3305            sw->desktop = 0;
3306            sw->position_timer = xmalloc(sizeof(struct timeval));
3307            timerclear(sw->position_timer);
3308            sw->outstanding_position = False;
3309          sw->next = g_seamless_windows;          sw->next = g_seamless_windows;
3310          g_seamless_windows = sw;          g_seamless_windows = sw;
3311  }  }
# Line 3116  ui_seamless_destroy_window(unsigned long Line 3316  ui_seamless_destroy_window(unsigned long
3316  {  {
3317          seamless_window *sw;          seamless_window *sw;
3318    
3319          sw = seamless_get_window_by_id(id);          if (!g_seamless_active)
3320                    return;
3321    
3322            sw = sw_get_window_by_id(id);
3323          if (!sw)          if (!sw)
3324          {          {
3325                  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 3124  ui_seamless_destroy_window(unsigned long Line 3327  ui_seamless_destroy_window(unsigned long
3327          }          }
3328    
3329          XDestroyWindow(g_display, sw->wnd);          XDestroyWindow(g_display, sw->wnd);
3330          seamless_remove_window(sw);          sw_remove_window(sw);
3331  }  }
3332    
3333    
# Line 3133  ui_seamless_move_window(unsigned long id Line 3336  ui_seamless_move_window(unsigned long id
3336  {  {
3337          seamless_window *sw;          seamless_window *sw;
3338    
3339          sw = seamless_get_window_by_id(id);          if (!g_seamless_active)
3340                    return;
3341    
3342            sw = sw_get_window_by_id(id);
3343          if (!sw)          if (!sw)
3344          {          {
3345                  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);
3346                  return;                  return;
3347          }          }
3348    
3349            /* We ignore server updates until it has handled our request. */
3350            if (sw->outstanding_position)
3351                    return;
3352    
3353          if (!width || !height)          if (!width || !height)
3354                  /* X11 windows must be at least 1x1 */                  /* X11 windows must be at least 1x1 */
3355                  return;                  return;
3356    
3357          /* About MAX and MIN: Windows allows moving a window outside          sw->xoffset = x;
3358             the desktop. This happens, for example, when maximizing an          sw->yoffset = y;
3359             application. In this case, the position is set to something          sw->width = width;
3360             like -4,-4,1288,1032. Many WMs does not allow windows          sw->height = height;
            outside the desktop, however. Therefore, clip the window  
            ourselves. */  
         sw->xoffset = MAX(0, x);  
         sw->yoffset = MAX(0, y);  
         sw->width = MIN(MIN(width, width + x), g_width - sw->xoffset);  
         sw->height = MIN(MIN(height, height + y), g_height - sw->yoffset);  
3361    
3362          /* 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
3363             accept restoration */             accept restoration */
3364          if (sw->state != SEAMLESSRDP_NORMAL)          switch (sw->state)
3365                  return;          {
3366                    case SEAMLESSRDP_MINIMIZED:
3367                    case SEAMLESSRDP_MAXIMIZED:
3368                            return;
3369            }
3370    
3371          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */
3372          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);
# Line 3166  ui_seamless_move_window(unsigned long id Line 3374  ui_seamless_move_window(unsigned long id
3374    
3375    
3376  void  void
3377    ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags)
3378    {
3379            seamless_window *sw;
3380    
3381            if (!g_seamless_active)
3382                    return;
3383    
3384            sw = sw_get_window_by_id(id);
3385            if (!sw)
3386            {
3387                    warning("ui_seamless_restack_window: No information for window 0x%lx\n", id);
3388                    return;
3389            }
3390    
3391            if (behind)
3392            {
3393                    seamless_window *sw_behind;
3394                    Window wnds[2];
3395    
3396                    sw_behind = sw_get_window_by_id(behind);
3397                    if (!sw_behind)
3398                    {
3399                            warning("ui_seamless_restack_window: No information for window 0x%lx\n",
3400                                    behind);
3401                            return;
3402                    }
3403    
3404                    wnds[1] = sw_behind->wnd;
3405                    wnds[0] = sw->wnd;
3406    
3407                    XRestackWindows(g_display, wnds, 2);
3408            }
3409            else
3410            {
3411                    XRaiseWindow(g_display, sw->wnd);
3412            }
3413    
3414            sw_restack_window(sw, behind);
3415    }
3416    
3417    
3418    void
3419  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)
3420  {  {
3421          seamless_window *sw;          seamless_window *sw;
3422    
3423          sw = seamless_get_window_by_id(id);          if (!g_seamless_active)
3424                    return;
3425    
3426            sw = sw_get_window_by_id(id);
3427          if (!sw)          if (!sw)
3428          {          {
3429                  warning("ui_seamless_settitle: No information for window 0x%lx\n", id);                  warning("ui_seamless_settitle: No information for window 0x%lx\n", id);
3430                  return;                  return;
3431          }          }
3432    
3433            /* FIXME: Might want to convert the name for non-EWMH WMs */
3434          XStoreName(g_display, sw->wnd, title);          XStoreName(g_display, sw->wnd, title);
3435            ewmh_set_wm_name(sw->wnd, title);
3436  }  }
3437    
3438    
# Line 3186  ui_seamless_setstate(unsigned long id, u Line 3441  ui_seamless_setstate(unsigned long id, u
3441  {  {
3442          seamless_window *sw;          seamless_window *sw;
3443    
3444          sw = seamless_get_window_by_id(id);          if (!g_seamless_active)
3445                    return;
3446    
3447            sw = sw_get_window_by_id(id);
3448          if (!sw)          if (!sw)
3449          {          {
3450                  warning("ui_seamless_setstate: No information for window 0x%lx\n", id);                  warning("ui_seamless_setstate: No information for window 0x%lx\n", id);
3451                  return;                  return;
3452          }          }
3453    
         sw->state = state;  
   
3454          switch (state)          switch (state)
3455          {          {
3456                  case SEAMLESSRDP_NORMAL:                  case SEAMLESSRDP_NORMAL:
3457                  case SEAMLESSRDP_MAXIMIZED:                  case SEAMLESSRDP_MAXIMIZED:
3458                          ewmh_change_state(sw->wnd, state);                          ewmh_change_state(sw->wnd, state);
3459                            XMapWindow(g_display, sw->wnd);
3460                          break;                          break;
3461                  case SEAMLESSRDP_MINIMIZED:                  case SEAMLESSRDP_MINIMIZED:
3462                          /* 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 3464  ui_seamless_setstate(unsigned long id, u
3464                             _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
3465                             such as minimization, rather than an independent state." Besides,                             such as minimization, rather than an independent state." Besides,
3466                             XIconifyWindow is easier. */                             XIconifyWindow is easier. */
3467                          XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));                          if (sw->state == SEAMLESSRDP_NOTYETMAPPED)
3468                            {
3469                                    XWMHints *hints;
3470                                    hints = XAllocWMHints();
3471                                    hints->flags = StateHint;
3472                                    hints->initial_state = IconicState;
3473                                    XSetWMHints(g_display, sw->wnd, hints);
3474                                    XFree(hints);
3475                                    XMapWindow(g_display, sw->wnd);
3476                            }
3477                            else
3478                                    XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));
3479                          break;                          break;
3480                  default:                  default:
3481                          warning("SeamlessRDP: Invalid state %d\n", state);                          warning("SeamlessRDP: Invalid state %d\n", state);
3482                          break;                          break;
3483          }          }
3484    
3485            sw->state = state;
3486  }  }
3487    
3488    
3489  void  void
3490  ui_seamless_syncbegin(unsigned long flags)  ui_seamless_syncbegin(unsigned long flags)
3491  {  {
3492            if (!g_seamless_active)
3493                    return;
3494    
3495          /* Destroy all seamless windows */          /* Destroy all seamless windows */
3496          while (g_seamless_windows)          while (g_seamless_windows)
3497          {          {
3498                  XDestroyWindow(g_display, g_seamless_windows->wnd);                  XDestroyWindow(g_display, g_seamless_windows->wnd);
3499                  seamless_remove_window(g_seamless_windows);                  sw_remove_window(g_seamless_windows);
3500            }
3501    }
3502    
3503    
3504    void
3505    ui_seamless_ack(unsigned int serial)
3506    {
3507            seamless_window *sw;
3508            for (sw = g_seamless_windows; sw; sw = sw->next)
3509            {
3510                    if (sw->outpos_serial == serial)
3511                    {
3512                            sw->xoffset = sw->outpos_xoffset;
3513                            sw->yoffset = sw->outpos_yoffset;
3514                            sw->width = sw->outpos_width;
3515                            sw->height = sw->outpos_height;
3516                            sw->outstanding_position = False;
3517                            break;
3518                    }
3519          }          }
3520    
3521            return;
3522  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26