diff --git a/Xext/namespace/config.c b/Xext/namespace/config.c new file mode 100644 index 000000000..424b9c1f1 --- /dev/null +++ b/Xext/namespace/config.c @@ -0,0 +1,39 @@ +#include + +#include +#include + +#include "namespace.h" + +struct Xnamespace ns_root = { + .builtin = TRUE, + .name = NS_NAME_ROOT, + .refcnt = 1, + .superPower = TRUE, +}; + +struct Xnamespace ns_anon = { + .builtin = TRUE, + .name = NS_NAME_ANONYMOUS, + .refcnt = 1, +}; + +struct xorg_list ns_list = { 0 }; + +Bool XnsLoadConfig(void) +{ + xorg_list_init(&ns_list); + xorg_list_add(&ns_root.entry, &ns_list); + xorg_list_add(&ns_anon.entry, &ns_list); + + return TRUE; +} + +struct Xnamespace *XnsFindByName(const char* name) { + struct Xnamespace *walk; + xorg_list_for_each_entry(walk, &ns_list, entry) { + if (strcmp(walk->name, name)==0) + return walk; + } + return NULL; +} diff --git a/Xext/namespace/meson.build b/Xext/namespace/meson.build index f8ce18fe8..78dd9f1cb 100644 --- a/Xext/namespace/meson.build +++ b/Xext/namespace/meson.build @@ -1,6 +1,7 @@ libxserver_namespace = static_library( 'libxserver_namespace', [ + 'config.c', 'namespace.c', ], include_directories: inc, diff --git a/Xext/namespace/namespace.c b/Xext/namespace/namespace.c index 3a74e592a..26e81df07 100644 --- a/Xext/namespace/namespace.c +++ b/Xext/namespace/namespace.c @@ -1,7 +1,9 @@ #include +#include #include +#include "dix/dix_priv.h" #include "include/os.h" #include "miext/extinit_priv.h" @@ -9,8 +11,46 @@ Bool noNamespaceExtension = TRUE; +DevPrivateKeyRec namespaceClientPrivKeyRec = { 0 }; + void NamespaceExtensionInit(void) { XNS_LOG("initializing namespace extension ...\n"); + + /* load configuration */ + if (!XnsLoadConfig()) { + XNS_LOG("No config file. disabling Xns extension\n"); + return; + } + + if (!dixRegisterPrivateKey + (&namespaceClientPrivKeyRec, PRIVATE_CLIENT, sizeof(struct XnamespaceClientPriv))) + FatalError("NamespaceExtensionInit: allocation failure\n"); + + /* Do the serverClient */ + struct XnamespaceClientPriv *srv = XnsClientPriv(serverClient); + *srv = (struct XnamespaceClientPriv) { .isServer = TRUE }; + XnamespaceAssignClient(srv, &ns_root); +} + +void XnamespaceAssignClient(struct XnamespaceClientPriv *priv, struct Xnamespace *newns) +{ + if (priv->ns != NULL) + priv->ns->refcnt--; + + priv->ns = newns; + + if (newns != NULL) + newns->refcnt++; +} + +void XnamespaceAssignClientByName(struct XnamespaceClientPriv *priv, const char *name) +{ + struct Xnamespace *newns = XnsFindByName(name); + + if (newns == NULL) + newns = &ns_anon; + + XnamespaceAssignClient(priv, newns); } diff --git a/Xext/namespace/namespace.h b/Xext/namespace/namespace.h index 96a307bb4..93549eb31 100644 --- a/Xext/namespace/namespace.h +++ b/Xext/namespace/namespace.h @@ -4,6 +4,53 @@ #include #include +#include "include/dixstruct.h" +#include "include/list.h" +#include "include/privates.h" +#include "include/window.h" + +struct Xnamespace { + struct xorg_list entry; + const char *name; + Bool builtin; + Bool superPower; + size_t refcnt; +}; + +extern struct xorg_list ns_list; +extern struct Xnamespace ns_root; +extern struct Xnamespace ns_anon; + +struct XnamespaceClientPriv { + Bool isServer; + XID authId; + struct Xnamespace* ns; +}; + +#define NS_NAME_ROOT "root" +#define NS_NAME_ANONYMOUS "anon" + +extern DevPrivateKeyRec namespaceClientPrivKeyRec; + +Bool XnsLoadConfig(void); +struct Xnamespace *XnsFindByName(const char* name); +void XnamespaceAssignClient(struct XnamespaceClientPriv *priv, struct Xnamespace *ns); +void XnamespaceAssignClientByName(struct XnamespaceClientPriv *priv, const char *name); + +static inline struct XnamespaceClientPriv *XnsClientPriv(ClientPtr client) { + if (client == NULL) return NULL; + return dixLookupPrivate(&client->devPrivates, &namespaceClientPrivKeyRec); +} + +static inline Bool XnsClientSameNS(struct XnamespaceClientPriv *p1, struct XnamespaceClientPriv *p2) +{ + if (!p1 && !p2) + return TRUE; + if (!p1 || !p2) + return FALSE; + return (p1->ns == p2->ns); +} + #define XNS_LOG(...) do { printf("XNS "); printf(__VA_ARGS__); } while (0) static inline Bool streq(const char *a, const char *b) diff --git a/dix/privates.c b/dix/privates.c index 846ddd9c3..5d6018c4a 100644 --- a/dix/privates.c +++ b/dix/privates.c @@ -109,6 +109,7 @@ static const char *key_names[PRIVATE_LAST] = { [PRIVATE_GLYPHSET] = "GLYPHSET", [PRIVATE_PICTURE] = "PICTURE", [PRIVATE_SYNC_FENCE] = "SYNC_FENCE", + [PRIVATE_NAMESPACE] = "NAMESPACE", }; static const Bool screen_specific_private[PRIVATE_LAST] = { diff --git a/include/privates.h b/include/privates.h index 394e3d685..743afb11e 100644 --- a/include/privates.h +++ b/include/privates.h @@ -51,6 +51,7 @@ typedef enum { PRIVATE_GLYPHSET, PRIVATE_PICTURE, PRIVATE_SYNC_FENCE, + PRIVATE_NAMESPACE, /* last private type */ PRIVATE_LAST,