Blame SOURCES/resolutionKMS-wayland-2.patch

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