/[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 1118 by astrand, Tue Mar 14 13:56:50 2006 UTC revision 1149 by ossman_, Thu Mar 16 15:27:59 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;
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 85  static Cursor g_current_cursor; Line 89  static Cursor g_current_cursor;
89  static HCURSOR g_null_cursor = NULL;  static HCURSOR g_null_cursor = NULL;
90  static Atom g_protocol_atom, g_kill_atom;  static Atom g_protocol_atom, g_kill_atom;
91  extern Atom g_net_wm_state_atom;  extern Atom g_net_wm_state_atom;
92    extern Atom g_net_wm_desktop_atom;
93  static BOOL g_focused;  static BOOL g_focused;
94  static BOOL g_mouse_in_wnd;  static BOOL g_mouse_in_wnd;
95  /* Indicates that:  /* Indicates that:
# Line 300  seamless_remove_window(seamless_window * Line 305  seamless_remove_window(seamless_window *
305  }  }
306    
307    
308    /* Move all windows except wnd to new desktop */
309    static void
310    seamless_all_to_desktop(Window wnd, unsigned int desktop)
311    {
312            seamless_window *sw;
313            for (sw = g_seamless_windows; sw; sw = sw->next)
314            {
315                    if (sw->wnd == wnd)
316                            continue;
317                    if (sw->desktop != desktop)
318                    {
319                            ewmh_move_to_desktop(sw->wnd, desktop);
320                            sw->desktop = desktop;
321                    }
322            }
323    }
324    
325    
326  static void  static void
327  mwm_hide_decorations(Window wnd)  mwm_hide_decorations(Window wnd)
328  {  {
# Line 1544  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 1618  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 1957  xwin_process_events(void) Line 1978  xwin_process_events(void)
1978                                          sw->state = ewmh_get_window_state(sw->wnd);                                          sw->state = ewmh_get_window_state(sw->wnd);
1979                                          seamless_send_state(sw->id, sw->state, 0);                                          seamless_send_state(sw->id, sw->state, 0);
1980                                  }                                  }
1981    
1982                                    if ((xevent.xproperty.atom == g_net_wm_desktop_atom)
1983                                        && (xevent.xproperty.state == PropertyNewValue))
1984                                    {
1985                                            sw->desktop = ewmh_get_window_desktop(sw->wnd);
1986                                            seamless_all_to_desktop(sw->wnd, sw->desktop);
1987                                    }
1988    
1989                                  break;                                  break;
1990                          case MapNotify:                          case MapNotify:
1991                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
1992                                          rdp_send_client_window_status(1);                                          rdp_send_client_window_status(1);
1993                                  break;                                  break;
1994                          case UnmapNotify:                          case UnmapNotify:
1995                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
1996                                          rdp_send_client_window_status(0);                                          rdp_send_client_window_status(0);
1997                                  break;                                  break;
1998                  }                  }
# Line 2977  ui_end_update(void) Line 3006  ui_end_update(void)
3006  }  }
3007    
3008  void  void
3009    ui_seamless_begin()
3010    {
3011            if (!g_seamless_rdp)
3012                    return;
3013    
3014            if (g_seamless_started)
3015                    return;
3016    
3017            g_seamless_started = True;
3018    
3019            ui_seamless_toggle();
3020    }
3021    
3022    void
3023  ui_seamless_toggle()  ui_seamless_toggle()
3024  {  {
3025          if (g_seamless_rdp)          if (!g_seamless_rdp)
3026                    return;
3027    
3028            if (!g_seamless_started)
3029                    return;
3030    
3031            if (g_seamless_active)
3032          {          {
3033                  /* Deactivate */                  /* Deactivate */
3034                  while (g_seamless_windows)                  while (g_seamless_windows)
# Line 2992  ui_seamless_toggle() Line 3041  ui_seamless_toggle()
3041          else          else
3042          {          {
3043                  /* 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;  
                 }  
   
3044                  XUnmapWindow(g_display, g_wnd);                  XUnmapWindow(g_display, g_wnd);
3045                  seamless_send_sync();                  seamless_send_sync();
3046          }          }
3047    
3048          g_seamless_rdp = !g_seamless_rdp;          g_seamless_active = !g_seamless_active;
3049  }  }
3050    
3051  void  void
# Line 3016  ui_seamless_create_window(unsigned long Line 3054  ui_seamless_create_window(unsigned long
3054          Window wnd;          Window wnd;
3055          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
3056          XClassHint *classhints;          XClassHint *classhints;
3057            XSizeHints *sizehints;
3058          long input_mask;          long input_mask;
3059          seamless_window *sw, *sw_parent;          seamless_window *sw, *sw_parent;
3060    
3061          get_window_attribs(&attribs);          if (!g_seamless_active)
3062                    return;
3063    
3064            /* Ignore CREATEs for existing windows */
3065            sw = seamless_get_window_by_id(id);
3066            if (sw)
3067                    return;
3068    
3069            get_window_attribs(&attribs);
3070          attribs.override_redirect = False;          attribs.override_redirect = False;
3071    
3072          /* 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,  
3073                              InputOutput, g_visual,                              InputOutput, g_visual,
3074                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
3075                              CWBorderPixel, &attribs);                              CWBorderPixel, &attribs);
3076    
3077          XStoreName(g_display, wnd, "rdesktop-seamless");          XStoreName(g_display, wnd, "SeamlessRDP");
3078            ewmh_set_wm_name(wnd, "SeamlessRDP");
3079    
3080          mwm_hide_decorations(wnd);          mwm_hide_decorations(wnd);
3081    
3082          classhints = XAllocClassHint();          classhints = XAllocClassHint();
3083          if (classhints != NULL)          if (classhints != NULL)
3084          {          {
3085                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = "rdesktop";
3086                    classhints->res_class = "SeamlessRDP";
3087                  XSetClassHint(g_display, wnd, classhints);                  XSetClassHint(g_display, wnd, classhints);
3088                  XFree(classhints);                  XFree(classhints);
3089          }          }
3090    
3091            /* WM_NORMAL_HINTS */
3092            sizehints = XAllocSizeHints();
3093            if (sizehints != NULL)
3094            {
3095                    sizehints->flags = USPosition;
3096                    XSetWMNormalHints(g_display, wnd, sizehints);
3097                    XFree(sizehints);
3098            }
3099    
3100          /* Set WM_TRANSIENT_FOR, if necessary */          /* Set WM_TRANSIENT_FOR, if necessary */
3101          if (parent)          if ((parent != 0x00000000) && (parent != 0xFFFFFFFF))
3102          {          {
3103                  sw_parent = seamless_get_window_by_id(parent);                  sw_parent = seamless_get_window_by_id(parent);
3104                  if (sw_parent)                  if (sw_parent)
# Line 3053  ui_seamless_create_window(unsigned long Line 3107  ui_seamless_create_window(unsigned long
3107                          warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);                          warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);
3108          }          }
3109    
3110    
3111          /* FIXME: Support for Input Context:s */          /* FIXME: Support for Input Context:s */
3112    
3113          get_input_mask(&input_mask);          get_input_mask(&input_mask);
# Line 3060  ui_seamless_create_window(unsigned long Line 3115  ui_seamless_create_window(unsigned long
3115    
3116          XSelectInput(g_display, wnd, input_mask);          XSelectInput(g_display, wnd, input_mask);
3117    
         XMapWindow(g_display, wnd);  
   
3118          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a
3119             seamless window, we could try to close the window on the             seamless window, we could try to close the window on the
3120             serverside, instead of terminating rdesktop */             serverside, instead of terminating rdesktop */
# Line 3070  ui_seamless_create_window(unsigned long Line 3123  ui_seamless_create_window(unsigned long
3123          sw = malloc(sizeof(seamless_window));          sw = malloc(sizeof(seamless_window));
3124          sw->wnd = wnd;          sw->wnd = wnd;
3125          sw->id = id;          sw->id = id;
3126            sw->parent = parent;
3127          sw->xoffset = 0;          sw->xoffset = 0;
3128          sw->yoffset = 0;          sw->yoffset = 0;
3129          sw->width = 0;          sw->width = 0;
3130          sw->height = 0;          sw->height = 0;
3131            sw->state = SEAMLESSRDP_NOTYETMAPPED;
3132            sw->desktop = 0;
3133          sw->next = g_seamless_windows;          sw->next = g_seamless_windows;
3134          g_seamless_windows = sw;          g_seamless_windows = sw;
3135  }  }
# Line 3084  ui_seamless_destroy_window(unsigned long Line 3140  ui_seamless_destroy_window(unsigned long
3140  {  {
3141          seamless_window *sw;          seamless_window *sw;
3142    
3143            if (!g_seamless_active)
3144                    return;
3145    
3146          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3147          if (!sw)          if (!sw)
3148          {          {
# Line 3101  ui_seamless_move_window(unsigned long id Line 3160  ui_seamless_move_window(unsigned long id
3160  {  {
3161          seamless_window *sw;          seamless_window *sw;
3162    
3163            if (!g_seamless_active)
3164                    return;
3165    
3166          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3167          if (!sw)          if (!sw)
3168          {          {
# Line 3125  ui_seamless_move_window(unsigned long id Line 3187  ui_seamless_move_window(unsigned long id
3187    
3188          /* 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
3189             accept restoration */             accept restoration */
3190          if (sw->state != SEAMLESSRDP_NORMAL)          switch (sw->state)
3191                  return;          {
3192                    case SEAMLESSRDP_MINIMIZED:
3193                    case SEAMLESSRDP_MAXIMIZED:
3194                            return;
3195            }
3196    
3197          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */
3198          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 3138  ui_seamless_settitle(unsigned long id, c Line 3204  ui_seamless_settitle(unsigned long id, c
3204  {  {
3205          seamless_window *sw;          seamless_window *sw;
3206    
3207            if (!g_seamless_active)
3208                    return;
3209    
3210          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3211          if (!sw)          if (!sw)
3212          {          {
# Line 3145  ui_seamless_settitle(unsigned long id, c Line 3214  ui_seamless_settitle(unsigned long id, c
3214                  return;                  return;
3215          }          }
3216    
3217            /* FIXME: Might want to convert the name for non-EWMH WMs */
3218          XStoreName(g_display, sw->wnd, title);          XStoreName(g_display, sw->wnd, title);
3219            ewmh_set_wm_name(sw->wnd, title);
3220  }  }
3221    
3222    
# Line 3154  ui_seamless_setstate(unsigned long id, u Line 3225  ui_seamless_setstate(unsigned long id, u
3225  {  {
3226          seamless_window *sw;          seamless_window *sw;
3227    
3228            if (!g_seamless_active)
3229                    return;
3230    
3231          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3232          if (!sw)          if (!sw)
3233          {          {
# Line 3161  ui_seamless_setstate(unsigned long id, u Line 3235  ui_seamless_setstate(unsigned long id, u
3235                  return;                  return;
3236          }          }
3237    
         sw->state = state;  
   
3238          switch (state)          switch (state)
3239          {          {
3240                  case SEAMLESSRDP_NORMAL:                  case SEAMLESSRDP_NORMAL:
3241                  case SEAMLESSRDP_MAXIMIZED:                  case SEAMLESSRDP_MAXIMIZED:
3242                          ewmh_change_state(sw->wnd, state);                          ewmh_change_state(sw->wnd, state);
3243                            XMapWindow(g_display, sw->wnd);
3244                          break;                          break;
3245                  case SEAMLESSRDP_MINIMIZED:                  case SEAMLESSRDP_MINIMIZED:
3246                          /* 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 3175  ui_seamless_setstate(unsigned long id, u Line 3248  ui_seamless_setstate(unsigned long id, u
3248                             _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
3249                             such as minimization, rather than an independent state." Besides,                             such as minimization, rather than an independent state." Besides,
3250                             XIconifyWindow is easier. */                             XIconifyWindow is easier. */
3251                          XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));                          if (sw->state == SEAMLESSRDP_NOTYETMAPPED)
3252                            {
3253                                    XWMHints *hints;
3254                                    hints = XAllocWMHints();
3255                                    hints->flags = StateHint;
3256                                    hints->initial_state = IconicState;
3257                                    XSetWMHints(g_display, sw->wnd, hints);
3258                                    XFree(hints);
3259                                    XMapWindow(g_display, sw->wnd);
3260                            }
3261                            else
3262                                    XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));
3263                          break;                          break;
3264                  default:                  default:
3265                          warning("SeamlessRDP: Invalid state %d\n", state);                          warning("SeamlessRDP: Invalid state %d\n", state);
3266                          break;                          break;
3267          }          }
3268    
3269            /* Handle popups without parents through some ewm hints */
3270            if ((sw->state == SEAMLESSRDP_NOTYETMAPPED) && (sw->parent == 0xFFFFFFFF))
3271                    ewmh_set_window_popup(sw->wnd);
3272    
3273            sw->state = state;
3274    }
3275    
3276    
3277    void
3278    ui_seamless_syncbegin(unsigned long flags)
3279    {
3280            if (!g_seamless_active)
3281                    return;
3282    
3283            /* Destroy all seamless windows */
3284            while (g_seamless_windows)
3285            {
3286                    XDestroyWindow(g_display, g_seamless_windows->wnd);
3287                    seamless_remove_window(g_seamless_windows);
3288            }
3289  }  }

Legend:
Removed from v.1118  
changed lines
  Added in v.1149

  ViewVC Help
Powered by ViewVC 1.1.26