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

View File

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

View File

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

View File

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

View File

@ -60,13 +60,14 @@ winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class)
while (prop) {
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
must handle the cases when one or both is absent or not null terminated
*/
len_name = strlen((char *) prop->data);
if (len_name > prop->size) len_name = prop->size;
len_name = strlen((char *) prop->value.data);
if (len_name > prop->value.size) len_name = prop->value.size;
(*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 */
strncpy((*res_name), prop->data, len_name);
strncpy((*res_name), prop->value.data, len_name);
(*res_name)[len_name] = '\0';
/* 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));
if (len_class > prop->size - 1 - len_name) len_class = prop->size - 1 - len_name;
len_class = (len_name >= prop->value.size) ? 0 : (strlen(((char *) prop->value.data) + 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);
@ -94,7 +95,7 @@ winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class)
}
/* 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';
return 1;
@ -119,8 +120,8 @@ winMultiWindowGetWMHints(WindowPtr pWin, WinXWMHints * hints)
memset(hints, 0, sizeof(WinXWMHints));
while (prop) {
if (prop->propertyName == XA_WM_HINTS && prop->data) {
memcpy(hints, prop->data, sizeof(WinXWMHints));
if (prop->propertyName == XA_WM_HINTS && prop->value.data) {
memcpy(hints, prop->value.data, sizeof(WinXWMHints));
return 1;
}
else
@ -143,8 +144,9 @@ winMultiWindowGetWindowRole(WindowPtr pWin, char **res_role)
*res_role = NULL;
while (prop) {
if (prop->propertyName == AtmWmWindowRole()
&& prop->type == XA_STRING && prop->format == 8 && prop->data) {
len_role = prop->size;
&& prop->value.type == XA_STRING
&& prop->value.format == 8 && prop->value.data) {
len_role = prop->value.size;
(*res_role) = calloc(1, len_role + 1);
@ -153,7 +155,7 @@ winMultiWindowGetWindowRole(WindowPtr pWin, char **res_role)
return 0;
}
strncpy((*res_role), prop->data, len_role);
strncpy((*res_role), prop->value.data, len_role);
(*res_role)[len_role] = 0;
return 1;
@ -178,8 +180,8 @@ winMultiWindowGetWMNormalHints(WindowPtr pWin, WinXSizeHints * hints)
memset(hints, 0, sizeof(WinXSizeHints));
while (prop) {
if (prop->propertyName == XA_WM_NORMAL_HINTS && prop->data) {
memcpy(hints, prop->data, sizeof(WinXSizeHints));
if (prop->propertyName == XA_WM_NORMAL_HINTS && prop->value.data) {
memcpy(hints, prop->value.data, sizeof(WinXSizeHints));
return 1;
}
else
@ -205,7 +207,7 @@ winMultiWindowGetTransientFor(WindowPtr pWin, Window *pDaddyId)
while (prop) {
if (prop->propertyName == XA_WM_TRANSIENT_FOR) {
if (pDaddyId)
memcpy(pDaddyId, prop->data, sizeof(Window));
memcpy(pDaddyId, prop->value.data, sizeof(Window));
return 1;
}
else
@ -232,8 +234,8 @@ winMultiWindowGetWMName(WindowPtr pWin, char **wmName)
while (prop) {
if (prop->propertyName == XA_WM_NAME
&& prop->type == XA_STRING && prop->data) {
len_name = prop->size;
&& prop->value.type == XA_STRING && prop->value.data) {
len_name = prop->value.size;
(*wmName) = calloc(1, len_name + 1);
@ -242,7 +244,7 @@ winMultiWindowGetWMName(WindowPtr pWin, char **wmName)
return 0;
}
strncpy((*wmName), prop->data, len_name);
strncpy((*wmName), prop->value.data, len_name);
(*wmName)[len_name] = 0;
return 1;

View File

@ -458,6 +458,7 @@ if build_xorg
'pixmapstr.h',
'privates.h',
'property.h',
'property_value.h',
'ptrveloc.h',
'region.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
#define PROPERTYSTRUCT_H
#include "misc.h"
#include "property.h"
#include "privates.h"
#include "property_value.h"
/*
* PROPERTY -- property element
*/
@ -56,10 +59,7 @@ SOFTWARE.
typedef struct _Property {
struct _Property *next;
ATOM propertyName;
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 value;
PrivateRec *devPrivates;
} PropertyRec;