diff --git a/.gitignore b/.gitignore index a4673f3..3227eb0 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ /open-vm-tools-10.1.0-4449150.tar.gz /open-vm-tools-10.1.5-5055683.tar.gz /open-vm-tools-10.1.10-6082533.tar.gz +/open-vm-tools-10.2.0-7253323.tar.gz diff --git a/open-vm-tools.spec b/open-vm-tools.spec index e63b0b9..83b3256 100644 --- a/open-vm-tools.spec +++ b/open-vm-tools.spec @@ -19,16 +19,16 @@ ################################################################################ %global _hardened_build 1 -%global majorversion 10.1 -%global minorversion 10 -%global toolsbuild 6082533 +%global majorversion 10.2 +%global minorversion 0 +%global toolsbuild 7253323 %global toolsversion %{majorversion}.%{minorversion} %global toolsdaemon vmtoolsd %global vgauthdaemon vgauthd Name: open-vm-tools Version: %{toolsversion} -Release: 4%{?dist} +Release: 1%{?dist} Summary: Open Virtual Machine Tools for virtual machines hosted on VMware Group: Applications/System License: GPLv2 @@ -42,9 +42,6 @@ ExclusiveArch: x86_64 ExclusiveArch: %{ix86} x86_64 %endif -Patch1: resolutionKMS-wayland.patch -Patch2: resolutionKMS-wayland-2.patch - BuildRequires: autoconf BuildRequires: automake BuildRequires: libtool @@ -53,7 +50,7 @@ BuildRequires: doxygen # Fuse is optional and enables vmblock-fuse BuildRequires: fuse-devel BuildRequires: glib2-devel >= 2.14.0 -BuildRequires: gtk2-devel >= 2.4.0 +BuildRequires: gtk3-devel >= 3.0.0 %if 0%{?fedora} >= 23 || 0%{?rhel} > 7 # F23 split gdk-pixbuf2-devel >= 2.31.3-5 into 3 packages, # gdk-pixbuf2-devel, gdk-pixbuf2-modules-devel, and @@ -62,7 +59,7 @@ BuildRequires: gtk2-devel >= 2.4.0 # gdk-pixbuf2-xlib-devel dependency ourselves. BuildRequires: gdk-pixbuf2-xlib-devel %endif -BuildRequires: gtkmm24-devel +BuildRequires: gtkmm30-devel >= 3.0.0 BuildRequires: libdnet-devel BuildRequires: libicu-devel BuildRequires: libmspack-devel @@ -128,10 +125,18 @@ This package contains only the user-space programs and libraries of %{name} that are essential for developing customized applications for VMware virtual machines. +%package test +Summary: Test utilities for Open Virtual Machine Tools +Group: Development/Libraries +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description test +This package contains only the test utilities for %{name} that are +useful for verifying the functioning of %{name} in VMware virtual +machines. + %prep %setup -q -n %{name}-%{version}-%{toolsbuild} -%patch1 -p1 -%patch2 -p1 %build # Required for regenerating configure script when @@ -286,6 +291,7 @@ fi %files desktop %{_sysconfdir}/xdg/autostart/*.desktop +%{_bindir}/vmware-user %{_bindir}/vmware-user-suid-wrapper %{_bindir}/vmware-vmblock-fuse %{_libdir}/%{name}/plugins/vmusr/ @@ -301,7 +307,18 @@ fi %{_libdir}/libvgauth.so %{_libdir}/libvmtools.so +%files test +%{_bindir}/vmware-vgauth-smoketest + %changelog +* Fri Dec 15 2017 Ravindra Kumar - 10.2.0-1 +- Package new upstream version open-vm-tools-10.2.0-7253323. +- Remove the patches that are no longer needed. +- New version builds with gtk3 by default. +- Package vmware-user symlink in desktop. +- Add a new test package for test utilities. +- Pick a fix to a conditional from Miroslav Vadkerti . + * Thu Nov 30 2017 Pete Walter - 10.1.10-4 - Rebuild for ICU 60.1 diff --git a/resolutionKMS-wayland-2.patch b/resolutionKMS-wayland-2.patch deleted file mode 100644 index 8c9376d..0000000 --- a/resolutionKMS-wayland-2.patch +++ /dev/null @@ -1,339 +0,0 @@ ---- open-vm-tools-10.1.10-6082533/services/plugins/resolutionKMS/resolutionKMS.c 2017-09-27 18:16:07.428992005 -0700 -+++ open-vm-tools-10.1.10-modified/services/plugins/resolutionKMS/resolutionKMS.c 2017-09-27 16:38:40.000000000 -0700 -@@ -1,5 +1,5 @@ - /********************************************************* -- * Copyright (C) 2008-2016 VMware, Inc. All rights reserved. -+ * Copyright (C) 2008-2017 VMware, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published -@@ -279,6 +279,34 @@ - g_warning("%s: Unable to set tools.capability.resolution_server\n", - __FUNCTION__); - } -+ -+ if (value == 1) { -+ /* -+ * Whenever resolutionKMS is enabled, send -+ * "tools.capability.resolution_server toolbox-dnd 0" to clear -+ * resolutionSet as resolution server. -+ * -+ * Note: The below rpc is sent to TOOLS_DND_NAME if rpcChannelName is -+ * TOOLS_DAEMON_NAME and vice versa (to clear the opposite channel). -+ * This is how rpcChannelName is selected in ToolsOnLoad(): -+ * -+ * if (strcmp(ctx->name, VMTOOLS_GUEST_SERVICE) == 0) { -+ * rpcChannelName = TOOLS_DAEMON_NAME; -+ * } else if (strcmp(ctx->name, VMTOOLS_USER_SERVICE) == 0) { -+ * rpcChannelName = TOOLS_DND_NAME; -+ * } -+ */ -+ gchar *msgClear; -+ msgClear = g_strdup_printf("tools.capability.resolution_server %s 0", -+ (strcmp(rpcChannelName, TOOLS_DAEMON_NAME) == 0 ? -+ TOOLS_DND_NAME : TOOLS_DAEMON_NAME)); -+ if (!RpcChannel_Send(chan, msgClear, strlen(msgClear), NULL, NULL)) { -+ g_warning("%s: Unable to clear tools.capability.resolution_server\n", -+ __FUNCTION__); -+ } -+ g_free(msgClear); -+ } -+ - g_free(msg); - } - -@@ -448,7 +476,7 @@ - - /* - * Save the RPC channel name from the ToolsAppCtx so that we can use it later -- * in calls to ResolutionSetServerCapability(). -+ * in calls to ResolutionKMSServerCapability(). - */ - - if (strcmp(ctx->name, VMTOOLS_GUEST_SERVICE) == 0) { ---- open-vm-tools-10.1.10-6082533/services/plugins/resolutionSet/resolutionCommon.c 2017-09-27 18:16:07.429992005 -0700 -+++ open-vm-tools-10.1.10-modified/services/plugins/resolutionSet/resolutionCommon.c 2017-09-27 16:38:40.000000000 -0700 -@@ -1,5 +1,5 @@ - /********************************************************* -- * Copyright (C) 2016 VMware, Inc. All rights reserved. -+ * Copyright (C) 2016-2017 VMware, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published -@@ -38,6 +38,7 @@ - /* The DRM device we are looking for */ - #define RESOLUTION_VENDOR "0x15ad" - #define RESOLUTION_DEVICE "0x0405" -+#define RESOLUTION_KERNELNAME "vmwgfx" - - /* Required DRM version for resolutionKMS */ - #define RESOLUTION_DRM_MAJOR 2 -@@ -84,11 +85,19 @@ - struct udev_list_entry *devices, *devListEntry; - struct udev_device *dev; - int fd = -1; -+ int drmFd; - const char *devNode = NULL; - -+ /* Force load the kernel module. */ -+ drmFd = drmOpen(RESOLUTION_KERNELNAME, NULL); -+ if (drmFd >= 0) { -+ (void) drmDropMaster(drmFd); -+ } -+ - udev = udev_new(); -- if (!udev) -- return -1; -+ if (!udev) { -+ goto outNoUdev; -+ } - - /* - * Udev error return codes that are not caught immediately are -@@ -148,6 +157,10 @@ - udev_enumerate_unref(enumerate); - udev_unref(udev); - -+ if (drmFd >= 0) { -+ drmClose(drmFd); -+ } -+ - return fd; - - outFound: -@@ -155,6 +168,10 @@ - outErr: - udev_enumerate_unref(enumerate); - udev_unref(udev); -+ outNoUdev: -+ if (drmFd >= 0) { -+ drmClose(drmFd); -+ } - - return -1; - } -@@ -190,7 +207,7 @@ - } - - if (ver->version_major != RESOLUTION_DRM_MAJOR || -- ver->version_minor < RESOLUTION_DRM_MINOR) { -+ ver->version_minor < RESOLUTION_DRM_MINOR) { - g_debug("%s: Insufficient DRM version %d.%d for resolutionKMS.\n", - __func__, ver->version_major, ver->version_minor); - drmFreeVersion(ver); ---- open-vm-tools-10.1.10-6082533/services/plugins/resolutionSet/resolutionDL.c 2017-09-27 18:16:07.429992005 -0700 -+++ open-vm-tools-10.1.10-modified/services/plugins/resolutionSet/resolutionDL.c 2017-09-27 16:38:40.000000000 -0700 -@@ -66,6 +66,8 @@ - }; - - static struct FuncToResolv drm2Table[] = { -+ LIBDRM_RESOLV(Open), -+ LIBDRM_RESOLV(Close), - LIBDRM_RESOLV(GetVersion), - LIBDRM_RESOLV(FreeVersion), - LIBDRM_RESOLV(DropMaster), ---- open-vm-tools-10.1.10-6082533/services/plugins/resolutionSet/resolutionDL.h 2017-09-27 18:16:07.429992005 -0700 -+++ open-vm-tools-10.1.10-modified/services/plugins/resolutionSet/resolutionDL.h 2017-09-27 16:38:40.000000000 -0700 -@@ -144,6 +144,8 @@ - * However this struct is not subject to the license header of this file. - */ - struct Drm2Interface { -+ int (*Open)(const char *, const char *); -+ int (*Close)(int); - drmVersionPtr (*GetVersion)(int fd); - void (*FreeVersion)(drmVersionPtr); - int (*DropMaster)(int fd); -@@ -190,6 +192,10 @@ - #define udev_list_entry_foreach(_a, _b)\ - udevi_list_entry_foreach(udevi, _a, _b) - -+#define drmOpen \ -+ drmi->Open -+#define drmClose \ -+ drmi->Close - #define drmGetVersion \ - drmi->GetVersion - #define drmFreeVersion \ ---- open-vm-tools-10.1.10-6082533/services/plugins/resolutionSet/resolutionSet.c 2017-09-27 18:16:07.429992005 -0700 -+++ open-vm-tools-10.1.10-modified/services/plugins/resolutionSet/resolutionSet.c 2017-09-27 16:38:40.000000000 -0700 -@@ -76,8 +76,7 @@ - * - * Initialize the guest resolution library. - * -- * @param[in] handle Back-end specific handle, if needed. E.g., in the X11 -- case, this refers to the X11 display handle. -+ * @param[in] handle Back-end specific handle, if needed. - * @return TRUE on success, FALSE on failure - */ - ---- open-vm-tools-10.1.10-6082533/services/plugins/resolutionSet/resolutionX11.c 2017-09-27 18:16:07.429992005 -0700 -+++ open-vm-tools-10.1.10-modified/services/plugins/resolutionSet/resolutionX11.c 2017-09-27 16:38:40.000000000 -0700 -@@ -35,8 +35,6 @@ - #ifndef NO_MULTIMON - #include - #endif --#include --#include - - #include "vmware.h" - #include "debug.h" -@@ -62,6 +60,8 @@ - Bool canUseVMwareCtrlTopologySet; - // TRUE if VMwareCtrl extension supports topology set - Bool canUseRandR12; // TRUE if RandR extension >= 1.2 available -+ -+ Bool canUseResolutionKMS; // TRUE if backing off for resolutionKMS - } ResolutionInfoX11Type; - - -@@ -78,6 +78,7 @@ - static Bool ResolutionCanSet(void); - static Bool TopologyCanSet(void); - static Bool SelectResolution(uint32 width, uint32 height); -+static int ResolutionX11ErrorHandler(Display *d, XErrorEvent *e); - - - /* -@@ -89,29 +90,45 @@ - * X11 back-end initializer. Records caller's X11 display, then determines - * which capabilities are available. - * -- * @param[in] handle User's X11 display -+ * @param[in] handle (ResolutionInfoX11Type is used as backend specific handle) - * @return TRUE on success, FALSE on failure. - */ - - Bool - ResolutionBackendInit(InitHandle handle) - { -- ResolutionInfoX11Type *resInfoX = &resolutionInfoX11; -+ ResolutionInfoX11Type *resInfoX = (ResolutionInfoX11Type *)handle; - ResolutionInfoType *resInfo = &resolutionInfo; - int dummy1; - int dummy2; - -- memset(resInfoX, 0, sizeof *resInfoX); -+ if (resInfoX->canUseResolutionKMS == TRUE) { -+ resInfo->canSetResolution = FALSE; -+ resInfo->canSetTopology = FALSE; -+ return FALSE; -+ } - -- resInfoX->display = handle; -+ XSetErrorHandler(ResolutionX11ErrorHandler); -+ resInfoX->display = XOpenDisplay(NULL); - -+ /* -+ * In case display is NULL, we do not load resolutionSet -+ * as it serve no purpose. Also avoids SEGFAULT issue -+ * like BZ1880932. -+ * -+ * VMX currently remembers the settings across a reboot, -+ * so let's say someone replaces our Xorg driver with -+ * xf86-video-modesetting, and then rebooted, we'd end up here, -+ * but the VMX would still send resolution / topology events -+ * and we'd hit the same segfault. -+ */ - if (resInfoX->display == NULL) { -+ g_error("%s: Invalid display detected.\n", __func__); - resInfo->canSetResolution = FALSE; - resInfo->canSetTopology = FALSE; -- return TRUE; -+ return FALSE; - } - -- resInfoX->display = handle; - resInfoX->rootWindow = DefaultRootWindow(resInfoX->display); - resInfoX->canUseVMwareCtrl = VMwareCtrl_QueryVersion(resInfoX->display, &dummy1, - &dummy2); -@@ -132,6 +149,10 @@ - void - ResolutionBackendCleanup(void) - { -+ ResolutionInfoX11Type *resInfoX = &resolutionInfoX11; -+ if (resInfoX->display) { -+ XCloseDisplay(resInfoX->display); -+ } - return; - } - -@@ -524,7 +545,7 @@ - g_debug("Setting guest resolution to: %dx%d (requested: %d, %d)\n", - xrrSizes[bestFitIndex].width, xrrSizes[bestFitIndex].height, width, height); - rc = XRRSetScreenConfig(resInfoX->display, xrrConfig, resInfoX->rootWindow, -- bestFitIndex, xrrCurRotation, GDK_CURRENT_TIME); -+ bestFitIndex, xrrCurRotation, CurrentTime); - g_debug("XRRSetScreenConfig returned %d (result: %dx%d)\n", rc, - xrrSizes[bestFitIndex].width, xrrSizes[bestFitIndex].height); - } else { -@@ -574,42 +595,28 @@ - - - /** -- * Obtain a "handle", which for X11, is a display pointer. -+ * Obtain a "handle". - * - * @note We will have to move this out of the resolution plugin soon, I am -- * just landing this here now for convenience as I port resolution set over -+ * just landing this here now for convenience as I port resolution set over - * to the new service architecture. - * -- * @return X server display -+ * @return ResolutionInfoX11Type as backend specific handle - */ - - InitHandle - ResolutionToolkitInit(ToolsAppCtx *ctx) // IN: For config database access - { -- int argc = 1; -- char *argv[] = {"", NULL}; -- GtkWidget *wnd; -- Display *display; -+ ResolutionInfoX11Type *resInfoX = &resolutionInfoX11; - int fd; - -+ memset(resInfoX, 0, sizeof *resInfoX); -+ - fd = resolutionCheckForKMS(ctx); - if (fd >= 0) { - resolutionDRMClose(fd); - g_message("%s: Backing off for resolutionKMS.\n", __func__); -- return (InitHandle) 0; -+ resInfoX->canUseResolutionKMS = TRUE; - } -- -- XSetErrorHandler(ResolutionX11ErrorHandler); -- gtk_init(&argc, (char ***) &argv); -- wnd = gtk_invisible_new(); --#ifndef GTK3 -- display = GDK_WINDOW_XDISPLAY(wnd->window); --#else -- display = GDK_WINDOW_XDISPLAY(gtk_widget_get_window(wnd)); --#endif -- -- if (!display) -- g_error("%s: Invalid display detected.\n", __func__); -- -- return (InitHandle) display; -+ return (InitHandle) resInfoX; - } ---- open-vm-tools-10.1.10-6082533/services/plugins/resolutionSet/resolutionRandR12.c 2017-07-28 15:19:20.000000000 -0700 -+++ open-vm-tools-10.1.10-modified/services/plugins/resolutionSet/resolutionRandR12.c 2017-09-27 16:38:40.000000000 -0700 -@@ -139,7 +139,7 @@ - #define LOG_STOP fclose(_ofile) - #else - #define LOG_START --#include -+#include - #define LOG_STOP - #endif - -@@ -1000,7 +1000,7 @@ - info = RandR12GetInfo(dpy, rootWin); - if (!info) { - g_warning("%s: Setup info struct failed.\n", __func__); -- goto out_ungrab; -+ return FALSE; - } - - RandR12GetDpi(dpy, screen, info); diff --git a/resolutionKMS-wayland.patch b/resolutionKMS-wayland.patch deleted file mode 100644 index c922818..0000000 --- a/resolutionKMS-wayland.patch +++ /dev/null @@ -1,2283 +0,0 @@ -diff --git a/configure.ac b/configure.ac -index 20370ae..9e4272e 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -235,6 +235,14 @@ AC_ARG_ENABLE( - [enable_tests="$enableval"], - [enable_tests="auto"]) - -+AC_ARG_ENABLE( -+ resolutionkms, -+ AS_HELP_STRING( -+ [--enable-resolutionkms], -+ [build the linux / unix resolutionkms module.]), -+ [], -+ [enable_resolutionkms="auto"]) -+ - AM_INIT_AUTOMAKE - - ### -@@ -792,6 +800,7 @@ AC_CHECK_FUNCS( - [VIX_LIBADD="$VIX_LIBADD -ldl" - LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -ldl" - VGAUTH_LIBADD="$VGAUTH_LIBADD -ldl" -+ RESOLUTIONSET_LIBADD="$RESOLUTIONSET_LIBADD -ldl" - ], - [AC_MSG_ERROR( - [dlopen was not found, but is required for open-vm-tools to function properly. Please contact your OS vendor.])])]) -@@ -1265,6 +1274,15 @@ if test "$os" = "linux"; then - MODULES="$MODULES vmblock vmsync" - fi - buildHgfsmounter=yes -+ if test "x$enable_resolutionkms" != "xno"; then -+ PKG_CHECK_MODULES( -+ [LIBUDEV], -+ libdrm libudev, -+ [LIBUDEV_CFLAGS="$LIBUDEV_CFLAGS -DHAVE_LIBUDEV"], -+ [AC_MSG_WARN( -+ [Missing libdrm or libudev. The resolutionKMS plugin will search for them at run-time.])]) -+ enable_resolutionkms="yes" -+ fi - fi - - if test "$os" = "freebsd" || test "$os" = "kfreebsd-gnu"; then -@@ -1352,6 +1370,14 @@ else - UDEVRULESDIR="" - fi - -+if test "x$enable_resolutionkms" = "xauto"; then -+ enable_resolutionkms="no" -+fi -+ -+if test "x$enable_resolutionkms" = "xyes"; then -+ CPPFLAGS="$CPPFLAGS -DENABLE_RESOLUTIONKMS" -+fi -+ - AM_CONDITIONAL(BUILD_HGFSMOUNTER, test "$buildHgfsmounter" = "yes") - AM_CONDITIONAL(LINUX, test "$os" = "linux") - AM_CONDITIONAL(SOLARIS, test "$os" = "solaris") -@@ -1382,6 +1408,7 @@ AM_CONDITIONAL(ENABLE_CAF, test "$enable_caf" = "yes") - AM_CONDITIONAL(HAVE_VSOCK, test "$os" = "linux") - AM_CONDITIONAL(HAVE_MKDTEMP, test "$have_mkdtemp" = "yes") - AM_CONDITIONAL(HAVE_UDEV, test "$have_udev" = "yes") -+AM_CONDITIONAL(ENABLE_RESOLUTIONKMS, test "x$enable_resolutionkms" = "xyes") - - if test "$have_xsm" != "yes"; then - AC_DEFINE([NO_XSM], 1, []) -@@ -1492,6 +1519,7 @@ AC_SUBST([LIB_AUTH_CPPFLAGS]) - AC_SUBST([LIB_IMPERSONATE_CPPFLAGS]) - AC_SUBST([LIB_USER_CPPFLAGS]) - AC_SUBST([LIBVMTOOLS_LIBADD]) -+AC_SUBST([RESOLUTIONSET_LIBADD]) - - ### Program substs - -@@ -1564,6 +1592,7 @@ AC_CONFIG_FILES([ \ - services/plugins/hgfsServer/Makefile \ - services/plugins/powerOps/Makefile \ - services/plugins/resolutionSet/Makefile \ -+ services/plugins/resolutionKMS/Makefile \ - services/plugins/timeSync/Makefile \ - services/plugins/vix/Makefile \ - services/plugins/vmbackup/Makefile \ -diff --git a/services/plugins/Makefile.am b/services/plugins/Makefile.am -index 5d75718..5deb281 100644 ---- a/services/plugins/Makefile.am -+++ b/services/plugins/Makefile.am -@@ -34,6 +34,14 @@ endif - if HAVE_X11 - SUBDIRS += resolutionSet - endif -+if ENABLE_RESOLUTIONKMS -+if !HAVE_X11 -+# resolutionKMS needs resolutionCommon, which lives in -+# the resolutionSet sub directory -+ SUBDIRS += resolutionSet -+endif -+SUBDIRS += resolutionKMS -+endif - SUBDIRS += timeSync - SUBDIRS += vix - SUBDIRS += vmbackup -diff --git a/services/plugins/resolutionKMS/COPYING b/services/plugins/resolutionKMS/COPYING -new file mode 100644 -index 0000000..9c6a6cc ---- /dev/null -+++ b/services/plugins/resolutionKMS/COPYING -@@ -0,0 +1,502 @@ -+ GNU LESSER GENERAL PUBLIC LICENSE -+ Version 2.1, February 1999 -+ -+ Copyright (C) 1991, 1999 Free Software Foundation, Inc. -+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ Everyone is permitted to copy and distribute verbatim copies -+ of this license document, but changing it is not allowed. -+ -+[This is the first released version of the Lesser GPL. It also counts -+ as the successor of the GNU Library Public License, version 2, hence -+ the version number 2.1.] -+ -+ Preamble -+ -+ The licenses for most software are designed to take away your -+freedom to share and change it. By contrast, the GNU General Public -+Licenses are intended to guarantee your freedom to share and change -+free software--to make sure the software is free for all its users. -+ -+ This license, the Lesser General Public License, applies to some -+specially designated software packages--typically libraries--of the -+Free Software Foundation and other authors who decide to use it. You -+can use it too, but we suggest you first think carefully about whether -+this license or the ordinary General Public License is the better -+strategy to use in any particular case, based on the explanations below. -+ -+ When we speak of free software, we are referring to freedom of use, -+not price. Our General Public Licenses are designed to make sure that -+you have the freedom to distribute copies of free software (and charge -+for this service if you wish); that you receive source code or can get -+it if you want it; that you can change the software and use pieces of -+it in new free programs; and that you are informed that you can do -+these things. -+ -+ To protect your rights, we need to make restrictions that forbid -+distributors to deny you these rights or to ask you to surrender these -+rights. These restrictions translate to certain responsibilities for -+you if you distribute copies of the library or if you modify it. -+ -+ For example, if you distribute copies of the library, whether gratis -+or for a fee, you must give the recipients all the rights that we gave -+you. You must make sure that they, too, receive or can get the source -+code. If you link other code with the library, you must provide -+complete object files to the recipients, so that they can relink them -+with the library after making changes to the library and recompiling -+it. And you must show them these terms so they know their rights. -+ -+ We protect your rights with a two-step method: (1) we copyright the -+library, and (2) we offer you this license, which gives you legal -+permission to copy, distribute and/or modify the library. -+ -+ To protect each distributor, we want to make it very clear that -+there is no warranty for the free library. Also, if the library is -+modified by someone else and passed on, the recipients should know -+that what they have is not the original version, so that the original -+author's reputation will not be affected by problems that might be -+introduced by others. -+ -+ Finally, software patents pose a constant threat to the existence of -+any free program. We wish to make sure that a company cannot -+effectively restrict the users of a free program by obtaining a -+restrictive license from a patent holder. Therefore, we insist that -+any patent license obtained for a version of the library must be -+consistent with the full freedom of use specified in this license. -+ -+ Most GNU software, including some libraries, is covered by the -+ordinary GNU General Public License. This license, the GNU Lesser -+General Public License, applies to certain designated libraries, and -+is quite different from the ordinary General Public License. We use -+this license for certain libraries in order to permit linking those -+libraries into non-free programs. -+ -+ When a program is linked with a library, whether statically or using -+a shared library, the combination of the two is legally speaking a -+combined work, a derivative of the original library. The ordinary -+General Public License therefore permits such linking only if the -+entire combination fits its criteria of freedom. The Lesser General -+Public License permits more lax criteria for linking other code with -+the library. -+ -+ We call this license the "Lesser" General Public License because it -+does Less to protect the user's freedom than the ordinary General -+Public License. It also provides other free software developers Less -+of an advantage over competing non-free programs. These disadvantages -+are the reason we use the ordinary General Public License for many -+libraries. However, the Lesser license provides advantages in certain -+special circumstances. -+ -+ For example, on rare occasions, there may be a special need to -+encourage the widest possible use of a certain library, so that it becomes -+a de-facto standard. To achieve this, non-free programs must be -+allowed to use the library. A more frequent case is that a free -+library does the same job as widely used non-free libraries. In this -+case, there is little to gain by limiting the free library to free -+software only, so we use the Lesser General Public License. -+ -+ In other cases, permission to use a particular library in non-free -+programs enables a greater number of people to use a large body of -+free software. For example, permission to use the GNU C Library in -+non-free programs enables many more people to use the whole GNU -+operating system, as well as its variant, the GNU/Linux operating -+system. -+ -+ Although the Lesser General Public License is Less protective of the -+users' freedom, it does ensure that the user of a program that is -+linked with the Library has the freedom and the wherewithal to run -+that program using a modified version of the Library. -+ -+ The precise terms and conditions for copying, distribution and -+modification follow. Pay close attention to the difference between a -+"work based on the library" and a "work that uses the library". The -+former contains code derived from the library, whereas the latter must -+be combined with the library in order to run. -+ -+ GNU LESSER GENERAL PUBLIC LICENSE -+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -+ -+ 0. This License Agreement applies to any software library or other -+program which contains a notice placed by the copyright holder or -+other authorized party saying it may be distributed under the terms of -+this Lesser General Public License (also called "this License"). -+Each licensee is addressed as "you". -+ -+ A "library" means a collection of software functions and/or data -+prepared so as to be conveniently linked with application programs -+(which use some of those functions and data) to form executables. -+ -+ The "Library", below, refers to any such software library or work -+which has been distributed under these terms. A "work based on the -+Library" means either the Library or any derivative work under -+copyright law: that is to say, a work containing the Library or a -+portion of it, either verbatim or with modifications and/or translated -+straightforwardly into another language. (Hereinafter, translation is -+included without limitation in the term "modification".) -+ -+ "Source code" for a work means the preferred form of the work for -+making modifications to it. For a library, complete source code means -+all the source code for all modules it contains, plus any associated -+interface definition files, plus the scripts used to control compilation -+and installation of the library. -+ -+ Activities other than copying, distribution and modification are not -+covered by this License; they are outside its scope. The act of -+running a program using the Library is not restricted, and output from -+such a program is covered only if its contents constitute a work based -+on the Library (independent of the use of the Library in a tool for -+writing it). Whether that is true depends on what the Library does -+and what the program that uses the Library does. -+ -+ 1. You may copy and distribute verbatim copies of the Library's -+complete source code as you receive it, in any medium, provided that -+you conspicuously and appropriately publish on each copy an -+appropriate copyright notice and disclaimer of warranty; keep intact -+all the notices that refer to this License and to the absence of any -+warranty; and distribute a copy of this License along with the -+Library. -+ -+ You may charge a fee for the physical act of transferring a copy, -+and you may at your option offer warranty protection in exchange for a -+fee. -+ -+ 2. You may modify your copy or copies of the Library or any portion -+of it, thus forming a work based on the Library, and copy and -+distribute such modifications or work under the terms of Section 1 -+above, provided that you also meet all of these conditions: -+ -+ a) The modified work must itself be a software library. -+ -+ b) You must cause the files modified to carry prominent notices -+ stating that you changed the files and the date of any change. -+ -+ c) You must cause the whole of the work to be licensed at no -+ charge to all third parties under the terms of this License. -+ -+ d) If a facility in the modified Library refers to a function or a -+ table of data to be supplied by an application program that uses -+ the facility, other than as an argument passed when the facility -+ is invoked, then you must make a good faith effort to ensure that, -+ in the event an application does not supply such function or -+ table, the facility still operates, and performs whatever part of -+ its purpose remains meaningful. -+ -+ (For example, a function in a library to compute square roots has -+ a purpose that is entirely well-defined independent of the -+ application. Therefore, Subsection 2d requires that any -+ application-supplied function or table used by this function must -+ be optional: if the application does not supply it, the square -+ root function must still compute square roots.) -+ -+These requirements apply to the modified work as a whole. If -+identifiable sections of that work are not derived from the Library, -+and can be reasonably considered independent and separate works in -+themselves, then this License, and its terms, do not apply to those -+sections when you distribute them as separate works. But when you -+distribute the same sections as part of a whole which is a work based -+on the Library, the distribution of the whole must be on the terms of -+this License, whose permissions for other licensees extend to the -+entire whole, and thus to each and every part regardless of who wrote -+it. -+ -+Thus, it is not the intent of this section to claim rights or contest -+your rights to work written entirely by you; rather, the intent is to -+exercise the right to control the distribution of derivative or -+collective works based on the Library. -+ -+In addition, mere aggregation of another work not based on the Library -+with the Library (or with a work based on the Library) on a volume of -+a storage or distribution medium does not bring the other work under -+the scope of this License. -+ -+ 3. You may opt to apply the terms of the ordinary GNU General Public -+License instead of this License to a given copy of the Library. To do -+this, you must alter all the notices that refer to this License, so -+that they refer to the ordinary GNU General Public License, version 2, -+instead of to this License. (If a newer version than version 2 of the -+ordinary GNU General Public License has appeared, then you can specify -+that version instead if you wish.) Do not make any other change in -+these notices. -+ -+ Once this change is made in a given copy, it is irreversible for -+that copy, so the ordinary GNU General Public License applies to all -+subsequent copies and derivative works made from that copy. -+ -+ This option is useful when you wish to copy part of the code of -+the Library into a program that is not a library. -+ -+ 4. You may copy and distribute the Library (or a portion or -+derivative of it, under Section 2) in object code or executable form -+under the terms of Sections 1 and 2 above provided that you accompany -+it with the complete corresponding machine-readable source code, which -+must be distributed under the terms of Sections 1 and 2 above on a -+medium customarily used for software interchange. -+ -+ If distribution of object code is made by offering access to copy -+from a designated place, then offering equivalent access to copy the -+source code from the same place satisfies the requirement to -+distribute the source code, even though third parties are not -+compelled to copy the source along with the object code. -+ -+ 5. A program that contains no derivative of any portion of the -+Library, but is designed to work with the Library by being compiled or -+linked with it, is called a "work that uses the Library". Such a -+work, in isolation, is not a derivative work of the Library, and -+therefore falls outside the scope of this License. -+ -+ However, linking a "work that uses the Library" with the Library -+creates an executable that is a derivative of the Library (because it -+contains portions of the Library), rather than a "work that uses the -+library". The executable is therefore covered by this License. -+Section 6 states terms for distribution of such executables. -+ -+ When a "work that uses the Library" uses material from a header file -+that is part of the Library, the object code for the work may be a -+derivative work of the Library even though the source code is not. -+Whether this is true is especially significant if the work can be -+linked without the Library, or if the work is itself a library. The -+threshold for this to be true is not precisely defined by law. -+ -+ If such an object file uses only numerical parameters, data -+structure layouts and accessors, and small macros and small inline -+functions (ten lines or less in length), then the use of the object -+file is unrestricted, regardless of whether it is legally a derivative -+work. (Executables containing this object code plus portions of the -+Library will still fall under Section 6.) -+ -+ Otherwise, if the work is a derivative of the Library, you may -+distribute the object code for the work under the terms of Section 6. -+Any executables containing that work also fall under Section 6, -+whether or not they are linked directly with the Library itself. -+ -+ 6. As an exception to the Sections above, you may also combine or -+link a "work that uses the Library" with the Library to produce a -+work containing portions of the Library, and distribute that work -+under terms of your choice, provided that the terms permit -+modification of the work for the customer's own use and reverse -+engineering for debugging such modifications. -+ -+ You must give prominent notice with each copy of the work that the -+Library is used in it and that the Library and its use are covered by -+this License. You must supply a copy of this License. If the work -+during execution displays copyright notices, you must include the -+copyright notice for the Library among them, as well as a reference -+directing the user to the copy of this License. Also, you must do one -+of these things: -+ -+ a) Accompany the work with the complete corresponding -+ machine-readable source code for the Library including whatever -+ changes were used in the work (which must be distributed under -+ Sections 1 and 2 above); and, if the work is an executable linked -+ with the Library, with the complete machine-readable "work that -+ uses the Library", as object code and/or source code, so that the -+ user can modify the Library and then relink to produce a modified -+ executable containing the modified Library. (It is understood -+ that the user who changes the contents of definitions files in the -+ Library will not necessarily be able to recompile the application -+ to use the modified definitions.) -+ -+ b) Use a suitable shared library mechanism for linking with the -+ Library. A suitable mechanism is one that (1) uses at run time a -+ copy of the library already present on the user's computer system, -+ rather than copying library functions into the executable, and (2) -+ will operate properly with a modified version of the library, if -+ the user installs one, as long as the modified version is -+ interface-compatible with the version that the work was made with. -+ -+ c) Accompany the work with a written offer, valid for at -+ least three years, to give the same user the materials -+ specified in Subsection 6a, above, for a charge no more -+ than the cost of performing this distribution. -+ -+ d) If distribution of the work is made by offering access to copy -+ from a designated place, offer equivalent access to copy the above -+ specified materials from the same place. -+ -+ e) Verify that the user has already received a copy of these -+ materials or that you have already sent this user a copy. -+ -+ For an executable, the required form of the "work that uses the -+Library" must include any data and utility programs needed for -+reproducing the executable from it. However, as a special exception, -+the materials to be distributed need not include anything that is -+normally distributed (in either source or binary form) with the major -+components (compiler, kernel, and so on) of the operating system on -+which the executable runs, unless that component itself accompanies -+the executable. -+ -+ It may happen that this requirement contradicts the license -+restrictions of other proprietary libraries that do not normally -+accompany the operating system. Such a contradiction means you cannot -+use both them and the Library together in an executable that you -+distribute. -+ -+ 7. You may place library facilities that are a work based on the -+Library side-by-side in a single library together with other library -+facilities not covered by this License, and distribute such a combined -+library, provided that the separate distribution of the work based on -+the Library and of the other library facilities is otherwise -+permitted, and provided that you do these two things: -+ -+ a) Accompany the combined library with a copy of the same work -+ based on the Library, uncombined with any other library -+ facilities. This must be distributed under the terms of the -+ Sections above. -+ -+ b) Give prominent notice with the combined library of the fact -+ that part of it is a work based on the Library, and explaining -+ where to find the accompanying uncombined form of the same work. -+ -+ 8. You may not copy, modify, sublicense, link with, or distribute -+the Library except as expressly provided under this License. Any -+attempt otherwise to copy, modify, sublicense, link with, or -+distribute the Library is void, and will automatically terminate your -+rights under this License. However, parties who have received copies, -+or rights, from you under this License will not have their licenses -+terminated so long as such parties remain in full compliance. -+ -+ 9. You are not required to accept this License, since you have not -+signed it. However, nothing else grants you permission to modify or -+distribute the Library or its derivative works. These actions are -+prohibited by law if you do not accept this License. Therefore, by -+modifying or distributing the Library (or any work based on the -+Library), you indicate your acceptance of this License to do so, and -+all its terms and conditions for copying, distributing or modifying -+the Library or works based on it. -+ -+ 10. Each time you redistribute the Library (or any work based on the -+Library), the recipient automatically receives a license from the -+original licensor to copy, distribute, link with or modify the Library -+subject to these terms and conditions. You may not impose any further -+restrictions on the recipients' exercise of the rights granted herein. -+You are not responsible for enforcing compliance by third parties with -+this License. -+ -+ 11. If, as a consequence of a court judgment or allegation of patent -+infringement or for any other reason (not limited to patent issues), -+conditions are imposed on you (whether by court order, agreement or -+otherwise) that contradict the conditions of this License, they do not -+excuse you from the conditions of this License. If you cannot -+distribute so as to satisfy simultaneously your obligations under this -+License and any other pertinent obligations, then as a consequence you -+may not distribute the Library at all. For example, if a patent -+license would not permit royalty-free redistribution of the Library by -+all those who receive copies directly or indirectly through you, then -+the only way you could satisfy both it and this License would be to -+refrain entirely from distribution of the Library. -+ -+If any portion of this section is held invalid or unenforceable under any -+particular circumstance, the balance of the section is intended to apply, -+and the section as a whole is intended to apply in other circumstances. -+ -+It is not the purpose of this section to induce you to infringe any -+patents or other property right claims or to contest validity of any -+such claims; this section has the sole purpose of protecting the -+integrity of the free software distribution system which is -+implemented by public license practices. Many people have made -+generous contributions to the wide range of software distributed -+through that system in reliance on consistent application of that -+system; it is up to the author/donor to decide if he or she is willing -+to distribute software through any other system and a licensee cannot -+impose that choice. -+ -+This section is intended to make thoroughly clear what is believed to -+be a consequence of the rest of this License. -+ -+ 12. If the distribution and/or use of the Library is restricted in -+certain countries either by patents or by copyrighted interfaces, the -+original copyright holder who places the Library under this License may add -+an explicit geographical distribution limitation excluding those countries, -+so that distribution is permitted only in or among countries not thus -+excluded. In such case, this License incorporates the limitation as if -+written in the body of this License. -+ -+ 13. The Free Software Foundation may publish revised and/or new -+versions of the Lesser General Public License from time to time. -+Such new versions will be similar in spirit to the present version, -+but may differ in detail to address new problems or concerns. -+ -+Each version is given a distinguishing version number. If the Library -+specifies a version number of this License which applies to it and -+"any later version", you have the option of following the terms and -+conditions either of that version or of any later version published by -+the Free Software Foundation. If the Library does not specify a -+license version number, you may choose any version ever published by -+the Free Software Foundation. -+ -+ 14. If you wish to incorporate parts of the Library into other free -+programs whose distribution conditions are incompatible with these, -+write to the author to ask for permission. For software which is -+copyrighted by the Free Software Foundation, write to the Free -+Software Foundation; we sometimes make exceptions for this. Our -+decision will be guided by the two goals of preserving the free status -+of all derivatives of our free software and of promoting the sharing -+and reuse of software generally. -+ -+ NO WARRANTY -+ -+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. -+ -+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -+DAMAGES. -+ -+ END OF TERMS AND CONDITIONS -+ -+ How to Apply These Terms to Your New Libraries -+ -+ If you develop a new library, and you want it to be of the greatest -+possible use to the public, we recommend making it free software that -+everyone can redistribute and change. You can do so by permitting -+redistribution under these terms (or, alternatively, under the terms of the -+ordinary General Public License). -+ -+ To apply these terms, attach the following notices to the library. It is -+safest to attach them to the start of each source file to most effectively -+convey the exclusion of warranty; and each file should have at least the -+"copyright" line and a pointer to where the full notice is found. -+ -+ -+ Copyright (C) -+ -+ This library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ This library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with this library; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ -+Also add information on how to contact you by electronic and paper mail. -+ -+You should also get your employer (if you work as a programmer) or your -+school, if any, to sign a "copyright disclaimer" for the library, if -+necessary. Here is a sample; alter the names: -+ -+ Yoyodyne, Inc., hereby disclaims all copyright interest in the -+ library `Frob' (a library for tweaking knobs) written by James Random Hacker. -+ -+ , 1 April 1990 -+ Ty Coon, President of Vice -+ -+That's all there is to it! -diff --git a/services/plugins/resolutionKMS/Makefile.am b/services/plugins/resolutionKMS/Makefile.am -new file mode 100644 -index 0000000..4503dc6 ---- /dev/null -+++ b/services/plugins/resolutionKMS/Makefile.am -@@ -0,0 +1,37 @@ -+################################################################################ -+### Copyright (C) 2009-2016 VMware, Inc. All rights reserved. -+### -+### This program is free software; you can redistribute it and/or modify -+### it under the terms of version 2 of the GNU General Public License as -+### published by the Free Software Foundation. -+### -+### This program is distributed in the hope that it will be useful, -+### but WITHOUT ANY WARRANTY; without even the implied warranty of -+### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+### GNU General Public License for more details. -+### -+### You should have received a copy of the GNU General Public License -+### along with this program; if not, write to the Free Software -+### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+################################################################################ -+ -+plugindir = @VMSVC_PLUGIN_INSTALLDIR@ -+plugin_LTLIBRARIES = libresolutionKMS.la -+ -+libresolutionKMS_la_CPPFLAGS = -+libresolutionKMS_la_CPPFLAGS += @LIBUDEV_CFLAGS@ -+libresolutionKMS_la_CPPFLAGS += @PLUGIN_CPPFLAGS@ -+ -+libresolutionKMS_la_LDFLAGS = -+libresolutionKMS_la_LDFLAGS += @PLUGIN_LDFLAGS@ -+ -+libresolutionKMS_la_LIBADD = -+libresolutionKMS_la_LIBADD += @VMTOOLS_LIBS@ -+libresolutionKMS_la_LIBADD += @RESOLUTIONSET_LIBADD@ -+libresolutionKMS_la_LIBADD += $(top_builddir)/services/plugins/resolutionSet/libresolutionCommon.la -+ -+libresolutionKMS_la_SOURCES = -+libresolutionKMS_la_SOURCES += resolutionKMS.c -+ -+libresolutionKMS_la_DEPENDENCIES = -+libresolutionKMS_la_DEPENDENCIES += $(top_builddir)/services/plugins/resolutionSet/libresolutionCommon.la -diff --git a/services/plugins/resolutionKMS/resolutionKMS.c b/services/plugins/resolutionKMS/resolutionKMS.c -new file mode 100644 -index 0000000..6aff018 ---- /dev/null -+++ b/services/plugins/resolutionKMS/resolutionKMS.c -@@ -0,0 +1,465 @@ -+/********************************************************* -+ * Copyright (C) 2008-2016 VMware, Inc. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Lesser General Public License as published -+ * by the Free Software Foundation version 2.1 and no later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public -+ * License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public License -+ * along with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ *********************************************************/ -+ -+/** -+ * @file resolutionKMS.c -- -+ * -+ * Plugin to communicate GUI topology to the vmwgfx drm device through a -+ * control node. This file is a modified version of resolutionSet.c -+ */ -+ -+#define G_LOG_DOMAIN "resolutionKMS" -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "vmware.h" -+#include "debug.h" -+#include "rpcout.h" -+#include "str.h" -+#include "strutil.h" -+ -+#include "xdrutil.h" -+#include "vmware/guestrpc/tclodefs.h" -+#include "vmware/tools/plugin.h" -+#include "vmware/tools/utils.h" -+#include "../resolutionSet/resolutionCommon.h" -+#include "../resolutionSet/resolutionDL.h" -+ -+#include "vm_version.h" -+#include "embed_version.h" -+#include "vmtoolsd_version.h" -+VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING); -+ -+/* -+ * The maximum number of capabilities we can set. -+ * -+ * See ResolutionSetCapabilities(). -+ */ -+#define RESOLUTION_SET_CAPABILITIES_MAX 5 -+ -+/* -+ * Global information about the communication state -+ */ -+typedef struct { -+ gboolean initialized; // Whether the plugin is already initialized. -+ int fd; // File descriptor to the DRM device. -+} KMSInfoType; -+ -+/* -+ * Internal global variables -+ */ -+KMSInfoType kmsInfo; -+ -+/* -+ * The name of the RPC channel we're using, e.g. TOOLS_DAEMON_NAME. Used by -+ * ResolutionSet_SetServerCapability() to determine which capability to set. -+ */ -+static const char *rpcChannelName = NULL; -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * ResolutionWriteToKernel -- -+ * -+ * Write GUI topology info to the drm device. -+ * -+ * Results: -+ * TRUE on success, FALSE on failure. -+ * -+ * Side effects: -+ * The drm device will send an uevent and expose the new -+ * topology. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+ -+static gboolean -+ResolutionWriteToKernel(const struct drm_vmw_rect *rects, // IN: Screen rects -+ unsigned int num_rects) // IN: Number of -+ // rects -+{ -+ struct drm_vmw_update_layout_arg arg; -+ int ret; -+ -+ memset(&arg, 0, sizeof arg); -+ arg.num_outputs = num_rects; -+ arg.rects = (unsigned long) rects; -+ -+ ret = drmCommandWrite(kmsInfo.fd, DRM_VMW_UPDATE_LAYOUT, &arg, sizeof arg); -+ if (ret < 0) { -+ g_debug("%s: FAIL! Resolutionset write to kernel failed: %d\n", -+ __FUNCTION__, ret); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * ResolutionResolutionSetCB -- -+ * -+ * Handler for TCLO 'Resolution_Set'. -+ * Routine unmarshals RPC arguments and passes over to back-end -+ * ResolutionWriteToKernel(). -+ * -+ * Results: -+ * TRUE if we can reply, FALSE otherwise. -+ * -+ * Side effects: -+ * None. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+ -+static gboolean -+ResolutionResolutionSetCB(RpcInData *data) // IN: The RPC data -+{ -+ struct drm_vmw_rect rect; -+ unsigned int index = 0; -+ gboolean retval = FALSE; -+ -+ if (!kmsInfo.initialized) { -+ g_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); -+ } -+ -+ rect.x = 0; -+ rect.y = 0; -+ -+ /* parse the width and height */ -+ if (!StrUtil_GetNextUintToken(&rect.w, &index, data->args, " ")) { -+ goto invalid_arguments; -+ } -+ if (!StrUtil_GetNextUintToken(&rect.h, &index, data->args, "")) { -+ goto invalid_arguments; -+ } -+ -+ retval = ResolutionWriteToKernel(&rect, 1); -+ -+invalid_arguments: -+ return RPCIN_SETRETVALS(data, retval ? "" : "Invalid arguments", retval); -+} -+ -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * ResolutionDisplayTopologySetCB -- -+ * -+ * Handler for TCLO 'DisplayTopology_Set'. -+ * Routine unmarshals RPC arguments and passes over to back-end -+ * ResolutionWriteToKernel(). -+ * -+ * Results: -+ * TRUE if we can reply, FALSE otherwise. -+ * -+ * Side effects: -+ * None. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+ -+static gboolean -+ResolutionDisplayTopologySetCB(RpcInData *data) -+{ -+ struct drm_vmw_rect *rects = NULL; -+ unsigned int count, i; -+ gboolean success = FALSE; -+ const char *p; -+ -+ if (!kmsInfo.initialized) { -+ g_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; -+ } -+ -+ /* -+ * The argument string will look something like: -+ * [ , ] * count. -+ * -+ * e.g. -+ * 3 , 0 0 640 480 , 640 0 800 600 , 0 480 640 480 -+ */ -+ -+ if (sscanf(data->args, "%u", &count) != 1) { -+ return RPCIN_SETRETVALS(data, -+ "Invalid arguments. Expected \"count\"", -+ FALSE); -+ } -+ -+ rects = malloc(sizeof *rects * count); -+ if (!rects) { -+ RPCIN_SETRETVALS(data, -+ "Failed to alloc buffer for display info", -+ FALSE); -+ return FALSE; -+ } -+ -+ for (p = data->args, i = 0; i < count; i++) { -+ p = strchr(p, ','); -+ if (!p) { -+ RPCIN_SETRETVALS(data, -+ "Expected comma separated display list", -+ FALSE); -+ goto out; -+ } -+ p++; /* Skip past the , */ -+ -+ if (sscanf(p, " %d %d %d %d ", &rects[i].x, -+ &rects[i].y, &rects[i].w, &rects[i].h) != 4) { -+ RPCIN_SETRETVALS(data, -+ "Expected x, y, w, h in display entry", -+ FALSE); -+ goto out; -+ } -+ } -+ -+ success = ResolutionWriteToKernel(rects, count); -+ RPCIN_SETRETVALS(data, success ? "" : "ResolutionSetTopology failed", success); -+out: -+ free(rects); -+ return success; -+} -+ -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * ResolutionKMSServerCapability -- -+ * -+ * Sends the tools.capability.resolution_server RPC to the VMX. -+ * -+ * Side effects: -+ * None. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+ -+static void -+ResolutionKMSServerCapability(RpcChannel *chan, // IN: The RPC channel. -+ unsigned int value) // IN: The value to send for -+ // the capability bit. -+{ -+ gchar *msg; -+ -+ if (!rpcChannelName) { -+ g_debug("Channel name is null, RPC not sent.\n"); -+ return; -+ } -+ -+ msg = g_strdup_printf("tools.capability.resolution_server %s %d", -+ rpcChannelName, -+ value); -+ if (!RpcChannel_Send(chan, msg, strlen(msg), NULL, NULL)) { -+ g_warning("%s: Unable to set tools.capability.resolution_server\n", -+ __FUNCTION__); -+ } -+ g_free(msg); -+} -+ -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * ResolutionKMSShutdown -- -+ * -+ * Cleans up internal data on shutdown. -+ * -+ * Side effects: -+ * None. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+ -+static void -+ResolutionKMSShutdown(gpointer src, // IN: Unused. -+ ToolsAppCtx *ctx, // IN: The app context. -+ gpointer data) // IN: Unused. -+{ -+ if (kmsInfo.initialized && ctx && ctx->rpc && ctx->isVMware) { -+ ResolutionKMSServerCapability(ctx->rpc, 0); -+ } -+ -+ if (kmsInfo.initialized) { -+ resolutionDRMClose(kmsInfo.fd); -+ kmsInfo.initialized = FALSE; -+ } -+} -+ -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * ResolutionKMSCapabilities -- -+ * -+ * Cleans up internal data on shutdown. -+ * -+ * Results: -+ * An array of capabilities -+ * -+ * Side effects: -+ * None. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+ -+static GArray * -+ResolutionKMSCapabilities(gpointer src, // IN: The source object. -+ ToolsAppCtx *ctx, // IN: The app context. -+ gboolean set, // IN: Whether setting or unsetting -+ // the capability. -+ gpointer data) // Unused. -+{ -+ /* The array of capabilities to return to the tools service. */ -+ ToolsAppCapability capabilityArray[RESOLUTION_SET_CAPABILITIES_MAX]; -+ -+ /* The next unused entry in the capabilities array. */ -+ unsigned int capabilityCount = 0; -+ -+ g_debug("%s: enter\n", __FUNCTION__); -+ -+ /* -+ * We must register display_topology_set before resolution_set to avoid -+ * a race condition in the host. See bug 472343. -+ */ -+ -+ /* -+ * We use a value of '2' here because, for historical reasons, the -+ * Workstation/Fusion UI will treat a value of 1 for this capability -+ * as unsupported. See bug 149541. -+ */ -+ capabilityArray[capabilityCount].type = TOOLS_CAP_OLD; -+ capabilityArray[capabilityCount].name = "display_topology_set"; -+ capabilityArray[capabilityCount].index = 0; -+ capabilityArray[capabilityCount].value = set ? 2 : 0; -+ capabilityCount++; -+ -+ capabilityArray[capabilityCount].type = TOOLS_CAP_OLD; -+ capabilityArray[capabilityCount].name = "display_global_offset"; -+ capabilityArray[capabilityCount].index = 0; -+ capabilityArray[capabilityCount].value = set ? 1 : 0; -+ capabilityCount++; -+ -+ capabilityArray[capabilityCount].type = TOOLS_CAP_OLD; -+ capabilityArray[capabilityCount].name = "resolution_set"; -+ capabilityArray[capabilityCount].index = 0; -+ capabilityArray[capabilityCount].value = set ? 1 : 0; -+ capabilityCount++; -+ -+ /* -+ * Send the resolution_server RPC to the VMX. -+ * -+ * XXX: We need to send this ourselves, instead of including it in the -+ * capability array, because the resolution_server RPC includes the -+ * name of the RPC channel that the VMX should use when sending -+ * resolution set RPCs as an argument. -+ */ -+ -+ if (kmsInfo.initialized && ctx && ctx->rpc && ctx->isVMware) { -+ ResolutionKMSServerCapability(ctx->rpc, set ? 1:0); -+ } -+ -+ ASSERT(capabilityCount <= RESOLUTION_SET_CAPABILITIES_MAX); -+ -+ return VMTools_WrapArray(capabilityArray, -+ sizeof *capabilityArray, -+ capabilityCount); -+} -+ -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * ToolsOnLoad -- -+ * -+ * Plugin entry point -+ * -+ * Results: -+ * The registration data. -+ * -+ * Side effects: -+ * Initializes internal plugin state. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+ -+TOOLS_MODULE_EXPORT ToolsPluginData * -+ToolsOnLoad(ToolsAppCtx *ctx) -+{ -+ RpcChannelCallback rpcs[] = { -+ { "Resolution_Set", &ResolutionResolutionSetCB }, -+ { "DisplayTopology_Set", &ResolutionDisplayTopologySetCB }, -+ }; -+ -+ static ToolsPluginData regData = { -+ "resolutionKMS", -+ NULL, -+ NULL -+ }; -+ -+ ToolsPluginSignalCb sigs[] = { -+ { TOOLS_CORE_SIG_CAPABILITIES, ResolutionKMSCapabilities, ®Data }, -+ { TOOLS_CORE_SIG_SHUTDOWN, ResolutionKMSShutdown, ®Data } -+ }; -+ -+ ToolsAppReg regs[] = { -+ { TOOLS_APP_GUESTRPC, NULL }, -+ { TOOLS_APP_SIGNALS, VMTools_WrapArray(sigs, sizeof *sigs, ARRAYSIZE(sigs)) } -+ }; -+ -+ /* -+ * If we aren't running in a VM (e.g., running in bootcamp natively on -+ * a Mac), then just return NULL. -+ */ -+ if (!ctx->isVMware) { -+ return NULL; -+ } -+ -+ kmsInfo.fd = resolutionCheckForKMS(ctx); -+ if (kmsInfo.fd < 0) { -+ return NULL; -+ } -+ kmsInfo.initialized = TRUE; -+ -+ /* -+ * Save the RPC channel name from the ToolsAppCtx so that we can use it later -+ * in calls to ResolutionSetServerCapability(). -+ */ -+ -+ if (strcmp(ctx->name, VMTOOLS_GUEST_SERVICE) == 0) { -+ rpcChannelName = TOOLS_DAEMON_NAME; -+ } else if (strcmp(ctx->name, VMTOOLS_USER_SERVICE) == 0) { -+ rpcChannelName = TOOLS_DND_NAME; -+ } else { -+ NOT_REACHED(); -+ } -+ -+ regs[0].data = VMTools_WrapArray(rpcs, sizeof *rpcs, ARRAYSIZE(rpcs)); -+ regData.regs = VMTools_WrapArray(regs, sizeof *regs, ARRAYSIZE(regs)); -+ return ®Data; -+} -diff --git a/services/plugins/resolutionSet/Makefile.am b/services/plugins/resolutionSet/Makefile.am -index 3d8dbc4..b3cf81e 100644 ---- a/services/plugins/resolutionSet/Makefile.am -+++ b/services/plugins/resolutionSet/Makefile.am -@@ -16,6 +16,9 @@ - ################################################################################ - - plugindir = @VMUSR_PLUGIN_INSTALLDIR@ -+noinst_LTLIBRARIES = libresolutionCommon.la -+ -+if HAVE_X11 - plugin_LTLIBRARIES = libresolutionSet.la - - libresolutionSet_la_CPPFLAGS = -@@ -30,10 +33,27 @@ libresolutionSet_la_LIBADD = - libresolutionSet_la_LIBADD += @COMMON_XLIBS@ - libresolutionSet_la_LIBADD += @GTK_LIBS@ - libresolutionSet_la_LIBADD += @VMTOOLS_LIBS@ -+libresolutionSet_la_LIBADD += @RESOLUTIONSET_LIBADD@ -+libresolutionSet_la_LIBADD += libresolutionCommon.la - - libresolutionSet_la_SOURCES = - libresolutionSet_la_SOURCES += libvmwarectrl.c - libresolutionSet_la_SOURCES += resolutionSet.c - libresolutionSet_la_SOURCES += resolutionX11.c - libresolutionSet_la_SOURCES += resolutionRandR12.c -+endif -+ -+libresolutionCommon_la_CPPFLAGS = -+libresolutionCommon_la_CPPFLAGS += @PLUGIN_CPPFLAGS@ -+libresolutionCommon_la_CPPFLAGS += @LIBUDEV_CFLAGS@ -+ -+libresolutionCommon_la_SOURCES = -+libresolutionCommon_la_SOURCES += resolutionCommon.c -+libresolutionCommon_la_SOURCES += resolutionCommon.h -+libresolutionCommon_la_SOURCES += resolutionDL.c -+libresolutionCommon_la_SOURCES += resolutionDL.h -+libresolutionCommon_la_LDFLAGS = -+libresolutionCommon_la_LDFLAGS += @PLUGIN_LDFLAGS@ - -+libresolutionCommon_la_LIBADD = -+libresolutionCommon_la_LIBADD += @LIBUDEV_LIBS@ -diff --git a/services/plugins/resolutionSet/resolutionCommon.c b/services/plugins/resolutionSet/resolutionCommon.c -new file mode 100644 -index 0000000..9a076e3 ---- /dev/null -+++ b/services/plugins/resolutionSet/resolutionCommon.c -@@ -0,0 +1,430 @@ -+/********************************************************* -+ * Copyright (C) 2016 VMware, Inc. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Lesser General Public License as published -+ * by the Free Software Foundation version 2.1 and no later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public -+ * License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public License -+ * along with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ *********************************************************/ -+/* Authors: -+ * Thomas Hellstrom -+ */ -+ -+#define G_LOG_DOMAIN "resolutionCommon" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "resolutionDL.h" -+#include "vmware/tools/plugin.h" -+#include "vmware/tools/utils.h" -+#include "resolutionCommon.h" -+ -+#ifdef ENABLE_RESOLUTIONKMS -+ -+/* The DRM device we are looking for */ -+#define RESOLUTION_VENDOR "0x15ad" -+#define RESOLUTION_DEVICE "0x0405" -+ -+/* Required DRM version for resolutionKMS */ -+#define RESOLUTION_DRM_MAJOR 2 -+#define RESOLUTION_DRM_MINOR 12 -+ -+/* Required Xorg driver version for resolutionKMS default on */ -+#define RESOLUTION_XORG_MAJOR 13 -+#define RESOLUTION_XORG_MINOR 2 -+ -+/* Recognition token for Xorg driver version scanner */ -+#define RESOLUTION_XORG_VERSTRING "version=" -+ -+/* -+ * Xorg driver file names to scan for. Only the first found will be -+ * scanned for version info. -+ */ -+static const char *driverNames[]= { -+ "/usr/lib64/xorg/modules/drivers/vmware_drv.so", -+ "/usr/lib/xorg/modules/drivers/vmware_drv.so" -+}; -+ -+static const int numDriverNames = 2; -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * resolutionOpenDRM -- -+ * -+ * Opens a file descriptor on the indicated node to the first SVGA2 device. -+ * -+ * Results: -+ * Returns a positive file descriptor on success. Otherwise returns -1. -+ * -+ * Side effects: -+ * None. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+static int -+resolutionOpenDRM(const char *node) // IN: Device node base name. -+{ -+ struct udev *udev; -+ struct udev_enumerate *enumerate; -+ struct udev_list_entry *devices, *devListEntry; -+ struct udev_device *dev; -+ int fd = -1; -+ const char *devNode = NULL; -+ -+ udev = udev_new(); -+ if (!udev) -+ return -1; -+ -+ /* -+ * Udev error return codes that are not caught immediately are -+ * typically caught in the input argument check in the udev -+ * function calls following the failing call! -+ */ -+ enumerate = udev_enumerate_new(udev); -+ if (udev_enumerate_add_match_subsystem(enumerate, "drm")) -+ goto outErr; -+ if (udev_enumerate_add_match_property(enumerate, "DEVTYPE", "drm_minor")) -+ goto outErr; -+ if (udev_enumerate_scan_devices(enumerate)) -+ goto outErr; -+ -+ devices = udev_enumerate_get_list_entry(enumerate); -+ udev_list_entry_foreach(devListEntry, devices) { -+ const char *path, *vendor, *device; -+ struct udev_device *parent; -+ -+ path = udev_list_entry_get_name(devListEntry); -+ if (!path) -+ continue; -+ if (!strstr(path, node)) -+ continue; -+ -+ dev = udev_device_new_from_syspath(udev, path); -+ if (!dev) -+ goto outErr; -+ -+ parent = udev_device_get_parent_with_subsystem_devtype(dev, -+ "pci", -+ NULL); -+ if (!parent) -+ goto skipCheck; -+ -+ vendor = udev_device_get_sysattr_value(parent, "vendor"); -+ device = udev_device_get_sysattr_value(parent, "device"); -+ if (!vendor || !device) -+ goto skipCheck; -+ -+ if (strcmp(vendor, RESOLUTION_VENDOR) || -+ strcmp(device, RESOLUTION_DEVICE)) -+ goto skipCheck; -+ -+ devNode = udev_device_get_devnode(dev); -+ if (!devNode) -+ goto outFound; -+ -+ fd = open(devNode, O_RDWR); -+ udev_device_unref(dev); -+ break; -+ -+skipCheck: -+ udev_device_unref(dev); -+ } -+ -+ udev_enumerate_unref(enumerate); -+ udev_unref(udev); -+ -+ return fd; -+ -+ outFound: -+ udev_device_unref(dev); -+ outErr: -+ udev_enumerate_unref(enumerate); -+ udev_unref(udev); -+ -+ return -1; -+} -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * resolutionDRMCheckVersion -- -+ * -+ * Check that the drm version supports GUI topology communication. -+ * -+ * Checks that the DRM device supports setting GUI topology from the -+ * control node, and also that the topology is communicated on the -+ * modesetting connectors. -+ * -+ * Results: -+ * 0 if DRM device is usable for communicating GUI topology. -+ * -1 otherwise. -+ * -+ * Side effects: -+ * None. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+static int -+resolutionDRMCheckVersion(int fd) // IN: An open DRM file descriptor. -+{ -+ drmVersionPtr ver = drmGetVersion(fd); -+ -+ if (!ver) { -+ g_debug("%s: Failed to get DRM version.\n", __func__); -+ return -1; -+ } -+ -+ if (ver->version_major != RESOLUTION_DRM_MAJOR || -+ ver->version_minor < RESOLUTION_DRM_MINOR) { -+ g_debug("%s: Insufficient DRM version %d.%d for resolutionKMS.\n", -+ __func__, ver->version_major, ver->version_minor); -+ drmFreeVersion(ver); -+ return -1; -+ } -+ -+ drmFreeVersion(ver); -+ return 0; -+} -+ -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * resolutionDRMRPrimaryCheckOpen -- -+ * -+ * First tries to open a render node to DRM, and if that fails opens a -+ * primary node, and drops master. Then checks that drm supports GUI -+ * topology communication. -+ * -+ * Results: -+ * If succesful returns a positive open file descriptor. Otherwise -+ * returns -1. -+ * -+ * Side effects: -+ * May temporarily become drm master if render nodes are not available, -+ * and thus race with the X server. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+static int -+resolutionDRMRPrimaryCheckOpen(void) -+{ -+ int fd = -1; -+ -+ fd = resolutionOpenDRM("renderD"); -+ if (fd < 0) { -+ g_debug("%s: Failed to open DRM render node.\n", __func__); -+ fd = resolutionOpenDRM("card"); -+ if (fd >= 0) -+ (void) drmDropMaster(fd); -+ } -+ if (fd < 0) { -+ g_debug("%s: Failed to open DRM card node.\n", __func__); -+ goto outErr; -+ } -+ -+ if (!resolutionDRMCheckVersion(fd)) { -+ return fd; -+ } -+ -+ close(fd); -+ outErr: -+ return -1; -+} -+ -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * resolutionCheckForKMS -- -+ * -+ * Checks whether the vmwgfx DRM is present and supports exposing -+ * layout information through connector properties and preferred modes. -+ * -+ * Results: -+ * If succesful returns a positive number representing an open file -+ * descriptor to the node indicated by the control argument. If -+ * unsuccessful returns -1. -+ * -+ * Side effects: -+ * Opens a file to DRM. The file descriptor should be closed with -+ * resolutionDRMClose() when needed. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+int -+resolutionCheckForKMS(ToolsAppCtx *ctx) // IN: The ToolsAppCtx for -+ // configuration db access. -+{ -+ GError *err = NULL; -+ gboolean doResolutionKMS; -+ int fd; -+ -+ doResolutionKMS = g_key_file_get_boolean(ctx->config, "resolutionKMS", -+ "enable", &err); -+ if (err) { -+ /* -+ * If there is nothing in the configuration file, require -+ * at least Xorg driver version 13.2.0, which has the autolayout -+ * feature, to enable resolutionKMS. -+ */ -+ int major, minor, level; -+ g_clear_error(&err); -+ doResolutionKMS = FALSE; -+ if (!resolutionXorgDriverVersion(numDriverNames, driverNames, -+ RESOLUTION_XORG_VERSTRING, &major, -+ &minor, &level) && -+ (major > RESOLUTION_XORG_MAJOR || -+ (major == RESOLUTION_XORG_MAJOR && -+ minor >= RESOLUTION_XORG_MINOR))) { -+ doResolutionKMS = TRUE; -+ g_debug("%s: ResolutionKMS enabled based on Xorg driver version.\n", -+ __func__); -+ } else { -+ g_debug("%s: ResolutionKMS disabled. (No configuration).\n", -+ __func__); -+ doResolutionKMS = FALSE; -+ } -+ } else { -+ g_debug("%s: ResolutionKMS %s using configuration file info.\n", -+ __func__, (doResolutionKMS) ? "enabled" : "disabled"); -+ } -+ -+ if (!doResolutionKMS) -+ return -1; -+ -+ if (resolutionDLOpen()) { -+ g_warning("%s: Failed to find needed system libraries for " -+ "resolutionKMS.\n", __func__); -+ return -1; -+ } else { -+ g_message("%s: dlopen succeeded.\n", __func__); -+ } -+ -+ fd = resolutionDRMRPrimaryCheckOpen(); -+ -+ if (fd < 0) -+ g_warning("%s: No system support for resolutionKMS.\n", __func__); -+ else -+ g_message("%s: System support available for resolutionKMS.\n", -+ __func__); -+ -+ return fd; -+} -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * resolutionDRMClose -- -+ * -+ * Scans for VMWare Xorg driver files and tries to determine the Xorg -+ * driver version. -+ * -+ * Results: -+ * If succesful returns zero and outputs the driver version in the -+ * parameters major, minor and level. If not successful, returns -1. -+ * -+ * Side effects: -+ * None. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+void -+resolutionDRMClose(int fd) -+{ -+ close(fd); -+ resolutionDLClose(); -+} -+ -+#endif /* ENABLE_RESOLUTIONKMS */ -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * resolutionXorgDriverVersion -- -+ * -+ * Scans for VMWare Xorg driver files and tries to determine the Xorg -+ * driver version. -+ * -+ * Results: -+ * If succesful returns zero and outputs the driver version in the -+ * parameters major, minor and level. If not successful, returns -1. -+ * -+ * Side effects: -+ * None. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+int -+resolutionXorgDriverVersion(int numPaths, // IN: Number of strings -+ // in paths. -+ const char *paths[], // IN: Possible driver -+ // paths. -+ const char versionString[], // IN: Version token. -+ int *major, // OUT: Major version # -+ int *minor, // OUT: Minor version # -+ int *level) // OUT: Patchlevel -+ // version # -+{ -+ FILE *driver = NULL; -+ const char *curMatch; -+ char curFileChar; -+ int i; -+ -+ g_debug("%s: Scanning for VMWare Xorg drivers.\n", __func__); -+ for(i = 0; i < numPaths; ++i) { -+ g_debug("%s: Looking for \"%s\".\n", __func__, paths[i]); -+ driver = fopen(paths[i], "r"); -+ if (driver) -+ break; -+ } -+ -+ if (!driver) { -+ g_debug("%s: No driver found.\n", __func__); -+ return -1; -+ } -+ -+ g_debug("%s: Driver found. Looking for version info.\n", __func__); -+ curMatch = versionString; -+ while (*curMatch) { -+ if (feof(driver)) -+ goto outNotFound; -+ -+ curFileChar = fgetc(driver); -+ if (curFileChar == *curMatch) { -+ curMatch++; -+ continue; -+ } else if (curMatch != versionString) { -+ curMatch = versionString; -+ (void) ungetc(curFileChar, driver); -+ } -+ } -+ -+ if (fscanf(driver, "%d.%d.%d", major, minor, level) != 3) -+ goto outNotFound; -+ -+ fclose(driver); -+ g_debug("%s: Version info found: %d.%d.%d\n", __func__, *major, *minor, -+ *level); -+ return 0; -+ -+ outNotFound: -+ fclose(driver); -+ g_debug("%s: No version info found.\n", __func__); -+ return -1; -+} -diff --git a/services/plugins/resolutionSet/resolutionCommon.h b/services/plugins/resolutionSet/resolutionCommon.h -new file mode 100644 -index 0000000..6565190 ---- /dev/null -+++ b/services/plugins/resolutionSet/resolutionCommon.h -@@ -0,0 +1,53 @@ -+/********************************************************* -+ * Copyright (C) 2016 VMware, Inc. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Lesser General Public License as published -+ * by the Free Software Foundation version 2.1 and no later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public -+ * License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public License -+ * along with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ *********************************************************/ -+/* Authors: -+ * Thomas Hellstrom -+ */ -+ -+#ifndef _RESOLUTION_COMMON_H_ -+#define _RESOLUTION_COMMON_H_ -+ -+#define INCLUDE_ALLOW_USERLEVEL -+#define INCLUDE_ALLOW_DISTRIBUTE -+#include "includeCheck.h" -+#include "vmware/tools/plugin.h" -+#ifdef ENABLE_RESOLUTIONKMS -+ -+int resolutionCheckForKMS(ToolsAppCtx *ctx); -+void resolutionDRMClose(int fd); -+ -+#else -+ -+static inline int resolutionCheckForKMS(ToolsAppCtx *ctx) -+{ -+ return -1; -+} -+ -+static inline void resolutionDRMClose(int fd) {} -+ -+#endif /* !ENABLE_RESOLUTIONKMS */ -+ -+int -+resolutionXorgDriverVersion(int numPaths, -+ const char *paths[], -+ const char versionString[], -+ int *major, -+ int *minor, -+ int *level); -+ -+#endif /* _RESOLUTION_COMMON_H_ */ -diff --git a/services/plugins/resolutionSet/resolutionDL.c b/services/plugins/resolutionSet/resolutionDL.c -new file mode 100644 -index 0000000..5ec0abb ---- /dev/null -+++ b/services/plugins/resolutionSet/resolutionDL.c -@@ -0,0 +1,206 @@ -+/********************************************************* -+ * Copyright (C) 2016 VMware, Inc. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Lesser General Public License as published -+ * by the Free Software Foundation version 2.1 and no later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public -+ * License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public License -+ * along with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ *********************************************************/ -+/* Authors: -+ * Thomas Hellstrom -+ */ -+ -+#ifdef ENABLE_RESOLUTIONKMS -+#ifndef HAVE_LIBUDEV -+ -+#include "resolutionDL.h" -+#include "vmware.h" -+#include -+#include -+#include -+ -+#define G_LOG_DOMAIN "resolutionCommon" -+#include "vmware/tools/plugin.h" -+#include "vmware/tools/utils.h" -+ -+ -+struct FuncToResolv { -+ size_t offset; -+ const char *name; -+}; -+ -+#define UDEV_RESOLV(_name) \ -+ {.offset = offsetof(struct Udev1Interface, _name), \ -+ .name = "udev"#_name} -+ -+#define LIBDRM_RESOLV(_name) \ -+ {.offset = offsetof(struct Drm2Interface, _name), \ -+ .name = "drm"#_name} -+ -+ -+static struct FuncToResolv udev1Table[] = { -+ UDEV_RESOLV(_device_get_devnode), -+ UDEV_RESOLV(_device_get_parent_with_subsystem_devtype), -+ UDEV_RESOLV(_device_get_sysattr_value), -+ UDEV_RESOLV(_device_new_from_syspath), -+ UDEV_RESOLV(_device_unref), -+ UDEV_RESOLV(_enumerate_add_match_property), -+ UDEV_RESOLV(_enumerate_add_match_subsystem), -+ UDEV_RESOLV(_enumerate_get_list_entry), -+ UDEV_RESOLV(_enumerate_new), -+ UDEV_RESOLV(_enumerate_scan_devices), -+ UDEV_RESOLV(_enumerate_unref), -+ UDEV_RESOLV(_list_entry_get_name), -+ UDEV_RESOLV(_list_entry_get_next), -+ UDEV_RESOLV(_new), -+ UDEV_RESOLV(_unref) -+}; -+ -+static struct FuncToResolv drm2Table[] = { -+ LIBDRM_RESOLV(GetVersion), -+ LIBDRM_RESOLV(FreeVersion), -+ LIBDRM_RESOLV(DropMaster), -+ LIBDRM_RESOLV(CommandWrite) -+}; -+ -+struct Udev1Interface *udevi = NULL; -+struct Drm2Interface *drmi = NULL; -+ -+static void *dlhandle; -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * resolutionDLClose -- -+ * -+ * Removes any dynamic library reference and frees any resource -+ * allocated by resolutionDLOpen. -+ * -+ * Side effects: -+ * None. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+void -+resolutionDLClose(void) -+{ -+ if (udevi) { -+ free(udevi); -+ udevi = NULL; -+ } -+ -+ if (drmi) { -+ free(drmi); -+ drmi = NULL; -+ } -+ -+ if (dlhandle) { -+ dlclose(dlhandle); -+ dlhandle = NULL; -+ } -+} -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * resolutionDLResolve -- -+ * -+ * Tries to open and resolve needed symbols of a single shared library. -+ * -+ * Results: -+ * If succesful returns zero, otherwise returns -1. -+ * -+ * Side effects: -+ * None. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+static int -+resolutionDLResolve(void **ptr, // OUT: pointer to -+ // function table. -+ size_t size, // IN: Size of ft. -+ const char name[], // IN: Library name. -+ const struct FuncToResolv table[], // IN: Table of name- -+ // offset pairs -+ int numEntries) // IN: Num entries in -+ // table. -+{ -+ void **func_ptr; -+ int i; -+ -+ if (*ptr) -+ return 0; -+ -+ *ptr = malloc(size); -+ if (!*ptr) -+ return -1; -+ -+ dlhandle = dlopen(name, RTLD_NOW); -+ if (!dlhandle) { -+ g_debug("%s: Failed to open shared library \"%s\".\n", __func__, -+ name); -+ goto out_err; -+ } -+ -+ for (i = 0; i < numEntries; ++i) { -+ func_ptr = (void *) ((unsigned long) *ptr + table[i].offset); -+ *func_ptr = dlsym(dlhandle, table[i].name); -+ if (!*func_ptr) { -+ g_debug("%s: Failed to resolve %s symbol \"%s\".\n", __func__, -+ name,table[i].name); -+ goto out_err; -+ } -+ } -+ -+ return 0; -+ -+ out_err: -+ resolutionDLClose(); -+ -+ return -1; -+} -+ -+/* -+ *----------------------------------------------------------------------------- -+ * -+ * resolutionDLOpen -- -+ * -+ * Tries to open and create a reference to distribution shared libraries -+ * needed for the resolutionKMS functionality. -+ * -+ * Results: -+ * If succesful returns zero, otherwise returns -1. -+ * -+ * Side effects: -+ * None. -+ * -+ *----------------------------------------------------------------------------- -+ */ -+int -+resolutionDLOpen(void) -+{ -+ /* We support libudev major versions 0 and 1 for now. */ -+ if (resolutionDLResolve((void **)&udevi, sizeof(*udevi), "libudev.so.1", -+ udev1Table, ARRAYSIZE(udev1Table)) && -+ resolutionDLResolve((void **)&udevi, sizeof(*udevi), "libudev.so.0", -+ udev1Table, ARRAYSIZE(udev1Table))) -+ return -1; -+ -+ if (resolutionDLResolve((void **)&drmi, sizeof(*drmi), "libdrm.so.2", -+ drm2Table, ARRAYSIZE(drm2Table))) -+ return -1; -+ -+ return 0; -+} -+ -+#endif /* !HAVE_LIBUDEV */ -+#endif /* ENABLE_RESOLUTIONKMS */ -diff --git a/services/plugins/resolutionSet/resolutionDL.h b/services/plugins/resolutionSet/resolutionDL.h -new file mode 100644 -index 0000000..f0d8c6d ---- /dev/null -+++ b/services/plugins/resolutionSet/resolutionDL.h -@@ -0,0 +1,217 @@ -+/********************************************************* -+ * Copyright (C) 2016 VMware, Inc. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Lesser General Public License as published -+ * by the Free Software Foundation version 2.1 and no later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public -+ * License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public License -+ * along with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ *********************************************************/ -+/* Authors: -+ * Thomas Hellstrom -+ */ -+ -+#ifndef _RESOLUTION_DL_H_ -+#define _RESOLUTION_DL_H_ -+#ifdef ENABLE_RESOLUTIONKMS -+ -+#define INCLUDE_ALLOW_USERLEVEL -+#define INCLUDE_ALLOW_DISTRIBUTE -+#include "includeCheck.h" -+ -+#ifndef HAVE_LIBUDEV -+ -+#include -+ -+struct udev; -+struct udev_device; -+struct udev_enumerate; -+ -+/* -+ * This struct holds the function pointers we use in libudev.1. Libudev is -+ * Lgpl 2.1 (or later) licensed, and according to lgpl 2.1, section 5, while -+ * we use materials copied from header files, we restrict ourselves to -+ * data structure layouts and small macros and thus, while this should be -+ * considered a derivative work, the use of the object file is unrestricted. -+ * An executable linked with libudev is however subject to lgpl license -+ * restrictions. -+ */ -+struct Udev1Interface { -+ const char * -+ (*_device_get_devnode)(struct udev_device *); -+ struct udev_device * -+ (*_device_get_parent_with_subsystem_devtype)(struct udev_device *, -+ const char *, const char *); -+ const char * -+ (*_device_get_sysattr_value)(struct udev_device *, const char *); -+ struct udev_device * -+ (*_device_new_from_syspath)(struct udev *, const char *); -+ struct udev_device * -+ (*_device_unref)(struct udev_device *); -+ int -+ (*_enumerate_add_match_property)(struct udev_enumerate *,const char *, -+ const char *); -+ int -+ (*_enumerate_add_match_subsystem)(struct udev_enumerate *,const char *); -+ struct udev_list_entry * -+ (*_enumerate_get_list_entry)(struct udev_enumerate *); -+ struct udev_enumerate * -+ (*_enumerate_new)(struct udev *udev); -+ int -+ (*_enumerate_scan_devices)(struct udev_enumerate *); -+ struct udev_enumerate * -+ (*_enumerate_unref)(struct udev_enumerate *); -+ const char * -+ (*_list_entry_get_name)(struct udev_list_entry *); -+ struct udev_list_entry * -+ (*_list_entry_get_next)(struct udev_list_entry *); -+ struct udev * -+ (*_new)(void); -+ struct udev * -+ (*_unref)(struct udev *); -+}; -+ -+#define udevi_list_entry_foreach(_udevi, list_entry, first_entry) \ -+ for (list_entry = first_entry; \ -+ list_entry != NULL; \ -+ list_entry = (_udevi)->_list_entry_get_next(list_entry)) -+ -+/* -+ * This struct is originally defined in xf86drm.h which is MIT licenced. -+ * However, this should not be considered a substantial part of the software, -+ * and this struct is not subject to the license header of this file. -+ */ -+typedef struct _drmVersion { -+ int version_major; /* Major version */ -+ int version_minor; /* Minor version */ -+ int version_patchlevel; /* Patch level */ -+ int name_len; /* Length of name buffer */ -+ char *name; /* Name of driver */ -+ int date_len; /* Length of date buffer */ -+ char *date; /* User-space buffer to hold date */ -+ int desc_len; /* Length of desc buffer */ -+ char *desc; /* User-space buffer to hold desc */ -+} drmVersion, *drmVersionPtr; -+ -+#define DRM_VMW_UPDATE_LAYOUT 20 -+ -+/* -+ * These structs are originally defined in vmwgfx_drm.h, which is dual -+ * MIT and GPLv2 licenced. However, VMWare Inc. owns the copyright and it's -+ * should not be considered a substantial part of the software. -+ * However this struct is not subject to the license header of this file. -+ */ -+/** -+ * struct drm_vmw_rect -+ * -+ * Defines a rectangle. Used in the overlay ioctl to define -+ * source and destination rectangle. -+ */ -+ -+struct drm_vmw_rect { -+ int32_t x; -+ int32_t y; -+ uint32_t w; -+ uint32_t h; -+}; -+ -+/** -+ * struct drm_vmw_update_layout_arg -+ * -+ * @num_outputs: number of active connectors -+ * @rects: pointer to array of drm_vmw_rect cast to an uint64_t -+ * -+ * Input argument to the DRM_VMW_UPDATE_LAYOUT Ioctl. -+ */ -+struct drm_vmw_update_layout_arg { -+ uint32_t num_outputs; -+ uint32_t pad64; -+ uint64_t rects; -+}; -+ -+/* -+ * This struct holds the function pointers we use in libdrm.2. The -+ * libdrm API is MIT licenced and what we do here should not be considered -+ * a substantial part of the software: -+ * However this struct is not subject to the license header of this file. -+ */ -+struct Drm2Interface { -+ drmVersionPtr (*GetVersion)(int fd); -+ void (*FreeVersion)(drmVersionPtr); -+ int (*DropMaster)(int fd); -+ int (*CommandWrite)(int fd, unsigned long drmCommandIndex, void *data, -+ unsigned long size); -+}; -+ -+extern struct Udev1Interface *udevi; -+extern struct Drm2Interface *drmi; -+ -+void resolutionDLClose(void); -+int resolutionDLOpen(void); -+ -+#define udev_device_get_devnode \ -+ udevi->_device_get_devnode -+#define udev_device_get_parent_with_subsystem_devtype \ -+ udevi->_device_get_parent_with_subsystem_devtype -+#define udev_device_get_sysattr_value \ -+ udevi->_device_get_sysattr_value -+#define udev_device_new_from_syspath \ -+ udevi->_device_new_from_syspath -+#define udev_device_unref \ -+ udevi->_device_unref -+#define udev_enumerate_add_match_property \ -+ udevi->_enumerate_add_match_property -+#define udev_enumerate_add_match_subsystem \ -+ udevi->_enumerate_add_match_subsystem -+#define udev_enumerate_get_list_entry \ -+ udevi->_enumerate_get_list_entry -+#define udev_enumerate_new \ -+ udevi->_enumerate_new -+#define udev_enumerate_scan_devices \ -+ udevi->_enumerate_scan_devices -+#define udev_enumerate_unref \ -+ udevi->_enumerate_unref -+#define udev_list_entry_get_name \ -+ udevi->_list_entry_get_name -+#define udev_list_entry_get_next \ -+ udevi->_list_entry_get_next -+#define udev_new \ -+ udevi->_new -+#define udev_unref \ -+ udevi->_unref -+#define udev_list_entry_foreach(_a, _b)\ -+ udevi_list_entry_foreach(udevi, _a, _b) -+ -+#define drmGetVersion \ -+ drmi->GetVersion -+#define drmFreeVersion \ -+ drmi->FreeVersion -+#define drmDropMaster \ -+ drmi->DropMaster -+#define drmCommandWrite \ -+ drmi->CommandWrite -+ -+#else /* HAVE_LIBUDEV */ -+ -+#include -+#include -+#include -+ -+/* Work around an incorrect define in old libdrm */ -+#undef DRM_VMW_UPDATE_LAYOUT -+#define DRM_VMW_UPDATE_LAYOUT 20 -+ -+static inline void resolutionDLClose(void) {} -+static inline int resolutionDLOpen(void) {return 0;} -+ -+#endif /* HAVE_LIBUDEV */ -+#endif /* ENABLE_RESOLUTIONKMS */ -+#endif -diff --git a/services/plugins/resolutionSet/resolutionInt.h b/services/plugins/resolutionSet/resolutionInt.h -index 55bb704..877a7bc 100644 ---- a/services/plugins/resolutionSet/resolutionInt.h -+++ b/services/plugins/resolutionSet/resolutionInt.h -@@ -74,13 +74,20 @@ typedef struct { - - extern ResolutionInfoType resolutionInfo; - -+#if defined(G_LOG_DOMAIN) -+#error Please include this file before glib.h -+#endif -+#define G_LOG_DOMAIN "resolutionSet" -+ -+#include "vmware/tools/plugin.h" -+ - /* - * Global functions - */ - - /* Functions defined by back-end. */ - Bool ResolutionBackendInit(InitHandle handle); --InitHandle ResolutionToolkitInit(void); -+InitHandle ResolutionToolkitInit(ToolsAppCtx *ctx); - void ResolutionBackendCleanup(void); - Bool ResolutionSetResolution(uint32 width, uint32 height); - #if defined(RESOLUTION_WIN32) -@@ -90,9 +97,4 @@ void ResolutionSetSessionChange(DWORD code, DWORD sessionID); - Bool ResolutionSetTopology(unsigned int ndisplays, DisplayTopologyInfo displays[]); - Bool ResolutionSetTopologyModes(unsigned int screen, unsigned int cmd, unsigned int ndisplays, DisplayTopologyInfo displays[]); - --#if defined(G_LOG_DOMAIN) --#error Please include this file before glib.h --#endif --#define G_LOG_DOMAIN "resolutionSet" -- - #endif // ifndef _LIB_RESOLUTIONINT_H_ -diff --git a/services/plugins/resolutionSet/resolutionSet.c b/services/plugins/resolutionSet/resolutionSet.c -index 96c8349..52e0c5b 100644 ---- a/services/plugins/resolutionSet/resolutionSet.c -+++ b/services/plugins/resolutionSet/resolutionSet.c -@@ -584,9 +584,10 @@ ToolsOnLoad(ToolsAppCtx *ctx) - /* - * XXX move to some shared lib or plugin - */ -- handle = ResolutionToolkitInit(); -+ handle = ResolutionToolkitInit(ctx); - -- ResolutionInit(handle); -+ if (!ResolutionInit(handle)) -+ return NULL; - - regs[0].data = VMTools_WrapArray(rpcs, sizeof *rpcs, ARRAYSIZE(rpcs)); - regData.regs = VMTools_WrapArray(regs, sizeof *regs, ARRAYSIZE(regs)); -diff --git a/services/plugins/resolutionSet/resolutionX11.c b/services/plugins/resolutionSet/resolutionX11.c -index 3c5c120..ae42617 100644 ---- a/services/plugins/resolutionSet/resolutionX11.c -+++ b/services/plugins/resolutionSet/resolutionX11.c -@@ -45,6 +45,7 @@ - #include "strutil.h" - #include "util.h" - #include "posix.h" -+#include "resolutionCommon.h" - - #define VMWAREDRV_PATH_64 "/usr/X11R6/lib64/modules/drivers/vmware_drv.o" - #define VMWAREDRV_PATH "/usr/X11R6/lib/modules/drivers/vmware_drv.o" -@@ -105,8 +106,9 @@ ResolutionBackendInit(InitHandle handle) - resInfoX->display = handle; - - if (resInfoX->display == NULL) { -- g_warning("%s: Called with invalid X display!\n", __func__); -- return FALSE; -+ resInfo->canSetResolution = FALSE; -+ resInfo->canSetTopology = FALSE; -+ return TRUE; - } - - resInfoX->display = handle; -@@ -335,15 +337,10 @@ static Bool - ResolutionCanSet(void) - { - ResolutionInfoX11Type *resInfoX = &resolutionInfoX11; -- int fd = -1; -- off_t filePos = 0; -- Bool keepSearching = TRUE; -- Bool found = FALSE; -- char buf[sizeof VERSION_STRING + 10]; // size of VERSION_STRING plus some extra for the version number -- const char versionString[] = VERSION_STRING; -- ssize_t bytesRead; -- int32 major, minor, level; -- unsigned int tokPos; -+ int major, minor, level; -+ static const char *driverPaths[] = { -+ VMWAREDRV_PATH_64, -+ VMWAREDRV_PATH}; - - /* See if the randr X module is loaded */ - if (!XRRQueryVersion(resInfoX->display, &major, &minor) ) { -@@ -411,55 +408,9 @@ ResolutionCanSet(void) - * 6.9/7.0, we can instead just use the VMWARE_CTRL check. - */ - -- buf[sizeof buf - 1] = '\0'; -- fd = Posix_Open(VMWAREDRV_PATH_64, O_RDONLY); -- if (fd == -1) { -- fd = Posix_Open(VMWAREDRV_PATH, O_RDONLY); -- } -- if (fd != -1) { -- /* -- * One of the opens succeeded, so start searching thru the file. -- */ -- while (keepSearching) { -- bytesRead = read(fd, buf, sizeof buf - 1); -- if (bytesRead == -1 || bytesRead < sizeof buf -1 ) { -- keepSearching = FALSE; -- } else { -- if (Str_Strncmp(versionString, buf, sizeof versionString - 1) == 0) { -- keepSearching = FALSE; -- found = TRUE; -- } -- } -- filePos = lseek(fd, filePos+1, SEEK_SET); -- if (filePos == -1) { -- keepSearching = FALSE; -- } -- } -- close(fd); -- if (found) { -- /* -- * We NUL-terminated buf earlier, but Coverity really wants it to -- * be NUL-terminated after the call to read (because -- * read doesn't NUL-terminate). So we'll do it again. -- */ -- buf[sizeof buf - 1] = '\0'; -- -- /* -- * Try and parse the major, minor and level versions -- */ -- tokPos = sizeof versionString - 1; -- if (!StrUtil_GetNextIntToken(&major, &tokPos, buf, ".- ")) { -- return FALSE; -- } -- if (!StrUtil_GetNextIntToken(&minor, &tokPos, buf, ".- ")) { -- return FALSE; -- } -- if (!StrUtil_GetNextIntToken(&level, &tokPos, buf, ".- ")) { -- return FALSE; -- } -- -- return ((major > 10) || (major == 10 && minor >= 11)); -- } -+ if (!resolutionXorgDriverVersion(2, driverPaths, VERSION_STRING, -+ &major, &minor, &level)) { -+ return ((major > 10) || (major == 10 && minor >= 11)); - } - return FALSE; - } -@@ -633,12 +584,20 @@ ResolutionX11ErrorHandler(Display *d, // IN: Pointer to display connection - */ - - InitHandle --ResolutionToolkitInit(void) -+ResolutionToolkitInit(ToolsAppCtx *ctx) // IN: For config database access - { - int argc = 1; - char *argv[] = {"", NULL}; - GtkWidget *wnd; - Display *display; -+ int fd; -+ -+ fd = resolutionCheckForKMS(ctx); -+ if (fd >= 0) { -+ resolutionDRMClose(fd); -+ g_message("%s: Backing off for resolutionKMS.\n", __func__); -+ return (InitHandle) 0; -+ } - - XSetErrorHandler(ResolutionX11ErrorHandler); - gtk_init(&argc, (char ***) &argv); -@@ -648,5 +607,9 @@ ResolutionToolkitInit(void) - #else - display = GDK_WINDOW_XDISPLAY(gtk_widget_get_window(wnd)); - #endif -+ -+ if (!display) -+ g_error("%s: Invalid display detected.\n", __func__); -+ - return (InitHandle) display; - } diff --git a/sources b/sources index e8db5b3..9a65af2 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (open-vm-tools-10.1.10-6082533.tar.gz) = 60c52a24509cb0630f2ad649fe6717fefff624fc2a5c736ced35cbdb8f639264d482e063e8140eedb39216adfb1231d58232bfef0233ebc477ba4f9a732c5965 +SHA512 (open-vm-tools-10.2.0-7253323.tar.gz) = b54a54685e6863f275966bda26317e181b121b7682980ee4fa376df50156fff4d7b577f025b46ab51669a17b1c1b269474e75374229d5041cca355a908f9565b