From: VMware, Inc <> Date: Fri, 18 Sep 2009 21:47:02 +0000 (-0700) Subject: Internal branch sync. Included in this change: X-Git-Tag: 2009.09.18-193784~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2e52b19490a3d5efdbb85d5c8f14d2d76841da7f;p=thirdparty%2Fopen-vm-tools.git Internal branch sync. Included in this change: . 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 --- diff --git a/open-vm-tools/lib/file/filePosix.c b/open-vm-tools/lib/file/filePosix.c index c6d9f0a25..d5e96be45 100644 --- a/open-vm-tools/lib/file/filePosix.c +++ b/open-vm-tools/lib/file/filePosix.c @@ -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); diff --git a/open-vm-tools/lib/hgfs/cpName.c b/open-vm-tools/lib/hgfs/cpName.c index dc92be0dc..58da546ab 100644 --- a/open-vm-tools/lib/hgfs/cpName.c +++ b/open-vm-tools/lib/hgfs/cpName.c @@ -113,7 +113,7 @@ CPName_GetComponent(char const *begin, // IN: Beginning of buffer len = walk - begin; *next = myNext; - return ((int) len); + return (int) len; } diff --git a/open-vm-tools/lib/include/vix.h b/open-vm-tools/lib/include/vix.h index ec826a334..3027e7fd1 100644 --- a/open-vm-tools/lib/include/vix.h +++ b/open-vm-tools/lib/include/vix.h @@ -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, diff --git a/open-vm-tools/lib/unity/unity.c b/open-vm-tools/lib/unity/unity.c index 832c7e4bc..19190fed7 100644 --- a/open-vm-tools/lib/unity/unity.c +++ b/open-vm-tools/lib/unity/unity.c @@ -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); + } } } diff --git a/open-vm-tools/lib/unity/unityPlatform.h b/open-vm-tools/lib/unity/unityPlatform.h index 3647686a5..c3748d808 100644 --- a/open-vm-tools/lib/unity/unityPlatform.h +++ b/open-vm-tools/lib/unity/unityPlatform.h @@ -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); diff --git a/open-vm-tools/lib/unity/unityPlatformX11.c b/open-vm-tools/lib/unity/unityPlatformX11.c index 31122b6f5..1a5f09439 100644 --- a/open-vm-tools/lib/unity/unityPlatformX11.c +++ b/open-vm-tools/lib/unity/unityPlatformX11.c @@ -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. + ****************************************************************************** + */ diff --git a/open-vm-tools/lib/unity/unityPlatformX11Window.c b/open-vm-tools/lib/unity/unityPlatformX11Window.c index 6df327320..b6184790d 100644 --- a/open-vm-tools/lib/unity/unityPlatformX11Window.c +++ b/open-vm-tools/lib/unity/unityPlatformX11Window.c @@ -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; diff --git a/open-vm-tools/services/plugins/resolutionSet/resolutionSet.c b/open-vm-tools/services/plugins/resolutionSet/resolutionSet.c index 6c682500c..a95dcef80 100644 --- a/open-vm-tools/services/plugins/resolutionSet/resolutionSet.c +++ b/open-vm-tools/services/plugins/resolutionSet/resolutionSet.c @@ -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.