From 067031a3b3036670ccc858be732264215a7d14ba Mon Sep 17 00:00:00 2001
From: Ulrich Sibiller <uli42@gmx.de>
Date: Sat, 15 Feb 2020 23:50:03 +0100
Subject: nxagent: use Xorg's callback mechanism for init/free of client
 privates

---
 nx-X11/programs/Xserver/dix/dispatch.c          |  4 --
 nx-X11/programs/Xserver/hw/nxagent/Client.c     | 76 ++++++++++++++++++++++++-
 nx-X11/programs/Xserver/hw/nxagent/Client.h     |  2 +-
 nx-X11/programs/Xserver/hw/nxagent/Init.c       |  6 ++
 nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c | 23 +-------
 5 files changed, 83 insertions(+), 28 deletions(-)

diff --git a/nx-X11/programs/Xserver/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c
index cd832319d..ac5d07281 100644
--- a/nx-X11/programs/Xserver/dix/dispatch.c
+++ b/nx-X11/programs/Xserver/dix/dispatch.c
@@ -3642,11 +3642,7 @@ void InitClient(ClientPtr client, int i, void * ospriv)
 }
 
 int
-#ifdef NXAGENT_SERVER
-xorg_InitClientPrivates(ClientPtr client)
-#else
 InitClientPrivates(ClientPtr client)
-#endif
 {
     register char *ptr;
     DevUnion *ppriv;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.c b/nx-X11/programs/Xserver/hw/nxagent/Client.c
index 1e4182599..020f90c91 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Client.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.c
@@ -68,6 +68,10 @@
 #undef  TEST
 #undef  DEBUG
 
+void nxagentClientStateCallback(CallbackListPtr *callbacks, void *data, void *args);
+static void initClientPrivates(ClientPtr client);
+static void freeClientPrivates(ClientPtr client);
+
 /*
  * Returns the last signal delivered to the process.
  */
@@ -106,8 +110,78 @@ int nxagentClientPrivateIndex;
 
 int nxagentShadowCounter = 0;
 
-void nxagentInitClientPrivates(ClientPtr client)
+/*
+ * called whenever the client state changes. See dixstruct.h for a
+ * list of known states.
+ */
+
+#ifdef DEBUG
+const char * getClientStateString(int state)
+{
+  switch (state)
+  {
+    case ClientStateInitial:          { return "Initial"; break; };
+    case ClientStateAuthenticating:   { return "Authenticating"; break; };
+    case ClientStateRunning:          { return "Running"; break; };
+    case ClientStateRetained:         { return "Retained"; break; };
+    case ClientStateGone:             { return "Gone"; break; };
+    case ClientStateCheckingSecurity: { return "CheckingSecurity"; break; };
+    case ClientStateCheckedSecurity:  { return "CheckedSecurity"; break; };
+    default:                          { return "UNKNOWN"; break; };
+  }
+}
+#endif
+
+void nxagentClientStateCallback(CallbackListPtr *callbacks, void *data, void *args)
+{
+  ClientPtr client = ((NewClientInfoRec *)args)->client;
+
+  #ifdef DEBUG
+  fprintf(stderr, "%s: client [%d] clientState [%s]\n", __func__, client->index,
+              getClientStateString(client->clientState));
+  #endif
+
+  switch(client->clientState)
+  {
+    case ClientStateInitial:
+    {
+      initClientPrivates(client);
+      break;
+    }
+    case ClientStateGone:
+    {
+      freeClientPrivates(client);
+      break;
+    }
+    default:
+    {
+      break;
+    }
+  }
+}
+
+static void initClientPrivates(ClientPtr client)
 {
+  #ifdef DEBUG
+  fprintf(stderr, "%s: called\n", __func__);
+  #endif
+
+  if (nxagentClientPriv(client))
+  {
+    nxagentClientPriv(client) -> clientState = 0;
+#ifdef COUNT_CLIENT_BYTES
+    nxagentClientPriv(client) -> clientBytes = 0;
+#endif
+    nxagentClientPriv(client) -> clientHint  = UNKNOWN;
+  }
+}
+
+static void freeClientPrivates(ClientPtr client)
+{
+  #ifdef DEBUG
+  fprintf(stderr, "%s: called\n", __func__);
+  #endif
+
   if (nxagentClientPriv(client))
   {
     nxagentClientPriv(client) -> clientState = 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.h b/nx-X11/programs/Xserver/hw/nxagent/Client.h
index 094e45257..2115e6b6d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Client.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.h
@@ -57,7 +57,7 @@ extern int nxagentClientPrivateIndex;
 #define nxagentClientPriv(pClient) \
   ((PrivClientRec *)((pClient)->devPrivates[nxagentClientPrivateIndex].ptr))
 
-void nxagentInitClientPrivates(ClientPtr);
+extern void nxagentClientStateCallback(CallbackListPtr *callbacks, void *data, void *args);
 
 #undef COUNT_CLIENT_BYTES
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c
index b4d8a270c..804c8c43b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.c
@@ -54,6 +54,7 @@ is" without express or implied warranty.
 #include "mi.h"
 #include <X11/fonts/fontstruct.h>
 #include "dixfontstr.h"
+#include "dixstruct.h"
 
 #include "Agent.h"
 #include "Display.h"
@@ -74,6 +75,7 @@ is" without express or implied warranty.
 #include "Error.h"
 #include "Keystroke.h"
 #include "Atoms.h"
+#include "Client.h"
 
 #include <nx/NX.h>
 #include "compext/Compext.h"
@@ -386,9 +388,13 @@ FIXME: These variables, if not removed at all because have probably
   nxagentInitKeystrokes(False);
 
 #ifdef NXAGENT_CLIPBOARD
+  /* FIXME: we need to call DeleteCallback at shutdown, but where? */
   AddCallback(&SelectionCallback, nxagentSetSelectionCallback, NULL);
 #endif
 
+  /* FIXME: we need to call DeleteCallback at shutdown, but where? */
+  AddCallback(&ClientStateCallback, nxagentClientStateCallback, NULL);
+
   nxagentInitAtoms();
 }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
index dc3b2dcd9..58dd71f60 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
@@ -1009,29 +1009,8 @@ CloseDownClient(register ClientPtr client)
      */
 
     nxagentCheckIfShadowAgent(client);
-#endif
-
-    xorg_CloseDownClient(client);
-}
 
-/* FIXME: Instead of having a own function use the provided Callback
-   mechanism */
-int
-InitClientPrivates(ClientPtr client)
-{
-    int ret = xorg_InitClientPrivates(client);
-
-#ifdef NXAGENT_SERVER
-    if (ret == 1)
-    {
-
-      /*
-       * Initialize the private members.
-       */
-
-      nxagentInitClientPrivates(client);
-    }
 #endif
 
-    return ret;
+    xorg_CloseDownClient(client);
 }
-- 
cgit v1.2.3