Xnamespace: create per-namespace fake root windows
For each namespace creating a fake (invisible) root window, which can be used for storing per-namespace properties (eg. cut buffers), etc. Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
parent
5901cb001d
commit
159183c8a0
|
@ -0,0 +1,71 @@
|
||||||
|
#define HOOK_NAME "initroot"
|
||||||
|
|
||||||
|
#include <dix-config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/Xmd.h>
|
||||||
|
|
||||||
|
#include "dix/window_priv.h"
|
||||||
|
|
||||||
|
#include "namespace.h"
|
||||||
|
#include "hooks.h"
|
||||||
|
|
||||||
|
static inline int setWinStrProp(WindowPtr pWin, Atom name, const char *text) {
|
||||||
|
return dixChangeWindowProperty(serverClient, pWin, name, XA_STRING,
|
||||||
|
8, PropModeReplace, strlen(text), text, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hookInitRootWindow(CallbackListPtr *pcbl, void *data, void *screen)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = (ScreenPtr)screen;
|
||||||
|
|
||||||
|
// only act on first screen
|
||||||
|
if (pScreen->myNum)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* create the virtual root windows */
|
||||||
|
WindowPtr realRoot = pScreen->root;
|
||||||
|
|
||||||
|
assert(realRoot);
|
||||||
|
|
||||||
|
struct Xnamespace *walk;
|
||||||
|
|
||||||
|
xorg_list_for_each_entry(walk, &ns_list, entry) {
|
||||||
|
if (strcmp(walk->name, NS_NAME_ROOT)==0) {
|
||||||
|
walk->rootWindow = realRoot;
|
||||||
|
XNS_LOG("<%s> actual root 0x%0x\n", walk->name, walk->rootWindow->drawable.id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc = 0;
|
||||||
|
WindowPtr pWin = dixCreateWindow(
|
||||||
|
FakeClientID(0), realRoot, 0, 0, 23, 23,
|
||||||
|
0, /* bw */
|
||||||
|
InputOutput,
|
||||||
|
0, /* vmask */
|
||||||
|
NULL, /* vlist */
|
||||||
|
0, /* depth */
|
||||||
|
serverClient,
|
||||||
|
wVisual(realRoot), /* visual */
|
||||||
|
&rc);
|
||||||
|
|
||||||
|
if (!pWin)
|
||||||
|
FatalError("hookInitRootWindow: cant create per-namespace root window for %s\n", walk->name);
|
||||||
|
|
||||||
|
Mask mask = pWin->eventMask;
|
||||||
|
pWin->eventMask = 0; /* subterfuge in case AddResource fails */
|
||||||
|
if (!AddResource(pWin->drawable.id, X11_RESTYPE_WINDOW, (void *) pWin))
|
||||||
|
FatalError("hookInitRootWindow: cant add per-namespace root window as resource\n");
|
||||||
|
pWin->eventMask = mask;
|
||||||
|
|
||||||
|
walk->rootWindow = pWin;
|
||||||
|
|
||||||
|
// set window name
|
||||||
|
char buf[PATH_MAX] = { 0 };
|
||||||
|
snprintf(buf, sizeof(buf)-1, "XNS-ROOT:%s", walk->name);
|
||||||
|
setWinStrProp(pWin, XA_WM_NAME, buf);
|
||||||
|
|
||||||
|
XNS_LOG("<%s> virtual root 0x%0x\n", walk->name, walk->rootWindow->drawable.id);
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@
|
||||||
struct XnamespaceClientPriv *subj = XnsClientPriv(client);
|
struct XnamespaceClientPriv *subj = XnsClientPriv(client);
|
||||||
|
|
||||||
void hookClientState(CallbackListPtr *pcbl, void *unused, void *calldata);
|
void hookClientState(CallbackListPtr *pcbl, void *unused, void *calldata);
|
||||||
|
void hookInitRootWindow(CallbackListPtr *pcbl, void *unused, void *calldata);
|
||||||
void hookSelectionFilter(CallbackListPtr *pcbl, void *unused, void *calldata);
|
void hookSelectionFilter(CallbackListPtr *pcbl, void *unused, void *calldata);
|
||||||
|
|
||||||
#endif /* __XSERVER_NAMESPACE_HOOKS_H */
|
#endif /* __XSERVER_NAMESPACE_HOOKS_H */
|
||||||
|
|
|
@ -3,6 +3,7 @@ libxserver_namespace = static_library(
|
||||||
[
|
[
|
||||||
'config.c',
|
'config.c',
|
||||||
'hook-clientstate.c',
|
'hook-clientstate.c',
|
||||||
|
'hook-init-rootwindow.c',
|
||||||
'hook-selection.c',
|
'hook-selection.c',
|
||||||
'namespace.c',
|
'namespace.c',
|
||||||
],
|
],
|
||||||
|
|
|
@ -29,6 +29,7 @@ NamespaceExtensionInit(void)
|
||||||
if (!(dixRegisterPrivateKey(&namespaceClientPrivKeyRec, PRIVATE_CLIENT,
|
if (!(dixRegisterPrivateKey(&namespaceClientPrivKeyRec, PRIVATE_CLIENT,
|
||||||
sizeof(struct XnamespaceClientPriv)) &&
|
sizeof(struct XnamespaceClientPriv)) &&
|
||||||
AddCallback(&ClientStateCallback, hookClientState, NULL) &&
|
AddCallback(&ClientStateCallback, hookClientState, NULL) &&
|
||||||
|
AddCallback(&PostInitRootWindowCallback, hookInitRootWindow, NULL) &&
|
||||||
AddCallback(&SelectionFilterCallback, hookSelectionFilter, NULL)))
|
AddCallback(&SelectionFilterCallback, hookSelectionFilter, NULL)))
|
||||||
FatalError("NamespaceExtensionInit: allocation failure\n");
|
FatalError("NamespaceExtensionInit: allocation failure\n");
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "include/list.h"
|
#include "include/list.h"
|
||||||
#include "include/privates.h"
|
#include "include/privates.h"
|
||||||
#include "include/window.h"
|
#include "include/window.h"
|
||||||
|
#include "include/windowstr.h"
|
||||||
|
|
||||||
struct Xnamespace {
|
struct Xnamespace {
|
||||||
struct xorg_list entry;
|
struct xorg_list entry;
|
||||||
|
@ -18,6 +19,7 @@ struct Xnamespace {
|
||||||
char *authTokenData;
|
char *authTokenData;
|
||||||
size_t authTokenLen;
|
size_t authTokenLen;
|
||||||
size_t refcnt;
|
size_t refcnt;
|
||||||
|
WindowPtr rootWindow;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct xorg_list ns_list;
|
extern struct xorg_list ns_list;
|
||||||
|
|
Loading…
Reference in New Issue