dix: split off PropertyRec's data field to separate record

Doing it the same way several extensions (eg. XI and randr) do it,
so we can consolidate things here.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult 2025-05-15 19:03:20 +02:00
parent 04cd1ac05a
commit 611055db8d
8 changed files with 92 additions and 65 deletions

View File

@ -123,10 +123,10 @@ static void
notifyVRRMode(ClientPtr pClient, WindowPtr pWindow, int state, PropertyPtr pProp) notifyVRRMode(ClientPtr pClient, WindowPtr pWindow, int state, PropertyPtr pProp)
{ {
const char *pName = NameForAtom(pProp->propertyName); const char *pName = NameForAtom(pProp->propertyName);
if (pName == NULL || strcmp(pName, "_VARIABLE_REFRESH") || pProp->format != 32 || pProp->size != 1) if (pName == NULL || strcmp(pName, "_VARIABLE_REFRESH") || pProp->value.format != 32 || pProp->value.size != 1)
return; return;
WindowVRRMode mode = (WindowVRRMode)(state == PropertyNewValue ? (*((uint32_t*)pProp->data)) : 0); WindowVRRMode mode = (WindowVRRMode)(state == PropertyNewValue ? (*((uint32_t*)pProp->value.data)) : 0);
#ifdef XINERAMA #ifdef XINERAMA
if (!noPanoramiXExtension) { if (!noPanoramiXExtension) {
@ -241,10 +241,10 @@ ProcRotateProperties(ClientPtr client)
notifyVRRMode(client, pWin, PropertyNewValue, props[i]); notifyVRRMode(client, pWin, PropertyNewValue, props[i]);
/* Preserve name and devPrivates */ /* Preserve name and devPrivates */
props[j]->type = saved[i].type; props[j]->value.type = saved[i].value.type;
props[j]->format = saved[i].format; props[j]->value.format = saved[i].value.format;
props[j]->size = saved[i].size; props[j]->value.size = saved[i].value.size;
props[j]->data = saved[i].data; props[j]->value.data = saved[i].value.data;
} }
} }
out: out:
@ -360,9 +360,9 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
existing format and type are irrelevant when using the mode existing format and type are irrelevant when using the mode
"PropModeReplace" since they will be written over. */ "PropModeReplace" since they will be written over. */
if ((format != pProp->format) && (mode != PropModeReplace)) if ((format != pProp->value.format) && (mode != PropModeReplace))
return BadMatch; return BadMatch;
if ((pProp->type != type) && (mode != PropModeReplace)) if ((pProp->value.type != type) && (mode != PropModeReplace))
return BadMatch; return BadMatch;
/* save the old values for later */ /* save the old values for later */
@ -375,43 +375,43 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
return BadAlloc; return BadAlloc;
memcpy(data, value, totalSize); memcpy(data, value, totalSize);
} }
pProp->data = data; pProp->value.data = data;
pProp->size = len; pProp->value.size = len;
pProp->type = type; pProp->value.type = type;
pProp->format = format; pProp->value.format = format;
} }
else if (len == 0) { else if (len == 0) {
/* do nothing */ /* do nothing */
} }
else if (mode == PropModeAppend) { else if (mode == PropModeAppend) {
unsigned char *data = calloc(pProp->size + len, sizeInBytes); unsigned char *data = calloc(pProp->value.size + len, sizeInBytes);
if (!data) if (!data)
return BadAlloc; return BadAlloc;
memcpy(data, pProp->data, pProp->size * sizeInBytes); memcpy(data, pProp->value.data, pProp->value.size * sizeInBytes);
memcpy(data + pProp->size * sizeInBytes, value, totalSize); memcpy(data + pProp->value.size * sizeInBytes, value, totalSize);
pProp->data = data; pProp->value.data = data;
pProp->size += len; pProp->value.size += len;
} }
else if (mode == PropModePrepend) { else if (mode == PropModePrepend) {
unsigned char *data = calloc(len + pProp->size, sizeInBytes); unsigned char *data = calloc(len + pProp->value.size, sizeInBytes);
if (!data) if (!data)
return BadAlloc; return BadAlloc;
memcpy(data + totalSize, pProp->data, pProp->size * sizeInBytes); memcpy(data + totalSize, pProp->value.data, pProp->value.size * sizeInBytes);
memcpy(data, value, totalSize); memcpy(data, value, totalSize);
pProp->data = data; pProp->value.data = data;
pProp->size += len; pProp->value.size += len;
} }
/* Allow security modules to check the new content */ /* Allow security modules to check the new content */
access_mode |= DixPostAccess; access_mode |= DixPostAccess;
rc = XaceHookPropertyAccess(pClient, pWin, &pProp, access_mode); rc = XaceHookPropertyAccess(pClient, pWin, &pProp, access_mode);
if (rc == Success) { if (rc == Success) {
if (savedProp.data != pProp->data) if (savedProp.value.data != pProp->value.data)
free(savedProp.data); free(savedProp.value.data);
} }
else { else {
if (savedProp.data != pProp->data) if (savedProp.value.data != pProp->value.data)
free(pProp->data); free(pProp->value.data);
*pProp = savedProp; *pProp = savedProp;
return rc; return rc;
} }
@ -539,13 +539,13 @@ ProcGetProperty(ClientPtr client)
/* If the request type and actual type don't match. Return the /* If the request type and actual type don't match. Return the
property information, but not the data. */ property information, but not the data. */
if (((p.type != pProp->type) && (p.type != AnyPropertyType))) { if (((p.type != pProp->value.type) && (p.type != AnyPropertyType))) {
xGetPropertyReply rep = { xGetPropertyReply rep = {
.type = X_Reply, .type = X_Reply,
.sequenceNumber = client->sequence, .sequenceNumber = client->sequence,
.bytesAfter = pProp->size, .bytesAfter = pProp->value.size,
.format = pProp->format, .format = pProp->value.format,
.propertyType = pProp->type .propertyType = pProp->value.type
}; };
if (client->swapped) { if (client->swapped) {
swaps(&rep.sequenceNumber); swaps(&rep.sequenceNumber);
@ -559,7 +559,7 @@ ProcGetProperty(ClientPtr client)
/* /*
* Return type, format, value to client * Return type, format, value to client
*/ */
n = (pProp->format / 8) * pProp->size; /* size (bytes) of prop */ n = (pProp->value.format / 8) * pProp->value.size; /* size (bytes) of prop */
ind = p.longOffset << 2; ind = p.longOffset << 2;
/* If longOffset is invalid such that it causes "len" to /* If longOffset is invalid such that it causes "len" to
@ -576,10 +576,10 @@ ProcGetProperty(ClientPtr client)
.type = X_Reply, .type = X_Reply,
.sequenceNumber = client->sequence, .sequenceNumber = client->sequence,
.bytesAfter = n - (ind + len), .bytesAfter = n - (ind + len),
.format = pProp->format, .format = pProp->value.format,
.length = bytes_to_int32(len), .length = bytes_to_int32(len),
.nItems = len / (pProp->format / 8), .nItems = len / (pProp->value.format / 8),
.propertyType = pProp->type .propertyType = pProp->value.type
}; };
if (p.delete && (rep.bytesAfter == 0)) { if (p.delete && (rep.bytesAfter == 0)) {
@ -590,7 +590,7 @@ ProcGetProperty(ClientPtr client)
void *payload = calloc(1, len); void *payload = calloc(1, len);
if (!payload) if (!payload)
return BadAlloc; return BadAlloc;
memcpy(payload, (char*)(pProp->data) + ind, len); memcpy(payload, (char*)(pProp->value.data) + ind, len);
if (p.delete && (rep.bytesAfter == 0)) { if (p.delete && (rep.bytesAfter == 0)) {
/* Delete the Property */ /* Delete the Property */

View File

@ -12,7 +12,7 @@
void dixPropertyFree(PropertyPtr pr) void dixPropertyFree(PropertyPtr pr)
{ {
if (pr) { if (pr) {
free(pr->data); free(pr->value.data);
dixFreeObjectWithPrivates(pr, PRIVATE_PROPERTY); dixFreeObjectWithPrivates(pr, PRIVATE_PROPERTY);
} }
} }
@ -34,11 +34,11 @@ PropertyPtr dixPropertyCreate(Atom type, Atom name, int format, size_t len,
memcpy(data, value, totalSize); memcpy(data, value, totalSize);
pProp->data = data;
pProp->propertyName = name; pProp->propertyName = name;
pProp->format = format; pProp->value.data = data;
pProp->size = len; pProp->value.format = format;
pProp->type = type; pProp->value.size = len;
pProp->value.type = type;
return pProp; return pProp;
} }

View File

@ -200,10 +200,10 @@ get_window_name(WindowPtr pWin)
return overlay_win_name; return overlay_win_name;
for (prop = pWin->properties; prop; prop = prop->next) { for (prop = pWin->properties; prop; prop = prop->next) {
if (prop->propertyName == XA_WM_NAME && prop->type == XA_STRING && if (prop->propertyName == XA_WM_NAME &&
prop->data) { prop->value.type == XA_STRING && prop->value.data) {
len = min(prop->size, WINDOW_NAME_BUF_LEN - 1); len = min(prop->value.size, WINDOW_NAME_BUF_LEN - 1);
memcpy(buf, prop->data, len); memcpy(buf, prop->value.data, len);
buf[len] = '\0'; buf[len] = '\0';
return buf; return buf;
} }

View File

@ -265,6 +265,9 @@ cat > sdksyms.c << EOF
#include "xkbrules.h" #include "xkbrules.h"
#include "xserver-properties.h" #include "xserver-properties.h"
// new SDK files
#include "property_value.h"
EOF EOF
topdir=$(readlink -f $1) topdir=$(readlink -f $1)

View File

@ -60,13 +60,14 @@ winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class)
while (prop) { while (prop) {
if (prop->propertyName == XA_WM_CLASS if (prop->propertyName == XA_WM_CLASS
&& prop->type == XA_STRING && prop->format == 8 && prop->data) { && prop->value.type == XA_STRING
&& prop->value.format == 8 && prop->value.data) {
/* /*
WM_CLASS property should consist of 2 null terminated strings, but we WM_CLASS property should consist of 2 null terminated strings, but we
must handle the cases when one or both is absent or not null terminated must handle the cases when one or both is absent or not null terminated
*/ */
len_name = strlen((char *) prop->data); len_name = strlen((char *) prop->value.data);
if (len_name > prop->size) len_name = prop->size; if (len_name > prop->value.size) len_name = prop->value.size;
(*res_name) = calloc(1, len_name + 1); (*res_name) = calloc(1, len_name + 1);
@ -76,12 +77,12 @@ winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class)
} }
/* Copy name and ensure null terminated */ /* Copy name and ensure null terminated */
strncpy((*res_name), prop->data, len_name); strncpy((*res_name), prop->value.data, len_name);
(*res_name)[len_name] = '\0'; (*res_name)[len_name] = '\0';
/* Compute length of class name, it could be that it is absent or not null terminated */ /* Compute length of class name, it could be that it is absent or not null terminated */
len_class = (len_name >= prop->size) ? 0 : (strlen(((char *) prop->data) + 1 + len_name)); len_class = (len_name >= prop->value.size) ? 0 : (strlen(((char *) prop->value.data) + 1 + len_name));
if (len_class > prop->size - 1 - len_name) len_class = prop->size - 1 - len_name; if (len_class > prop->value.size - 1 - len_name) len_class = prop->value.size - 1 - len_name;
(*res_class) = calloc(1, len_class + 1); (*res_class) = calloc(1, len_class + 1);
@ -94,7 +95,7 @@ winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class)
} }
/* Copy class name and ensure null terminated */ /* Copy class name and ensure null terminated */
strncpy((*res_class), ((char *) prop->data) + 1 + len_name, len_class); strncpy((*res_class), ((char *) prop->value.data) + 1 + len_name, len_class);
(*res_class)[len_class] = '\0'; (*res_class)[len_class] = '\0';
return 1; return 1;
@ -119,8 +120,8 @@ winMultiWindowGetWMHints(WindowPtr pWin, WinXWMHints * hints)
memset(hints, 0, sizeof(WinXWMHints)); memset(hints, 0, sizeof(WinXWMHints));
while (prop) { while (prop) {
if (prop->propertyName == XA_WM_HINTS && prop->data) { if (prop->propertyName == XA_WM_HINTS && prop->value.data) {
memcpy(hints, prop->data, sizeof(WinXWMHints)); memcpy(hints, prop->value.data, sizeof(WinXWMHints));
return 1; return 1;
} }
else else
@ -143,8 +144,9 @@ winMultiWindowGetWindowRole(WindowPtr pWin, char **res_role)
*res_role = NULL; *res_role = NULL;
while (prop) { while (prop) {
if (prop->propertyName == AtmWmWindowRole() if (prop->propertyName == AtmWmWindowRole()
&& prop->type == XA_STRING && prop->format == 8 && prop->data) { && prop->value.type == XA_STRING
len_role = prop->size; && prop->value.format == 8 && prop->value.data) {
len_role = prop->value.size;
(*res_role) = calloc(1, len_role + 1); (*res_role) = calloc(1, len_role + 1);
@ -153,7 +155,7 @@ winMultiWindowGetWindowRole(WindowPtr pWin, char **res_role)
return 0; return 0;
} }
strncpy((*res_role), prop->data, len_role); strncpy((*res_role), prop->value.data, len_role);
(*res_role)[len_role] = 0; (*res_role)[len_role] = 0;
return 1; return 1;
@ -178,8 +180,8 @@ winMultiWindowGetWMNormalHints(WindowPtr pWin, WinXSizeHints * hints)
memset(hints, 0, sizeof(WinXSizeHints)); memset(hints, 0, sizeof(WinXSizeHints));
while (prop) { while (prop) {
if (prop->propertyName == XA_WM_NORMAL_HINTS && prop->data) { if (prop->propertyName == XA_WM_NORMAL_HINTS && prop->value.data) {
memcpy(hints, prop->data, sizeof(WinXSizeHints)); memcpy(hints, prop->value.data, sizeof(WinXSizeHints));
return 1; return 1;
} }
else else
@ -205,7 +207,7 @@ winMultiWindowGetTransientFor(WindowPtr pWin, Window *pDaddyId)
while (prop) { while (prop) {
if (prop->propertyName == XA_WM_TRANSIENT_FOR) { if (prop->propertyName == XA_WM_TRANSIENT_FOR) {
if (pDaddyId) if (pDaddyId)
memcpy(pDaddyId, prop->data, sizeof(Window)); memcpy(pDaddyId, prop->value.data, sizeof(Window));
return 1; return 1;
} }
else else
@ -232,8 +234,8 @@ winMultiWindowGetWMName(WindowPtr pWin, char **wmName)
while (prop) { while (prop) {
if (prop->propertyName == XA_WM_NAME if (prop->propertyName == XA_WM_NAME
&& prop->type == XA_STRING && prop->data) { && prop->value.type == XA_STRING && prop->value.data) {
len_name = prop->size; len_name = prop->value.size;
(*wmName) = calloc(1, len_name + 1); (*wmName) = calloc(1, len_name + 1);
@ -242,7 +244,7 @@ winMultiWindowGetWMName(WindowPtr pWin, char **wmName)
return 0; return 0;
} }
strncpy((*wmName), prop->data, len_name); strncpy((*wmName), prop->value.data, len_name);
(*wmName)[len_name] = 0; (*wmName)[len_name] = 0;
return 1; return 1;

View File

@ -458,6 +458,7 @@ if build_xorg
'pixmapstr.h', 'pixmapstr.h',
'privates.h', 'privates.h',
'property.h', 'property.h',
'property_value.h',
'ptrveloc.h', 'ptrveloc.h',
'region.h', 'region.h',
'regionstr.h', 'regionstr.h',

21
include/property_value.h Normal file
View File

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: MIT OR X11
*
* Copyright © 2024 Enrico Weigelt, metux IT consult <info@metux.net>
*
* This header is part of the SDK / public driver API
*/
#ifndef _XORG_SDK_PROPERTY_VALUE_H
#define _XORG_SDK_PROPERTY_VALUE_H
#include <stdint.h>
#include "misc.h" // ATOM type
typedef struct _PropertyValue {
ATOM type; /* ignored by server */
uint32_t format; /* format of data for swapping - 8,16,32 */
uint32_t size; /* size of data in (format/8) bytes */
void *data; /* private to client */
} PropertyValueRec, *PropertyValuePtr;
#endif /* _XORG_SDK_PROPERTY_VALUE_H */

View File

@ -46,9 +46,12 @@ SOFTWARE.
#ifndef PROPERTYSTRUCT_H #ifndef PROPERTYSTRUCT_H
#define PROPERTYSTRUCT_H #define PROPERTYSTRUCT_H
#include "misc.h" #include "misc.h"
#include "property.h" #include "property.h"
#include "privates.h" #include "privates.h"
#include "property_value.h"
/* /*
* PROPERTY -- property element * PROPERTY -- property element
*/ */
@ -56,10 +59,7 @@ SOFTWARE.
typedef struct _Property { typedef struct _Property {
struct _Property *next; struct _Property *next;
ATOM propertyName; ATOM propertyName;
ATOM type; /* ignored by server */ PropertyValueRec value;
uint32_t format; /* format of data for swapping - 8,16,32 */
uint32_t size; /* size of data in (format/8) bytes */
void *data; /* private to client */
PrivateRec *devPrivates; PrivateRec *devPrivates;
} PropertyRec; } PropertyRec;