]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Internal branch sync. Included in this change:
authorVMware, Inc <>
Fri, 18 Sep 2009 21:47:02 +0000 (14:47 -0700)
committerMarcelo Vanzin <mvanzin@mvanzin-dev1.eng.vmware.com>
Sat, 19 Sep 2009 01:49:12 +0000 (18:49 -0700)
. Unity: Add {un,}stick window RPC handlers.

. Complain loudly if res set or topology set is called at wrong state.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/lib/file/filePosix.c
open-vm-tools/lib/hgfs/cpName.c
open-vm-tools/lib/include/vix.h
open-vm-tools/lib/unity/unity.c
open-vm-tools/lib/unity/unityPlatform.h
open-vm-tools/lib/unity/unityPlatformX11.c
open-vm-tools/lib/unity/unityPlatformX11Window.c
open-vm-tools/services/plugins/resolutionSet/resolutionSet.c

index c6d9f0a2532933a4897e779c462f98dabf8d2ea2..d5e96be45297ee081e0fe36ada978c6ff3087f8c 100644 (file)
@@ -76,7 +76,6 @@ static char *FilePosixLookupMountPoint(char const *canPath, Bool *bind);
 static char *FilePosixNearestExistingAncestor(char const *path);
 
 # ifdef VMX86_SERVER
-#define VMFS2CONST 456
 #define VMFS3CONST 256
 #include "hostType.h"
 /* Needed for VMFS implementation of File_GetFreeSpace() */
@@ -2068,9 +2067,6 @@ FilePosixCreateTestFileSize(ConstUnicode dirName, // IN: directory to create lar
  *
  *      Check if the given file is on a VMFS supports such a file size
  *
- *      In the case of VMFS2, the largest supported file size is
- *         456 * 1024 * B bytes
- *
  *      In the case of VMFS3/4, the largest supported file size is
  *         256 * 1024 * B bytes
  *
@@ -2112,14 +2108,12 @@ File_VMFSSupportsFileSize(ConstUnicode pathName,  // IN:
    }
 
    if (strcmp(fsType, "VMFS") == 0) {
-      if (version == 2) {
-         maxFileSize = (VMFS2CONST * (uint64) blockSize * 1024);
-      } else if (version >= 3) {
+      if (version >= 3) {
          /* Get ready for VMFS4 and perform sanity check on version */
          ASSERT(version == 3 || version == 4);
 
          maxFileSize = (VMFS3CONST * (uint64) blockSize * 1024);
-      } 
+      }
 
       if (fileSize <= maxFileSize && maxFileSize != -1) {
          free(fsType);
index dc92be0dc77c91886e386545b0b9e0d7f870a364..58da546ab7dcf228f9d3574aca5599fad9b94a54 100644 (file)
@@ -113,7 +113,7 @@ CPName_GetComponent(char const *begin,   // IN: Beginning of buffer
    len = walk - begin;
 
    *next = myNext;
-   return ((int) len);
+   return (int) len;
 }
 
 
index ec826a33467d48b87457b4f484de2768aed6bc3b..3027e7fd1a8d37eace7f74b2d4cf9963bb3271cd 100644 (file)
@@ -118,6 +118,7 @@ enum {
    VIX_E_LICENSE                                = 32,
    VIX_E_VM_HOST_DISCONNECTED                   = 34,
    VIX_E_AUTHENTICATION_FAIL                    = 35,
+   VIX_E_HOST_CONNECTION_LOST                   = 36,
 
    /* Handle Errors */
    VIX_E_INVALID_HANDLE                         = 1000,
index 832c7e4bc8fffdef5b027e33546da60ac507d37f..19190fed76ac39e09da6e6f349180fc4f075ab05 100644 (file)
@@ -170,6 +170,8 @@ static UnityCommandElem unityCommandTable[] = {
    { UNITY_RPC_WINDOW_UNMINIMIZE, UnityPlatformUnminimizeWindow },
    { UNITY_RPC_WINDOW_MAXIMIZE, UnityPlatformMaximizeWindow },
    { UNITY_RPC_WINDOW_UNMAXIMIZE, UnityPlatformUnmaximizeWindow },
+   { UNITY_RPC_WINDOW_STICK, UnityPlatformStickWindow },
+   { UNITY_RPC_WINDOW_UNSTICK, UnityPlatformUnstickWindow },
    /* Add more commands and handlers above this. */
    { NULL, NULL }
 };
@@ -380,6 +382,8 @@ Unity_InitBackdoor(struct RpcIn *rpcIn)   // IN
     */
 
    if (Unity_IsSupported()) {
+      UnityCommandElem *elem;
+
       RpcIn_RegisterCallback(rpcIn, UNITY_RPC_ENTER, UnityTcloEnter, NULL);
       RpcIn_RegisterCallback(rpcIn, UNITY_RPC_GET_UPDATE_FULL, UnityTcloGetUpdate, NULL);
       RpcIn_RegisterCallback(rpcIn, UNITY_RPC_GET_UPDATE_INCREMENTAL,
@@ -388,8 +392,6 @@ Unity_InitBackdoor(struct RpcIn *rpcIn)   // IN
                              UnityTcloGetWindowPath, NULL);
       RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_SETTOP,
                              UnityTcloSetTopWindowGroup, NULL);
-      RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_CLOSE,
-                             UnityTcloWindowCommand, NULL);
       RpcIn_RegisterCallback(rpcIn, UNITY_RPC_GET_WINDOW_CONTENTS,
                              UnityTcloGetWindowContents, NULL);
       RpcIn_RegisterCallback(rpcIn, UNITY_RPC_GET_ICON_DATA,
@@ -400,24 +402,20 @@ Unity_InitBackdoor(struct RpcIn *rpcIn)   // IN
       RpcIn_RegisterCallback(rpcIn, UNITY_RPC_EXIT, UnityTcloExit, NULL);
       RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_MOVE_RESIZE,
                              UnityTcloMoveResizeWindow, NULL);
-      RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_SHOW,
-                             UnityTcloWindowCommand, NULL);
-      RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_HIDE,
-                             UnityTcloWindowCommand, NULL);
-      RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_MINIMIZE,
-                             UnityTcloWindowCommand, NULL);
-      RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_UNMINIMIZE,
-                             UnityTcloWindowCommand, NULL);
-      RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_MAXIMIZE,
-                             UnityTcloWindowCommand, NULL);
-      RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_UNMAXIMIZE,
-                             UnityTcloWindowCommand, NULL);
       RpcIn_RegisterCallback(rpcIn, UNITY_RPC_DESKTOP_CONFIG_SET,
                              UnityTcloSetDesktopConfig, NULL);
       RpcIn_RegisterCallback(rpcIn, UNITY_RPC_DESKTOP_ACTIVE_SET,
                              UnityTcloSetDesktopActive, NULL);
       RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_DESKTOP_SET,
                              UnityTcloSetWindowDesktop, NULL);
+
+      /*
+       * Handle all of the UnityTcloWindowCommand RPCs at once.
+       */
+      for (elem = unityCommandTable; elem->name != NULL; elem++) {
+         RpcIn_RegisterCallback(rpcIn, elem->name, UnityTcloWindowCommand,
+                                NULL);
+      }
    }
 }
 
index 3647686a5edf5c56c041b9ed45225dcdb974d363..c3748d808922658b04f191e4af677c091d85baf9 100644 (file)
@@ -112,6 +112,10 @@ Bool UnityPlatformSetDesktopActive(UnityPlatform *up,
 Bool UnityPlatformSetWindowDesktop(UnityPlatform *up,
                                    UnityWindowId windowId,
                                    UnityDesktopId desktopId);
+Bool UnityPlatformStickWindow(UnityPlatform *up,
+                              UnityWindowId windowId);
+Bool UnityPlatformUnstickWindow(UnityPlatform *up,
+                                UnityWindowId windowId);
 Bool UnityPlatformIsUnityRunning(UnityPlatform *up);
 Bool UnityPlatformStartHelperThreads(UnityPlatform *up);
 void UnityPlatformKillHelperThreads(UnityPlatform *up);
index 31122b6f59c1d1fcbaff37170a72fec291a4e941..1a5f09439ab23a04f7567b7eb1226b7084f6f3eb 100644 (file)
@@ -83,11 +83,19 @@ static void UnityPlatformDnDSendClientMessage(UnityPlatform *up,
                                               int numItems,
                                               const void *data);
 
+static Bool GetRelevantWMWindow(UnityPlatform *up,
+                                UnityWindowId windowId,
+                                Window *wmWindow);
+static Bool SetWindowStickiness(UnityPlatform *up,
+                                UnityWindowId windowId,
+                                Bool wantSticky);
+
 static const GuestCapabilities platformUnityCaps[] = {
    UNITY_CAP_WORK_AREA,
    UNITY_CAP_START_MENU,
    UNITY_CAP_MULTI_MON,
-   UNITY_CAP_VIRTUAL_DESK
+   UNITY_CAP_VIRTUAL_DESK,
+   UNITY_CAP_STICKY_WINDOWS,
 };
 
 /*
@@ -964,7 +972,14 @@ UnityPlatformStartHelperThreads(UnityPlatform *up) // IN
     */
    {
       GIOChannel *unityDisplayChannel;
+
       unityDisplayChannel = g_io_channel_unix_new(ConnectionNumber(up->display));
+      if (g_io_channel_set_encoding(unityDisplayChannel, NULL, NULL) !=
+          G_IO_STATUS_NORMAL) {
+         Warning("%s: Unable to switch Unity I/O channel from UTF-8 to raw data.\n",
+                 __func__);
+      }
+
       up->unityDisplayWatchID = g_io_add_watch(unityDisplayChannel,
                                                G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
                                                UnityPlatformHandleEventsGlib,
@@ -2991,3 +3006,152 @@ Unity_LocalToUnityPoint(UnityPoint *unityPt, // IN/OUT
    unityPt->y = localPt->y;
 }
 
+
+/*
+ ******************************************************************************
+ * UnityPlatformStickWindow --                                           */ /**
+ *
+ * @brief "Stick" a window to the desktop.
+ *
+ * @param[in] up       Platform context.
+ * @param[in] windowId Operand window.
+ *
+ * @retval TRUE  Success.
+ * @retval FALSE Failure.
+ *
+ ******************************************************************************
+ */
+
+Bool
+UnityPlatformStickWindow(UnityPlatform *up,      // IN
+                         UnityWindowId windowId) // IN
+{
+   return SetWindowStickiness(up, windowId, TRUE);
+}
+
+
+/*
+ ******************************************************************************
+ * UnityPlatformUnstickWindow --                                         */ /**
+ *
+ * @brief "Unstick" a window from the desktop.
+ *
+ * @param[in] up       Platform context.
+ * @param[in] windowId Operand window.
+ *
+ * @retval TRUE  Success.
+ * @retval FALSE Failure.
+ *
+ ******************************************************************************
+ */
+
+Bool
+UnityPlatformUnstickWindow(UnityPlatform *up,      // IN
+                           UnityWindowId windowId) // IN
+{
+   return SetWindowStickiness(up, windowId, FALSE);
+}
+
+
+/*
+ ******************************************************************************
+ * Begin file-scope functions.
+ *
+ */
+
+
+/*
+ ******************************************************************************
+ * GetRelevantWMWindow --                                                */ /**
+ *
+ * @brief Given a UnityWindowId, return the X11 window relevant to WM operations.
+ *
+ * Starting with a Unity window, look for and return its associated
+ * clientWindow.  If there is no clientWindow, then return the top-level window.
+ *
+ * @param[in]  up        Unity/X11 context.
+ * @param[in]  windowId  Window search for.
+ * @param[out] wmWindow  Set to the relevant X11 window.
+ *
+ * @todo Consider exporting this for use in unityPlatformX11Window.c.
+ *
+ * @retval TRUE  Relevant window found and recorded in @a wmWindow.
+ * @retval FALSE Unable to find @a windowId.
+ *
+ ******************************************************************************
+ */
+
+static Bool
+GetRelevantWMWindow(UnityPlatform *up,          // IN
+                    UnityWindowId windowId,     // IN
+                    Window *wmWindow)           // OUT
+{
+   UnityPlatformWindow *upw;
+
+   ASSERT(up);
+
+   upw = UPWindow_Lookup(up, windowId);
+   if (!upw) {
+      return FALSE;
+   }
+
+   *wmWindow = upw->clientWindow ? upw->clientWindow : upw->toplevelWindow;
+   return TRUE;
+}
+
+
+/*
+ ******************************************************************************
+ * SetWindowStickiness --                                                */ /**
+ *
+ * @brief Sets or clears a window's sticky state.
+ *
+ * @param[in] up         Unity/X11 context.
+ * @param[in] windowId   Operand window.
+ * @param[in] wantSticky Set to TRUE to stick a window, FALSE to unstick it.
+ *
+ * @retval TRUE  Request successfully sent to X server.
+ * @retval FALSE Request failed.
+ *
+ ******************************************************************************
+ */
+
+static Bool
+SetWindowStickiness(UnityPlatform *up,          // IN
+                    UnityWindowId windowId,     // IN
+                    Bool wantSticky)            // IN
+{
+   GdkWindow *gdkWindow;
+   Window curWindow;
+
+   ASSERT(up);
+
+   if (!GetRelevantWMWindow(up, windowId, &curWindow)) {
+      Debug("%s: Lookup against window %#x failed.\n", __func__, windowId);
+      return FALSE;
+   }
+
+   gdkWindow = gdk_window_foreign_new(curWindow);
+   if (gdkWindow == NULL) {
+      Debug("%s: Unable to create Gdk window?! (%#x)\n", __func__, windowId);
+      return FALSE;
+   }
+
+   if (wantSticky) {
+      gdk_window_stick(gdkWindow);
+   } else {
+      gdk_window_unstick(gdkWindow);
+   }
+
+   gdk_flush();
+   g_object_unref(G_OBJECT(gdkWindow));
+
+   return TRUE;
+}
+
+
+/*
+ *
+ * End file-scope functions.
+ ******************************************************************************
+ */
index 6df32732054fffc516d3ce51bd96aa74793bee26..b6184790d9177ebcc61cbe076bd8645b43916992 100644 (file)
@@ -2388,12 +2388,23 @@ UnityPlatformUnminimizeWindow(UnityPlatform *up,    // IN
       upw->wantInputFocus = TRUE;
 
       /*
-       * Unfortunately the _NET_WM_STATE messages only work for windows that are already
-       * mapped, i.e. not iconified or withdrawn.
+       * Okay, client messages to update _NET_WM_STATE are intended only for
+       * /mapped/ windows.  (That's my interpretation considering that wm-spec
+       * only mentions mapped windows, and window managers seem to ignore the
+       * request for minimized windows.)
+       *
+       * Rather than directly mapping the window, we'll instead request that
+       * the window manager activate it.  Mapping the window has a negative
+       * consequence of stripping the window of its _NET_WM_STATE and
+       * _NET_WM_DESKTOP properties.  This is most visible when unminimizing
+       * a sticky window -- the result is that it would lose its stickiness.
        */
-      if (!upw->isHidden) {
-         XMapRaised(up->display, upw->clientWindow);
-      }
+
+      data[0] = 2;
+      data[1] = UnityPlatformGetServerTime(up);
+      data[2] = 0;
+      UnityPlatformSendClientMessage(up, upw->rootWindow, upw->clientWindow,
+                                     up->atoms._NET_ACTIVE_WINDOW, 32, 4, data);
 
       data[0] = _NET_WM_STATE_REMOVE;
       data[1] = up->atoms._NET_WM_STATE_HIDDEN;
index 6c682500ccdd0370a39ca1e58dc767093a17d377..a95dcef80dacc5303e5bebf1b19a4c6af16f382c 100644 (file)
@@ -151,6 +151,20 @@ ResolutionResolutionSetCB(RpcInData *data)
    unsigned int index = 0;
    Bool retval = FALSE;
 
+   ResolutionInfoType *resInfo = &resolutionInfo;
+
+   if (!resInfo->initialized) {
+      Debug("%s: FAIL! Request for resolution set but plugin is not initialized\n",
+            __FUNCTION__);
+      return RPCIN_SETRETVALS(data, "Invalid guest state: resolution set not initialized", FALSE);
+   }
+
+   if (!resInfo->canSetResolution) {
+      Debug("%s: FAIL! Request for resolution set but res set is not enabled\n",
+            __FUNCTION__);
+      return RPCIN_SETRETVALS(data, "Invalid guest state: resolution set not enabled", FALSE);
+   }
+
    /* parse the width and height */
    if (!StrUtil_GetNextUintToken(&width, &index, data->args, " ")) {
       goto invalid_arguments;
@@ -271,6 +285,22 @@ ResolutionDisplayTopologySetCB(RpcInData *data)
    Bool success = FALSE;
    const char *p;
 
+   ResolutionInfoType *resInfo = &resolutionInfo;
+
+   if (!resInfo->initialized) {
+      Debug("%s: FAIL! Request for topology set but plugin is not initialized\n",
+            __FUNCTION__);
+      RPCIN_SETRETVALS(data, "Invalid guest state: topology set not initialized", FALSE);
+      goto out;
+   }
+
+   if (!resInfo->canSetTopology) {
+      Debug("%s: FAIL! Request for topology set but topology set not enabled\n",
+            __FUNCTION__);
+      RPCIN_SETRETVALS(data, "Invalid guest state: topology set not enabled", FALSE);
+      goto out;
+   }
+
    /*
     * The argument string will look something like:
     *   <count> [ , <x> <y> <w> <h> ] * count.