|
|
ceabfb |
--- open-vm-tools-10.1.10-6082533/services/plugins/resolutionKMS/resolutionKMS.c 2017-09-27 18:16:07.428992005 -0700
|
|
|
ceabfb |
+++ open-vm-tools-10.1.10-modified/services/plugins/resolutionKMS/resolutionKMS.c 2017-09-27 16:38:40.000000000 -0700
|
|
|
ceabfb |
@@ -1,5 +1,5 @@
|
|
|
ceabfb |
/*********************************************************
|
|
|
ceabfb |
- * Copyright (C) 2008-2016 VMware, Inc. All rights reserved.
|
|
|
ceabfb |
+ * Copyright (C) 2008-2017 VMware, Inc. All rights reserved.
|
|
|
ceabfb |
*
|
|
|
ceabfb |
* This program is free software; you can redistribute it and/or modify it
|
|
|
ceabfb |
* under the terms of the GNU Lesser General Public License as published
|
|
|
ceabfb |
@@ -279,6 +279,34 @@
|
|
|
ceabfb |
g_warning("%s: Unable to set tools.capability.resolution_server\n",
|
|
|
ceabfb |
__FUNCTION__);
|
|
|
ceabfb |
}
|
|
|
ceabfb |
+
|
|
|
ceabfb |
+ if (value == 1) {
|
|
|
ceabfb |
+ /*
|
|
|
ceabfb |
+ * Whenever resolutionKMS is enabled, send
|
|
|
ceabfb |
+ * "tools.capability.resolution_server toolbox-dnd 0" to clear
|
|
|
ceabfb |
+ * resolutionSet as resolution server.
|
|
|
ceabfb |
+ *
|
|
|
ceabfb |
+ * Note: The below rpc is sent to TOOLS_DND_NAME if rpcChannelName is
|
|
|
ceabfb |
+ * TOOLS_DAEMON_NAME and vice versa (to clear the opposite channel).
|
|
|
ceabfb |
+ * This is how rpcChannelName is selected in ToolsOnLoad():
|
|
|
ceabfb |
+ *
|
|
|
ceabfb |
+ * if (strcmp(ctx->name, VMTOOLS_GUEST_SERVICE) == 0) {
|
|
|
ceabfb |
+ * rpcChannelName = TOOLS_DAEMON_NAME;
|
|
|
ceabfb |
+ * } else if (strcmp(ctx->name, VMTOOLS_USER_SERVICE) == 0) {
|
|
|
ceabfb |
+ * rpcChannelName = TOOLS_DND_NAME;
|
|
|
ceabfb |
+ * }
|
|
|
ceabfb |
+ */
|
|
|
ceabfb |
+ gchar *msgClear;
|
|
|
ceabfb |
+ msgClear = g_strdup_printf("tools.capability.resolution_server %s 0",
|
|
|
ceabfb |
+ (strcmp(rpcChannelName, TOOLS_DAEMON_NAME) == 0 ?
|
|
|
ceabfb |
+ TOOLS_DND_NAME : TOOLS_DAEMON_NAME));
|
|
|
ceabfb |
+ if (!RpcChannel_Send(chan, msgClear, strlen(msgClear), NULL, NULL)) {
|
|
|
ceabfb |
+ g_warning("%s: Unable to clear tools.capability.resolution_server\n",
|
|
|
ceabfb |
+ __FUNCTION__);
|
|
|
ceabfb |
+ }
|
|
|
ceabfb |
+ g_free(msgClear);
|
|
|
ceabfb |
+ }
|
|
|
ceabfb |
+
|
|
|
ceabfb |
g_free(msg);
|
|
|
ceabfb |
}
|
|
|
ceabfb |
|
|
|
ceabfb |
@@ -448,7 +476,7 @@
|
|
|
ceabfb |
|
|
|
ceabfb |
/*
|
|
|
ceabfb |
* Save the RPC channel name from the ToolsAppCtx so that we can use it later
|
|
|
ceabfb |
- * in calls to ResolutionSetServerCapability().
|
|
|
ceabfb |
+ * in calls to ResolutionKMSServerCapability().
|
|
|
ceabfb |
*/
|
|
|
ceabfb |
|
|
|
ceabfb |
if (strcmp(ctx->name, VMTOOLS_GUEST_SERVICE) == 0) {
|
|
|
ceabfb |
--- open-vm-tools-10.1.10-6082533/services/plugins/resolutionSet/resolutionCommon.c 2017-09-27 18:16:07.429992005 -0700
|
|
|
ceabfb |
+++ open-vm-tools-10.1.10-modified/services/plugins/resolutionSet/resolutionCommon.c 2017-09-27 16:38:40.000000000 -0700
|
|
|
ceabfb |
@@ -1,5 +1,5 @@
|
|
|
ceabfb |
/*********************************************************
|
|
|
ceabfb |
- * Copyright (C) 2016 VMware, Inc. All rights reserved.
|
|
|
ceabfb |
+ * Copyright (C) 2016-2017 VMware, Inc. All rights reserved.
|
|
|
ceabfb |
*
|
|
|
ceabfb |
* This program is free software; you can redistribute it and/or modify it
|
|
|
ceabfb |
* under the terms of the GNU Lesser General Public License as published
|
|
|
ceabfb |
@@ -38,6 +38,7 @@
|
|
|
ceabfb |
/* The DRM device we are looking for */
|
|
|
ceabfb |
#define RESOLUTION_VENDOR "0x15ad"
|
|
|
ceabfb |
#define RESOLUTION_DEVICE "0x0405"
|
|
|
ceabfb |
+#define RESOLUTION_KERNELNAME "vmwgfx"
|
|
|
ceabfb |
|
|
|
ceabfb |
/* Required DRM version for resolutionKMS */
|
|
|
ceabfb |
#define RESOLUTION_DRM_MAJOR 2
|
|
|
ceabfb |
@@ -84,11 +85,19 @@
|
|
|
ceabfb |
struct udev_list_entry *devices, *devListEntry;
|
|
|
ceabfb |
struct udev_device *dev;
|
|
|
ceabfb |
int fd = -1;
|
|
|
ceabfb |
+ int drmFd;
|
|
|
ceabfb |
const char *devNode = NULL;
|
|
|
ceabfb |
|
|
|
ceabfb |
+ /* Force load the kernel module. */
|
|
|
ceabfb |
+ drmFd = drmOpen(RESOLUTION_KERNELNAME, NULL);
|
|
|
ceabfb |
+ if (drmFd >= 0) {
|
|
|
ceabfb |
+ (void) drmDropMaster(drmFd);
|
|
|
ceabfb |
+ }
|
|
|
ceabfb |
+
|
|
|
ceabfb |
udev = udev_new();
|
|
|
ceabfb |
- if (!udev)
|
|
|
ceabfb |
- return -1;
|
|
|
ceabfb |
+ if (!udev) {
|
|
|
ceabfb |
+ goto outNoUdev;
|
|
|
ceabfb |
+ }
|
|
|
ceabfb |
|
|
|
ceabfb |
/*
|
|
|
ceabfb |
* Udev error return codes that are not caught immediately are
|
|
|
ceabfb |
@@ -148,6 +157,10 @@
|
|
|
ceabfb |
udev_enumerate_unref(enumerate);
|
|
|
ceabfb |
udev_unref(udev);
|
|
|
ceabfb |
|
|
|
ceabfb |
+ if (drmFd >= 0) {
|
|
|
ceabfb |
+ drmClose(drmFd);
|
|
|
ceabfb |
+ }
|
|
|
ceabfb |
+
|
|
|
ceabfb |
return fd;
|
|
|
ceabfb |
|
|
|
ceabfb |
outFound:
|
|
|
ceabfb |
@@ -155,6 +168,10 @@
|
|
|
ceabfb |
outErr:
|
|
|
ceabfb |
udev_enumerate_unref(enumerate);
|
|
|
ceabfb |
udev_unref(udev);
|
|
|
ceabfb |
+ outNoUdev:
|
|
|
ceabfb |
+ if (drmFd >= 0) {
|
|
|
ceabfb |
+ drmClose(drmFd);
|
|
|
ceabfb |
+ }
|
|
|
ceabfb |
|
|
|
ceabfb |
return -1;
|
|
|
ceabfb |
}
|
|
|
ceabfb |
@@ -190,7 +207,7 @@
|
|
|
ceabfb |
}
|
|
|
ceabfb |
|
|
|
ceabfb |
if (ver->version_major != RESOLUTION_DRM_MAJOR ||
|
|
|
ceabfb |
- ver->version_minor < RESOLUTION_DRM_MINOR) {
|
|
|
ceabfb |
+ ver->version_minor < RESOLUTION_DRM_MINOR) {
|
|
|
ceabfb |
g_debug("%s: Insufficient DRM version %d.%d for resolutionKMS.\n",
|
|
|
ceabfb |
__func__, ver->version_major, ver->version_minor);
|
|
|
ceabfb |
drmFreeVersion(ver);
|
|
|
ceabfb |
--- open-vm-tools-10.1.10-6082533/services/plugins/resolutionSet/resolutionDL.c 2017-09-27 18:16:07.429992005 -0700
|
|
|
ceabfb |
+++ open-vm-tools-10.1.10-modified/services/plugins/resolutionSet/resolutionDL.c 2017-09-27 16:38:40.000000000 -0700
|
|
|
ceabfb |
@@ -66,6 +66,8 @@
|
|
|
ceabfb |
};
|
|
|
ceabfb |
|
|
|
ceabfb |
static struct FuncToResolv drm2Table[] = {
|
|
|
ceabfb |
+ LIBDRM_RESOLV(Open),
|
|
|
ceabfb |
+ LIBDRM_RESOLV(Close),
|
|
|
ceabfb |
LIBDRM_RESOLV(GetVersion),
|
|
|
ceabfb |
LIBDRM_RESOLV(FreeVersion),
|
|
|
ceabfb |
LIBDRM_RESOLV(DropMaster),
|
|
|
ceabfb |
--- open-vm-tools-10.1.10-6082533/services/plugins/resolutionSet/resolutionDL.h 2017-09-27 18:16:07.429992005 -0700
|
|
|
ceabfb |
+++ open-vm-tools-10.1.10-modified/services/plugins/resolutionSet/resolutionDL.h 2017-09-27 16:38:40.000000000 -0700
|
|
|
ceabfb |
@@ -144,6 +144,8 @@
|
|
|
ceabfb |
* However this struct is not subject to the license header of this file.
|
|
|
ceabfb |
*/
|
|
|
ceabfb |
struct Drm2Interface {
|
|
|
ceabfb |
+ int (*Open)(const char *, const char *);
|
|
|
ceabfb |
+ int (*Close)(int);
|
|
|
ceabfb |
drmVersionPtr (*GetVersion)(int fd);
|
|
|
ceabfb |
void (*FreeVersion)(drmVersionPtr);
|
|
|
ceabfb |
int (*DropMaster)(int fd);
|
|
|
ceabfb |
@@ -190,6 +192,10 @@
|
|
|
ceabfb |
#define udev_list_entry_foreach(_a, _b)\
|
|
|
ceabfb |
udevi_list_entry_foreach(udevi, _a, _b)
|
|
|
ceabfb |
|
|
|
ceabfb |
+#define drmOpen \
|
|
|
ceabfb |
+ drmi->Open
|
|
|
ceabfb |
+#define drmClose \
|
|
|
ceabfb |
+ drmi->Close
|
|
|
ceabfb |
#define drmGetVersion \
|
|
|
ceabfb |
drmi->GetVersion
|
|
|
ceabfb |
#define drmFreeVersion \
|
|
|
ceabfb |
--- open-vm-tools-10.1.10-6082533/services/plugins/resolutionSet/resolutionSet.c 2017-09-27 18:16:07.429992005 -0700
|
|
|
ceabfb |
+++ open-vm-tools-10.1.10-modified/services/plugins/resolutionSet/resolutionSet.c 2017-09-27 16:38:40.000000000 -0700
|
|
|
ceabfb |
@@ -76,8 +76,7 @@
|
|
|
ceabfb |
*
|
|
|
ceabfb |
* Initialize the guest resolution library.
|
|
|
ceabfb |
*
|
|
|
ceabfb |
- * @param[in] handle Back-end specific handle, if needed. E.g., in the X11
|
|
|
ceabfb |
- case, this refers to the X11 display handle.
|
|
|
ceabfb |
+ * @param[in] handle Back-end specific handle, if needed.
|
|
|
ceabfb |
* @return TRUE on success, FALSE on failure
|
|
|
ceabfb |
*/
|
|
|
ceabfb |
|
|
|
ceabfb |
--- open-vm-tools-10.1.10-6082533/services/plugins/resolutionSet/resolutionX11.c 2017-09-27 18:16:07.429992005 -0700
|
|
|
ceabfb |
+++ open-vm-tools-10.1.10-modified/services/plugins/resolutionSet/resolutionX11.c 2017-09-27 16:38:40.000000000 -0700
|
|
|
ceabfb |
@@ -35,8 +35,6 @@
|
|
|
ceabfb |
#ifndef NO_MULTIMON
|
|
|
ceabfb |
#include <X11/extensions/Xinerama.h>
|
|
|
ceabfb |
#endif
|
|
|
ceabfb |
-#include <gtk/gtk.h>
|
|
|
ceabfb |
-#include <gdk/gdkx.h>
|
|
|
ceabfb |
|
|
|
ceabfb |
#include "vmware.h"
|
|
|
ceabfb |
#include "debug.h"
|
|
|
ceabfb |
@@ -62,6 +60,8 @@
|
|
|
ceabfb |
Bool canUseVMwareCtrlTopologySet;
|
|
|
ceabfb |
// TRUE if VMwareCtrl extension supports topology set
|
|
|
ceabfb |
Bool canUseRandR12; // TRUE if RandR extension >= 1.2 available
|
|
|
ceabfb |
+
|
|
|
ceabfb |
+ Bool canUseResolutionKMS; // TRUE if backing off for resolutionKMS
|
|
|
ceabfb |
} ResolutionInfoX11Type;
|
|
|
ceabfb |
|
|
|
ceabfb |
|
|
|
ceabfb |
@@ -78,6 +78,7 @@
|
|
|
ceabfb |
static Bool ResolutionCanSet(void);
|
|
|
ceabfb |
static Bool TopologyCanSet(void);
|
|
|
ceabfb |
static Bool SelectResolution(uint32 width, uint32 height);
|
|
|
ceabfb |
+static int ResolutionX11ErrorHandler(Display *d, XErrorEvent *e);
|
|
|
ceabfb |
|
|
|
ceabfb |
|
|
|
ceabfb |
/*
|
|
|
ceabfb |
@@ -89,29 +90,45 @@
|
|
|
ceabfb |
* X11 back-end initializer. Records caller's X11 display, then determines
|
|
|
ceabfb |
* which capabilities are available.
|
|
|
ceabfb |
*
|
|
|
ceabfb |
- * @param[in] handle User's X11 display
|
|
|
ceabfb |
+ * @param[in] handle (ResolutionInfoX11Type is used as backend specific handle)
|
|
|
ceabfb |
* @return TRUE on success, FALSE on failure.
|
|
|
ceabfb |
*/
|
|
|
ceabfb |
|
|
|
ceabfb |
Bool
|
|
|
ceabfb |
ResolutionBackendInit(InitHandle handle)
|
|
|
ceabfb |
{
|
|
|
ceabfb |
- ResolutionInfoX11Type *resInfoX = &resolutionInfoX11;
|
|
|
ceabfb |
+ ResolutionInfoX11Type *resInfoX = (ResolutionInfoX11Type *)handle;
|
|
|
ceabfb |
ResolutionInfoType *resInfo = &resolutionInfo;
|
|
|
ceabfb |
int dummy1;
|
|
|
ceabfb |
int dummy2;
|
|
|
ceabfb |
|
|
|
ceabfb |
- memset(resInfoX, 0, sizeof *resInfoX);
|
|
|
ceabfb |
+ if (resInfoX->canUseResolutionKMS == TRUE) {
|
|
|
ceabfb |
+ resInfo->canSetResolution = FALSE;
|
|
|
ceabfb |
+ resInfo->canSetTopology = FALSE;
|
|
|
ceabfb |
+ return FALSE;
|
|
|
ceabfb |
+ }
|
|
|
ceabfb |
|
|
|
ceabfb |
- resInfoX->display = handle;
|
|
|
ceabfb |
+ XSetErrorHandler(ResolutionX11ErrorHandler);
|
|
|
ceabfb |
+ resInfoX->display = XOpenDisplay(NULL);
|
|
|
ceabfb |
|
|
|
ceabfb |
+ /*
|
|
|
ceabfb |
+ * In case display is NULL, we do not load resolutionSet
|
|
|
ceabfb |
+ * as it serve no purpose. Also avoids SEGFAULT issue
|
|
|
ceabfb |
+ * like BZ1880932.
|
|
|
ceabfb |
+ *
|
|
|
ceabfb |
+ * VMX currently remembers the settings across a reboot,
|
|
|
ceabfb |
+ * so let's say someone replaces our Xorg driver with
|
|
|
ceabfb |
+ * xf86-video-modesetting, and then rebooted, we'd end up here,
|
|
|
ceabfb |
+ * but the VMX would still send resolution / topology events
|
|
|
ceabfb |
+ * and we'd hit the same segfault.
|
|
|
ceabfb |
+ */
|
|
|
ceabfb |
if (resInfoX->display == NULL) {
|
|
|
ceabfb |
+ g_error("%s: Invalid display detected.\n", __func__);
|
|
|
ceabfb |
resInfo->canSetResolution = FALSE;
|
|
|
ceabfb |
resInfo->canSetTopology = FALSE;
|
|
|
ceabfb |
- return TRUE;
|
|
|
ceabfb |
+ return FALSE;
|
|
|
ceabfb |
}
|
|
|
ceabfb |
|
|
|
ceabfb |
- resInfoX->display = handle;
|
|
|
ceabfb |
resInfoX->rootWindow = DefaultRootWindow(resInfoX->display);
|
|
|
ceabfb |
resInfoX->canUseVMwareCtrl = VMwareCtrl_QueryVersion(resInfoX->display, &dummy1,
|
|
|
ceabfb |
&dummy2);
|
|
|
ceabfb |
@@ -132,6 +149,10 @@
|
|
|
ceabfb |
void
|
|
|
ceabfb |
ResolutionBackendCleanup(void)
|
|
|
ceabfb |
{
|
|
|
ceabfb |
+ ResolutionInfoX11Type *resInfoX = &resolutionInfoX11;
|
|
|
ceabfb |
+ if (resInfoX->display) {
|
|
|
ceabfb |
+ XCloseDisplay(resInfoX->display);
|
|
|
ceabfb |
+ }
|
|
|
ceabfb |
return;
|
|
|
ceabfb |
}
|
|
|
ceabfb |
|
|
|
ceabfb |
@@ -524,7 +545,7 @@
|
|
|
ceabfb |
g_debug("Setting guest resolution to: %dx%d (requested: %d, %d)\n",
|
|
|
ceabfb |
xrrSizes[bestFitIndex].width, xrrSizes[bestFitIndex].height, width, height);
|
|
|
ceabfb |
rc = XRRSetScreenConfig(resInfoX->display, xrrConfig, resInfoX->rootWindow,
|
|
|
ceabfb |
- bestFitIndex, xrrCurRotation, GDK_CURRENT_TIME);
|
|
|
ceabfb |
+ bestFitIndex, xrrCurRotation, CurrentTime);
|
|
|
ceabfb |
g_debug("XRRSetScreenConfig returned %d (result: %dx%d)\n", rc,
|
|
|
ceabfb |
xrrSizes[bestFitIndex].width, xrrSizes[bestFitIndex].height);
|
|
|
ceabfb |
} else {
|
|
|
ceabfb |
@@ -574,42 +595,28 @@
|
|
|
ceabfb |
|
|
|
ceabfb |
|
|
|
ceabfb |
/**
|
|
|
ceabfb |
- * Obtain a "handle", which for X11, is a display pointer.
|
|
|
ceabfb |
+ * Obtain a "handle".
|
|
|
ceabfb |
*
|
|
|
ceabfb |
* @note We will have to move this out of the resolution plugin soon, I am
|
|
|
ceabfb |
- * just landing this here now for convenience as I port resolution set over
|
|
|
ceabfb |
+ * just landing this here now for convenience as I port resolution set over
|
|
|
ceabfb |
* to the new service architecture.
|
|
|
ceabfb |
*
|
|
|
ceabfb |
- * @return X server display
|
|
|
ceabfb |
+ * @return ResolutionInfoX11Type as backend specific handle
|
|
|
ceabfb |
*/
|
|
|
ceabfb |
|
|
|
ceabfb |
InitHandle
|
|
|
ceabfb |
ResolutionToolkitInit(ToolsAppCtx *ctx) // IN: For config database access
|
|
|
ceabfb |
{
|
|
|
ceabfb |
- int argc = 1;
|
|
|
ceabfb |
- char *argv[] = {"", NULL};
|
|
|
ceabfb |
- GtkWidget *wnd;
|
|
|
ceabfb |
- Display *display;
|
|
|
ceabfb |
+ ResolutionInfoX11Type *resInfoX = &resolutionInfoX11;
|
|
|
ceabfb |
int fd;
|
|
|
ceabfb |
|
|
|
ceabfb |
+ memset(resInfoX, 0, sizeof *resInfoX);
|
|
|
ceabfb |
+
|
|
|
ceabfb |
fd = resolutionCheckForKMS(ctx);
|
|
|
ceabfb |
if (fd >= 0) {
|
|
|
ceabfb |
resolutionDRMClose(fd);
|
|
|
ceabfb |
g_message("%s: Backing off for resolutionKMS.\n", __func__);
|
|
|
ceabfb |
- return (InitHandle) 0;
|
|
|
ceabfb |
+ resInfoX->canUseResolutionKMS = TRUE;
|
|
|
ceabfb |
}
|
|
|
ceabfb |
-
|
|
|
ceabfb |
- XSetErrorHandler(ResolutionX11ErrorHandler);
|
|
|
ceabfb |
- gtk_init(&argc, (char ***) &argv);
|
|
|
ceabfb |
- wnd = gtk_invisible_new();
|
|
|
ceabfb |
-#ifndef GTK3
|
|
|
ceabfb |
- display = GDK_WINDOW_XDISPLAY(wnd->window);
|
|
|
ceabfb |
-#else
|
|
|
ceabfb |
- display = GDK_WINDOW_XDISPLAY(gtk_widget_get_window(wnd));
|
|
|
ceabfb |
-#endif
|
|
|
ceabfb |
-
|
|
|
ceabfb |
- if (!display)
|
|
|
ceabfb |
- g_error("%s: Invalid display detected.\n", __func__);
|
|
|
ceabfb |
-
|
|
|
ceabfb |
- return (InitHandle) display;
|
|
|
ceabfb |
+ return (InitHandle) resInfoX;
|
|
|
ceabfb |
}
|
|
|
ceabfb |
--- open-vm-tools-10.1.10-6082533/services/plugins/resolutionSet/resolutionRandR12.c 2017-07-28 15:19:20.000000000 -0700
|
|
|
ceabfb |
+++ open-vm-tools-10.1.10-modified/services/plugins/resolutionSet/resolutionRandR12.c 2017-09-27 16:38:40.000000000 -0700
|
|
|
ceabfb |
@@ -139,7 +139,7 @@
|
|
|
ceabfb |
#define LOG_STOP fclose(_ofile)
|
|
|
ceabfb |
#else
|
|
|
ceabfb |
#define LOG_START
|
|
|
ceabfb |
-#include <gtk/gtk.h>
|
|
|
ceabfb |
+#include <glib.h>
|
|
|
ceabfb |
#define LOG_STOP
|
|
|
ceabfb |
#endif
|
|
|
ceabfb |
|
|
|
ceabfb |
@@ -1000,7 +1000,7 @@
|
|
|
ceabfb |
info = RandR12GetInfo(dpy, rootWin);
|
|
|
ceabfb |
if (!info) {
|
|
|
ceabfb |
g_warning("%s: Setup info struct failed.\n", __func__);
|
|
|
ceabfb |
- goto out_ungrab;
|
|
|
ceabfb |
+ return FALSE;
|
|
|
ceabfb |
}
|
|
|
ceabfb |
|
|
|
ceabfb |
RandR12GetDpi(dpy, screen, info);
|