Compare commits

...

14 Commits

Author SHA1 Message Date
Enrico Weigelt, metux IT consult aa49563def xfree86: compat: re-export DeliverEvents() for horryibly maintained Nvidia
NVidia yet again doing crazy shit in their proprietary drivers:
Video drivers have no business with directly send messages to clients.

For whatever weird reasons they have their own RandR extension implementation
(that's competing with the Xserver's one) *within* the video driver.

Let that sink in! Insane.

At some point one might ask the question why they're not forking the whole
Xserver itself (they once did, back in the 90s)

But still trying to be kind with Nvidia victims, thus adding a little wrapper
function under the old name. It spills out a log warning calling users to file
bug reports their driver vendor.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-06-30 20:35:14 +02:00
Enrico Weigelt, metux IT consult bd3232404b dix: rename DeliverEvents() to dixDeliverEvents()
DIX functions should have proper naming.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-06-30 20:35:14 +02:00
Enrico Weigelt, metux IT consult 92e9176def randr: replace RRPropertyValueRec by PropertyValueRec
Use the new PropertyValueRec instead of RRPropertyValueRec. The old name
is aliased to the new one, so external drivers still compile.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-06-30 20:35:14 +02:00
Enrico Weigelt, metux IT consult e2901cd496 Xi: replace XIPropertyValueRec by PropertyValueRec
Use the new PropertyValueRec instead of XIPropertyValueRec. The old name
is aliased to the new one, so external drivers still compile.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-06-30 20:35:14 +02:00
Enrico Weigelt, metux IT consult 4f8b584717 dix: add deletable field to PropertyRec
Preparational step for later using this struct for XI.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-06-30 20:35:14 +02:00
Enrico Weigelt, metux IT consult 611055db8d 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>
2025-06-30 20:35:14 +02:00
Enrico Weigelt, metux IT consult 04cd1ac05a dix: add dixPropertyUnlinkPtr()
This function shall be used for unlinking (but not destroying) property
from a property list.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-06-30 20:35:14 +02:00
Enrico Weigelt, metux IT consult a46077cfc9 dix: add dixPropertyCreate()
This function shall be used for creating an entirely new property
structure from given data.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-06-30 20:35:14 +02:00
Enrico Weigelt, metux IT consult 07d67a07e2 dix: add dixPropertyFree()
This function should be used for free'ing an individual Property
structure, along with associated data.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-06-30 20:35:14 +02:00
Enrico Weigelt, metux IT consult 628e36226c xnest 2025-06-30 20:35:14 +02:00
Enrico Weigelt, metux IT consult 2ba1178e22 hack: meson.build: enable analyzer 2025-06-30 20:35:14 +02:00
Enrico Weigelt, metux IT consult db18f717ac WIP 2025-06-30 20:35:14 +02:00
Enrico Weigelt, metux IT consult fba0c84ab5 (nomerge) mark includes that have been scanned for obsolete exports
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-06-30 20:35:14 +02:00
Enrico Weigelt, metux IT consult 8b5aaebdb9 HACK: keep ming32 build artifacts 2025-06-30 20:35:14 +02:00
40 changed files with 380 additions and 212 deletions

View File

@ -191,8 +191,22 @@ mingw-cross-build:
extends: .common-build-and-test extends: .common-build-and-test
script: script:
- .gitlab-ci/meson-build.sh --run-install - .gitlab-ci/meson-build.sh --run-install
- find / -name libX*.dll
variables: variables:
MESON_ARGS: --cross-file=.gitlab-ci/cross-i686-w64-mingw32.txt -Dglx=false -Dlisten_tcp=true -Dxvmc=true -Dxv=true MESON_ARGS: --cross-file=.gitlab-ci/cross-i686-w64-mingw32.txt -Dglx=false -Dlisten_tcp=true -Dxvmc=true -Dxv=true
artifacts:
when: always
paths:
- hw/vfb/Xvfb.exe
- hw/xnest/Xnest.exe
- hw/xwin/winclipboard/xwinclip.exe
- hw/xwin/Xming.exe
- build/hw/vfb/Xvfb.exe
- build/hw/xnest/Xnest.exe
- build/hw/xwin/winclipboard/xwinclip.exe
- build/hw/xwin/Xming.exe
- hw/xwin/system.XWinrc
expire_in: 1 week
freebsd: freebsd:
stage: build-and-test stage: build-and-test

View File

@ -583,7 +583,7 @@ InitXTestDevices(void)
*/ */
static int static int
DeviceSetXTestProperty(DeviceIntPtr dev, Atom property, DeviceSetXTestProperty(DeviceIntPtr dev, Atom property,
XIPropertyValuePtr prop, BOOL checkonly) PropertyValuePtr prop, BOOL checkonly)
{ {
if (property == XIGetKnownProperty(XI_PROP_XTEST_DEVICE)) if (property == XIGetKnownProperty(XI_PROP_XTEST_DEVICE))
return BadAccess; return BadAccess;

View File

@ -244,7 +244,7 @@ get_property(ClientPtr client, DeviceIntPtr dev, Atom property, Atom type,
unsigned long n, len, ind; unsigned long n, len, ind;
int rc; int rc;
XIPropertyPtr prop; XIPropertyPtr prop;
XIPropertyValuePtr prop_value; PropertyValuePtr prop_value;
if (!ValidAtom(property)) { if (!ValidAtom(property)) {
client->errorValue = property; client->errorValue = property;
@ -418,7 +418,7 @@ XIResetProperties(void)
* @return Success or the error code if an error occurred. * @return Success or the error code if an error occurred.
*/ */
int int
XIPropToInt(XIPropertyValuePtr val, int *nelem_return, int **buf_return) XIPropToInt(PropertyValuePtr val, int *nelem_return, int **buf_return)
{ {
int i; int i;
int *buf; int *buf;
@ -488,7 +488,7 @@ XIPropToInt(XIPropertyValuePtr val, int *nelem_return, int **buf_return)
* @return Success or the error code if an error occurred. * @return Success or the error code if an error occurred.
*/ */
int int
XIPropToFloat(XIPropertyValuePtr val, int *nelem_return, float **buf_return) XIPropToFloat(PropertyValuePtr val, int *nelem_return, float **buf_return)
{ {
int i; int i;
float *buf; float *buf;
@ -528,11 +528,11 @@ long
XIRegisterPropertyHandler(DeviceIntPtr dev, XIRegisterPropertyHandler(DeviceIntPtr dev,
int (*SetProperty) (DeviceIntPtr dev, int (*SetProperty) (DeviceIntPtr dev,
Atom property, Atom property,
XIPropertyValuePtr prop, PropertyValuePtr prop,
BOOL checkonly), BOOL checkonly),
int (*GetProperty) (DeviceIntPtr dev, int (*GetProperty) (DeviceIntPtr dev,
Atom property), Atom property),
int (*DeleteProperty) (DeviceIntPtr dev, int (*DelProperty) (DeviceIntPtr dev,
Atom property)) Atom property))
{ {
XIPropertyHandlerPtr new_handler; XIPropertyHandlerPtr new_handler;
@ -544,7 +544,7 @@ XIRegisterPropertyHandler(DeviceIntPtr dev,
new_handler->id = XIPropHandlerID++; new_handler->id = XIPropHandlerID++;
new_handler->SetProperty = SetProperty; new_handler->SetProperty = SetProperty;
new_handler->GetProperty = GetProperty; new_handler->GetProperty = GetProperty;
new_handler->DeleteProperty = DeleteProperty; new_handler->DeleteProperty = DelProperty;
new_handler->next = dev->properties.handlers; new_handler->next = dev->properties.handlers;
dev->properties.handlers = new_handler; dev->properties.handlers = new_handler;
@ -687,8 +687,8 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
XIPropertyPtr prop; XIPropertyPtr prop;
int size_in_bytes; int size_in_bytes;
unsigned long total_len; unsigned long total_len;
XIPropertyValuePtr prop_value; PropertyValuePtr prop_value;
XIPropertyValueRec new_value; PropertyValueRec new_value;
Bool add = FALSE; Bool add = FALSE;
int rc; int rc;
@ -804,7 +804,7 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
} }
int int
XIGetDeviceProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr *value) XIGetDeviceProperty(DeviceIntPtr dev, Atom property, PropertyValuePtr *value)
{ {
XIPropertyPtr prop = XIFetchDeviceProperty(dev, property); XIPropertyPtr prop = XIFetchDeviceProperty(dev, property);
int rc; int rc;

View File

@ -474,7 +474,7 @@ TellNoMap(WindowPtr pwin, Colormap * pmid)
#ifdef XINERAMA #ifdef XINERAMA
if (noPanoramiXExtension || !pwin->drawable.pScreen->myNum) if (noPanoramiXExtension || !pwin->drawable.pScreen->myNum)
#endif /* XINERAMA */ #endif /* XINERAMA */
DeliverEvents(pwin, &xE, 1, (WindowPtr) NULL); dixDeliverEvents(pwin, &xE, 1, (WindowPtr) NULL);
if (pwin->optional) { if (pwin->optional) {
pwin->optional->colormap = None; pwin->optional->colormap = None;
CheckWindowOptionalNeed(pwin); CheckWindowOptionalNeed(pwin);
@ -503,7 +503,7 @@ TellLostMap(WindowPtr pwin, void *value)
.u.colormap.state = ColormapUninstalled .u.colormap.state = ColormapUninstalled
}; };
xE.u.u.type = ColormapNotify; xE.u.u.type = ColormapNotify;
DeliverEvents(pwin, &xE, 1, (WindowPtr) NULL); dixDeliverEvents(pwin, &xE, 1, (WindowPtr) NULL);
} }
return WT_WALKCHILDREN; return WT_WALKCHILDREN;
@ -528,7 +528,7 @@ TellGainedMap(WindowPtr pwin, void *value)
.u.colormap.state = ColormapInstalled .u.colormap.state = ColormapInstalled
}; };
xE.u.u.type = ColormapNotify; xE.u.u.type = ColormapNotify;
DeliverEvents(pwin, &xE, 1, (WindowPtr) NULL); dixDeliverEvents(pwin, &xE, 1, (WindowPtr) NULL);
} }
return WT_WALKCHILDREN; return WT_WALKCHILDREN;

View File

@ -147,7 +147,7 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform_data)
* DIX property handler. * DIX property handler.
*/ */
static int static int
DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, DeviceSetProperty(DeviceIntPtr dev, Atom property, PropertyValuePtr prop,
BOOL checkonly) BOOL checkonly)
{ {
if (property == XIGetKnownProperty(XI_PROP_ENABLED)) { if (property == XIGetKnownProperty(XI_PROP_ENABLED)) {

View File

@ -2944,7 +2944,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
* @return event delivery state (@see enum EventDeliveryState) * @return event delivery state (@see enum EventDeliveryState)
*/ */
enum EventDeliveryState enum EventDeliveryState
DeliverEvents(WindowPtr pWin, xEvent *xE, size_t count, WindowPtr otherParent) dixDeliverEvents(WindowPtr pWin, xEvent *xE, size_t count, WindowPtr otherParent)
{ {
DeviceIntRec dummy; DeviceIntRec dummy;
int deliveries; int deliveries;

View File

@ -155,8 +155,8 @@ void XTestDeviceSendEvents(DeviceIntPtr dev,
int flags, int flags,
const ValuatorMask *mask); const ValuatorMask *mask);
int XIPropToInt(XIPropertyValuePtr val, int *nelem_return, int **buf_return); int XIPropToInt(PropertyValuePtr val, int *nelem_return, int **buf_return);
int XIPropToFloat(XIPropertyValuePtr val, int *nelem_return, float **buf_return); int XIPropToFloat(PropertyValuePtr val, int *nelem_return, float **buf_return);
#endif /* _XSERVER_EXEVENTS_PRIV_H */ #endif /* _XSERVER_EXEVENTS_PRIV_H */

View File

@ -24,6 +24,7 @@ srcs_dix = [
'pixmap.c', 'pixmap.c',
'privates.c', 'privates.c',
'property.c', 'property.c',
'property_list.c',
'ptrveloc.c', 'ptrveloc.c',
'region.c', 'region.c',
'registry.c', 'registry.c',

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) {
@ -166,7 +166,7 @@ deliverPropertyNotifyEvent(WindowPtr pWin, int state, PropertyPtr pProp)
}; };
event.u.u.type = PropertyNotify; event.u.u.type = PropertyNotify;
DeliverEvents(pWin, &event, 1, (WindowPtr) NULL); dixDeliverEvents(pWin, &event, 1, (WindowPtr) NULL);
} }
int int
@ -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:
@ -325,11 +325,9 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
{ {
PropertyPtr pProp; PropertyPtr pProp;
PropertyRec savedProp; PropertyRec savedProp;
int sizeInBytes, totalSize, rc; int rc;
Mask access_mode; Mask access_mode;
sizeInBytes = format >> 3;
totalSize = len * sizeInBytes;
access_mode = (mode == PropModeReplace) ? DixWriteAccess : DixBlendAccess; access_mode = (mode == PropModeReplace) ? DixWriteAccess : DixBlendAccess;
/* first see if property already exists */ /* first see if property already exists */
@ -338,27 +336,15 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
if (rc == BadMatch) { /* just add to list */ if (rc == BadMatch) { /* just add to list */
if (!MakeWindowOptional(pWin)) if (!MakeWindowOptional(pWin))
return BadAlloc; return BadAlloc;
pProp = dixAllocateObjectWithPrivates(PropertyRec, PRIVATE_PROPERTY);
pProp = dixPropertyCreate(type, property, format, len, value);
if (!pProp) if (!pProp)
return BadAlloc; return BadAlloc;
unsigned char *data = calloc(1, totalSize);
if (totalSize) {
if (!data) {
dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
return BadAlloc;
}
memcpy(data, value, totalSize);
}
pProp->propertyName = property;
pProp->type = type;
pProp->format = format;
pProp->data = data;
pProp->size = len;
rc = XaceHookPropertyAccess(pClient, pWin, &pProp, rc = XaceHookPropertyAccess(pClient, pWin, &pProp,
DixCreateAccess | DixWriteAccess); DixCreateAccess | DixWriteAccess);
if (rc != Success) { if (rc != Success) {
free(data); dixPropertyFree(pProp);
dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
pClient->errorValue = property; pClient->errorValue = property;
return rc; return rc;
} }
@ -366,14 +352,17 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
pWin->properties = pProp; pWin->properties = pProp;
} }
else if (rc == Success) { else if (rc == Success) {
const int sizeInBytes = format >> 3;
const int totalSize = len * sizeInBytes;
/* To append or prepend to a property the request format and type /* To append or prepend to a property the request format and type
must match those of the already defined property. The must match those of the already defined property. The
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 */
@ -386,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;
} }
@ -441,7 +430,7 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
int int
DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName) DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName)
{ {
PropertyPtr pProp, prevProp; PropertyPtr pProp;
int rc; int rc;
rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess); rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess);
@ -449,23 +438,13 @@ DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName)
return Success; /* Succeed if property does not exist */ return Success; /* Succeed if property does not exist */
if (rc == Success) { if (rc == Success) {
if (pWin->properties == pProp) { dixPropertyUnlinkPtr(&pWin->properties, pProp);
/* Takes care of head */ if (!pWin->properties)
if (!(pWin->properties = pProp->next))
CheckWindowOptionalNeed(pWin); CheckWindowOptionalNeed(pWin);
}
else {
/* Need to traverse to find the previous element */
prevProp = pWin->properties;
while (prevProp->next != pProp)
prevProp = prevProp->next;
prevProp->next = pProp->next;
}
deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp); deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp);
notifyVRRMode(client, pWin, PropertyDelete, pProp); notifyVRRMode(client, pWin, PropertyDelete, pProp);
free(pProp->data); dixPropertyFree(pProp);
dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
} }
return rc; return rc;
} }
@ -473,17 +452,13 @@ DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName)
void void
DeleteAllWindowProperties(WindowPtr pWin) DeleteAllWindowProperties(WindowPtr pWin)
{ {
PropertyPtr pProp = pWin->properties; PropertyPtr pProp;
while (pProp) { while ((pProp = pWin->properties)) {
deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp); deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp);
PropertyPtr pNextProp = pProp->next; dixPropertyUnlinkPtr(&pWin->properties, pProp);
free(pProp->data); dixPropertyFree(pProp);
dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
pProp = pNextProp;
} }
pWin->properties = NULL;
} }
/***************** /*****************
@ -564,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);
@ -584,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
@ -601,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)) {
@ -615,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 */
@ -632,8 +607,7 @@ ProcGetProperty(ClientPtr client)
prevProp->next = pProp->next; prevProp->next = pProp->next;
} }
free(pProp->data); dixPropertyFree(pProp);
dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
} }
if (client->swapped) { if (client->swapped) {

77
dix/property_list.c Normal file
View File

@ -0,0 +1,77 @@
/* SPDX-License-Identifier: MIT OR X11
*
* Copyright © 2024 Enrico Weigelt, metux IT consult <info@metux.net>
*/
#include <dix-config.h>
#include "dix/property_priv.h"
#include "include/privates.h"
#include "include/propertyst.h"
#include "os/bug_priv.h"
void dixPropertyFree(PropertyPtr pr)
{
if (pr) {
free(pr->value.data);
dixFreeObjectWithPrivates(pr, PRIVATE_PROPERTY);
}
}
PropertyPtr dixPropertyCreate(Atom type, Atom name, int format, size_t len,
const void *value)
{
const int totalSize = (format >> 3) * len;
void *data = calloc(1, totalSize);
if (!data)
return NULL;
PropertyPtr pProp = dixAllocateObjectWithPrivates(PropertyRec, PRIVATE_PROPERTY);
if (!pProp) {
free(data);
return NULL;
}
memcpy(data, value, totalSize);
pProp->propertyName = name;
pProp->value.data = data;
pProp->value.format = format;
pProp->value.size = len;
pProp->value.type = type;
pProp->deletable = TRUE;
return pProp;
}
PropertyPtr dixPropertyUnlinkPtr(PropertyPtr *list, PropertyPtr prop)
{
BUG_RETURN_VAL(!list, NULL);
if ((!prop) || (!(*list))) // nothing to do
return NULL;
PropertyPtr walk = *list;
// remove from head
if (walk == prop) {
*list = prop->next;
walk->next = NULL;
return prop;
}
// walk the list to find it
while (walk->next && walk->next != prop) {
walk = walk->next;
}
// didn't find it
if (!walk->next)
return NULL;
// unlink the element
walk->next = walk->next->next;
prop->next = NULL;
return prop;
}

View File

@ -53,6 +53,8 @@ SOFTWARE.
#include <X11/X.h> #include <X11/X.h>
#include "include/privates.h"
#include "dix.h" #include "dix.h"
#include "window.h" #include "window.h"
#include "property.h" #include "property.h"
@ -99,4 +101,36 @@ int dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom proprty,
void DeleteAllWindowProperties(WindowPtr pWin); void DeleteAllWindowProperties(WindowPtr pWin);
/*
* Free an individual property structure and related data.
* Invalidates the passed pointer. Doesn't touch anything other in the list.
*
* @param pProp pointer to property structure to free
*/
void dixPropertyFree(PropertyPtr pProp);
/*
* Create and fill a new property structure from given data. The `value`
* is malloc()ed and copied over.
*
* @param type AtomID of the property type
* @param name AtomID of the property name
* @param format the property format (8/16/32 bits)
* @param len length in units defined by format
* @param value pointer to the (raw) property data)
* @return pointer to newly created property structure (NULL on allocation failure)
*/
PropertyPtr dixPropertyCreate(Atom type, Atom name, int format,
size_t len, const void *value);
/*
* Unlink a property structure from a property list. The given property's next
* pointer is also cleared. The property structure itself is NOT destroyed.
*
* @param list pointer to the property list head (NULL on empty list)
* @param prop pointer to the property to unlink.
* @return on success, pointer to the property, NULL if not found in list
*/
PropertyPtr dixPropertyUnlinkPtr(PropertyPtr *list, PropertyPtr prop);
#endif /* _XSERVER_PROPERTY_PRIV_H */ #endif /* _XSERVER_PROPERTY_PRIV_H */

View File

@ -191,7 +191,7 @@ AccelerationDefaultCleanup(DeviceIntPtr dev)
*/ */
static int static int
AccelSetProfileProperty(DeviceIntPtr dev, Atom atom, AccelSetProfileProperty(DeviceIntPtr dev, Atom atom,
XIPropertyValuePtr val, BOOL checkOnly) PropertyValuePtr val, BOOL checkOnly)
{ {
DeviceVelocityPtr vel; DeviceVelocityPtr vel;
int profile, *ptr = &profile; int profile, *ptr = &profile;
@ -236,7 +236,7 @@ AccelInitProfileProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
*/ */
static int static int
AccelSetDecelProperty(DeviceIntPtr dev, Atom atom, AccelSetDecelProperty(DeviceIntPtr dev, Atom atom,
XIPropertyValuePtr val, BOOL checkOnly) PropertyValuePtr val, BOOL checkOnly)
{ {
DeviceVelocityPtr vel; DeviceVelocityPtr vel;
float v, *ptr = &v; float v, *ptr = &v;
@ -280,7 +280,7 @@ AccelInitDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
*/ */
static int static int
AccelSetAdaptDecelProperty(DeviceIntPtr dev, Atom atom, AccelSetAdaptDecelProperty(DeviceIntPtr dev, Atom atom,
XIPropertyValuePtr val, BOOL checkOnly) PropertyValuePtr val, BOOL checkOnly)
{ {
DeviceVelocityPtr veloc; DeviceVelocityPtr veloc;
float v, *ptr = &v; float v, *ptr = &v;
@ -327,7 +327,7 @@ AccelInitAdaptDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
*/ */
static int static int
AccelSetScaleProperty(DeviceIntPtr dev, Atom atom, AccelSetScaleProperty(DeviceIntPtr dev, Atom atom,
XIPropertyValuePtr val, BOOL checkOnly) PropertyValuePtr val, BOOL checkOnly)
{ {
DeviceVelocityPtr vel; DeviceVelocityPtr vel;
float v, *ptr = &v; float v, *ptr = &v;

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;
} }
@ -931,7 +931,7 @@ dixCreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w,
.u.createNotify.override = pWin->overrideRedirect .u.createNotify.override = pWin->overrideRedirect
}; };
event.u.u.type = CreateNotify; event.u.u.type = CreateNotify;
DeliverEvents(pParent, &event, 1, NullWindow); dixDeliverEvents(pParent, &event, 1, NullWindow);
} }
return pWin; return pWin;
} }
@ -1018,7 +1018,7 @@ CrushTree(WindowPtr pWin)
if (SubStrSend(pChild, pParent)) { if (SubStrSend(pChild, pParent)) {
xEvent event = { .u.u.type = DestroyNotify }; xEvent event = { .u.u.type = DestroyNotify };
event.u.destroyNotify.window = pChild->drawable.id; event.u.destroyNotify.window = pChild->drawable.id;
DeliverEvents(pChild, &event, 1, NullWindow); dixDeliverEvents(pChild, &event, 1, NullWindow);
} }
FreeResource(pChild->drawable.id, X11_RESTYPE_WINDOW); FreeResource(pChild->drawable.id, X11_RESTYPE_WINDOW);
pSib = pChild->nextSib; pSib = pChild->nextSib;
@ -1060,7 +1060,7 @@ DeleteWindow(void *value, XID wid)
if (wid && pParent && SubStrSend(pWin, pParent)) { if (wid && pParent && SubStrSend(pWin, pParent)) {
xEvent event = { .u.u.type = DestroyNotify }; xEvent event = { .u.u.type = DestroyNotify };
event.u.destroyNotify.window = pWin->drawable.id; event.u.destroyNotify.window = pWin->drawable.id;
DeliverEvents(pWin, &event, 1, NullWindow); dixDeliverEvents(pWin, &event, 1, NullWindow);
} }
FreeWindowResources(pWin); FreeWindowResources(pWin);
@ -1455,7 +1455,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
.u.colormap.state = IsMapInstalled(cmap, pWin) .u.colormap.state = IsMapInstalled(cmap, pWin)
}; };
xE.u.u.type = ColormapNotify; xE.u.u.type = ColormapNotify;
DeliverEvents(pWin, &xE, 1, NullWindow); dixDeliverEvents(pWin, &xE, 1, NullWindow);
} }
break; break;
case CWCursor: case CWCursor:
@ -1851,7 +1851,7 @@ ResizeChildrenWinSize(WindowPtr pWin, int dx, int dy, int dw, int dh)
.u.gravity.y = cwsy - wBorderWidth(pSib) .u.gravity.y = cwsy - wBorderWidth(pSib)
}; };
event.u.u.type = GravityNotify; event.u.u.type = GravityNotify;
DeliverEvents(pSib, &event, 1, NullWindow); dixDeliverEvents(pSib, &event, 1, NullWindow);
pSib->origin.x = cwsx; pSib->origin.x = cwsx;
pSib->origin.y = cwsy; pSib->origin.y = cwsy;
} }
@ -2374,7 +2374,7 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client)
event.u.configureNotify.y += screenInfo.screens[0]->y; event.u.configureNotify.y += screenInfo.screens[0]->y;
} }
#endif /* XINERAMA */ #endif /* XINERAMA */
DeliverEvents(pWin, &event, 1, NullWindow); dixDeliverEvents(pWin, &event, 1, NullWindow);
} }
if (mask & CWBorderWidth) { if (mask & CWBorderWidth) {
if (action == RESTACK_WIN) { if (action == RESTACK_WIN) {
@ -2462,7 +2462,7 @@ CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
} }
event.u.u.type = CirculateNotify; event.u.u.type = CirculateNotify;
DeliverEvents(pWin, &event, 1, NullWindow); dixDeliverEvents(pWin, &event, 1, NullWindow);
ReflectStackChange(pWin, ReflectStackChange(pWin,
(direction == RaiseLowest) ? pFirst : NullWindow, (direction == RaiseLowest) ? pFirst : NullWindow,
VTStack); VTStack);
@ -2519,7 +2519,7 @@ ReparentWindow(WindowPtr pWin, WindowPtr pParent,
event.u.reparent.y += screenInfo.screens[0]->y; event.u.reparent.y += screenInfo.screens[0]->y;
} }
#endif /* XINERAMA */ #endif /* XINERAMA */
DeliverEvents(pWin, &event, 1, pParent); dixDeliverEvents(pWin, &event, 1, pParent);
/* take out of sibling chain */ /* take out of sibling chain */
@ -2627,7 +2627,7 @@ DeliverMapNotify(WindowPtr pWin)
.u.mapNotify.override = pWin->overrideRedirect, .u.mapNotify.override = pWin->overrideRedirect,
}; };
event.u.u.type = MapNotify; event.u.u.type = MapNotify;
DeliverEvents(pWin, &event, 1, NullWindow); dixDeliverEvents(pWin, &event, 1, NullWindow);
} }
/***** /*****
@ -2818,7 +2818,7 @@ DeliverUnmapNotify(WindowPtr pWin, Bool fromConfigure)
.u.unmapNotify.fromConfigure = fromConfigure .u.unmapNotify.fromConfigure = fromConfigure
}; };
event.u.u.type = UnmapNotify; event.u.u.type = UnmapNotify;
DeliverEvents(pWin, &event, 1, NullWindow); dixDeliverEvents(pWin, &event, 1, NullWindow);
} }
/***** /*****
@ -3074,7 +3074,7 @@ SendVisibilityNotify(WindowPtr pWin)
.u.visibility.state = visibility .u.visibility.state = visibility
}; };
event.u.u.type = VisibilityNotify; event.u.u.type = VisibilityNotify;
DeliverEvents(pWin, &event, 1, NullWindow); dixDeliverEvents(pWin, &event, 1, NullWindow);
} }
#define RANDOM_WIDTH 32 #define RANDOM_WIDTH 32

View File

@ -0,0 +1,30 @@
#include <dix-config.h>
#include <X11/Xfuncproto.h>
#include "dix/dix_priv.h"
/*
* this is specifically for NVidia proprietary driver: they're again lagging
* behind a year, doing at least some minimal cleanup of their code base.
* All attempts to get in direct contact with them have failed.
*/
_X_EXPORT enum EventDeliveryState DeliverEvents(WindowPtr pWindow,
xEventPtr events,
size_t nEvents,
WindowPtr otherParent);
enum EventDeliveryState DeliverEvents(WindowPtr pWindow,
xEventPtr events,
size_t nEvents,
WindowPtr otherParent)
{
LogMessageVerb(X_WARNING, 0, "Bogus driver calling DIX-internal function DeliverEvents() !\n");
LogMessageVerb(X_WARNING, 0, "External drivers really should never ever call this function.\n");
LogMessageVerb(X_WARNING, 0, "File a bug report to driver vendor or use a FOSS driver.\n");
LogMessageVerb(X_WARNING, 0, "Proprietary drivers are inherently unstable, they just can't be done right.\n");
LogMessageVerb(X_WARNING, 0, "And just don't buy Nvidia hardware, ever.\n");
return dixDeliverEvents(pWindow, events, nEvents, otherParent);
}

View File

@ -1,5 +1,6 @@
srcs_xorg_compat = [ srcs_xorg_compat = [
'clientexception.c', 'clientexception.c',
'deliverevents.c',
'log.c', 'log.c',
'ones.c', 'ones.c',
'xf86Helper.c', 'xf86Helper.c',

View File

@ -3169,7 +3169,7 @@ drmmode_output_create_resources(xf86OutputPtr output)
static Bool static Bool
drmmode_output_set_property(xf86OutputPtr output, Atom property, drmmode_output_set_property(xf86OutputPtr output, Atom property,
RRPropertyValuePtr value) PropertyValuePtr value)
{ {
drmmode_output_private_ptr drmmode_output = output->driver_private; drmmode_output_private_ptr drmmode_output = output->driver_private;
drmmode_ptr drmmode = drmmode_output->drmmode; drmmode_ptr drmmode = drmmode_output->drmmode;

View File

@ -509,7 +509,7 @@ typedef struct _xf86OutputFuncs {
*/ */
Bool Bool
(*set_property) (xf86OutputPtr output, (*set_property) (xf86OutputPtr output,
Atom property, RRPropertyValuePtr value); Atom property, PropertyValuePtr value);
#endif #endif
#ifdef RANDR_13_INTERFACE #ifdef RANDR_13_INTERFACE
/** /**
@ -668,7 +668,7 @@ typedef struct _xf86ProviderFuncs {
*/ */
Bool Bool
(*set_property) (ScrnInfoPtr scrn, (*set_property) (ScrnInfoPtr scrn,
Atom property, RRPropertyValuePtr value); Atom property, PropertyValuePtr value);
/** /**
* Callback to get an updated property value * Callback to get an updated property value

View File

@ -1524,7 +1524,7 @@ xf86RandR12InitGamma(ScrnInfoPtr pScrn, unsigned gammaSize) {
static Bool static Bool
xf86RandR12OutputSetProperty(ScreenPtr pScreen, xf86RandR12OutputSetProperty(ScreenPtr pScreen,
RROutputPtr randr_output, RROutputPtr randr_output,
Atom property, RRPropertyValuePtr value) Atom property, PropertyValuePtr value)
{ {
xf86OutputPtr output = randr_output->devPrivate; xf86OutputPtr output = randr_output->devPrivate;
@ -2144,7 +2144,7 @@ xf86RandR14ProviderSetOffloadSink(ScreenPtr pScreen,
static Bool static Bool
xf86RandR14ProviderSetProperty(ScreenPtr pScreen, xf86RandR14ProviderSetProperty(ScreenPtr pScreen,
RRProviderPtr randr_provider, RRProviderPtr randr_provider,
Atom property, RRPropertyValuePtr value) Atom property, PropertyValuePtr value)
{ {
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);

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

@ -148,9 +148,10 @@ xnestChangeGC(GCPtr pGC, unsigned long mask)
if (mask & GCTileStipYOrigin) if (mask & GCTileStipYOrigin)
values.tile_stipple_origin_y = pGC->patOrg.y; values.tile_stipple_origin_y = pGC->patOrg.y;
if (mask & GCFont) if (mask & GCFont) {
assert(xnestFontPriv(pGC->font));
values.font = xnestFontPriv(pGC->font)->font_id; values.font = xnestFontPriv(pGC->font)->font_id;
}
if (mask & GCSubwindowMode) if (mask & GCSubwindowMode)
values.subwindow_mode = pGC->subWindowMode; values.subwindow_mode = pGC->subWindowMode;

View File

@ -190,11 +190,13 @@ xnestBitBlitHelper(GCPtr pGC)
default: default:
{ {
struct xnest_event_queue *q = malloc(sizeof(struct xnest_event_queue)); struct xnest_event_queue *q = malloc(sizeof(struct xnest_event_queue));
if (q) {
q->event = event; q->event = event;
xorg_list_add(&q->entry, &xnestUpstreamInfo.eventQueue.entry); xorg_list_add(&q->entry, &xnestUpstreamInfo.eventQueue.entry);
} }
} }
} }
}
RegionDestroy(pTmpReg); RegionDestroy(pTmpReg);
RegionValidate(pReg, &overlap); RegionValidate(pReg, &overlap);
@ -344,6 +346,9 @@ xnestPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
// won't get more than 254 elements, since it's already processed by doPolyText() // won't get more than 254 elements, since it's already processed by doPolyText()
int const bufsize = sizeof(xTextElt) + count; int const bufsize = sizeof(xTextElt) + count;
uint8_t *buffer = malloc(bufsize); uint8_t *buffer = malloc(bufsize);
if (!buffer)
return 0;
xTextElt *elt = (xTextElt*)buffer; xTextElt *elt = (xTextElt*)buffer;
elt->len = count; elt->len = count;
elt->delta = 0; elt->delta = 0;
@ -370,6 +375,8 @@ xnestPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
// won't get more than 254 elements, since it's already processed by doPolyText() // won't get more than 254 elements, since it's already processed by doPolyText()
int const bufsize = sizeof(xTextElt) + count*2; int const bufsize = sizeof(xTextElt) + count*2;
uint8_t *buffer = malloc(bufsize); uint8_t *buffer = malloc(bufsize);
if (!buffer)
return 0;
xTextElt *elt = (xTextElt*)buffer; xTextElt *elt = (xTextElt*)buffer;
elt->len = count; elt->len = count;
elt->delta = 0; elt->delta = 0;

View File

@ -293,6 +293,7 @@ breakout:
if (!found_default_visual) { if (!found_default_visual) {
ErrorF("Xnest: can't find matching visual for user specified depth %d\n", xnestDefaultDepth); ErrorF("Xnest: can't find matching visual for user specified depth %d\n", xnestDefaultDepth);
assert(visuals);
defaultVisual = visuals[0].vid; defaultVisual = visuals[0].vid;
rootDepth = visuals[0].nplanes; rootDepth = visuals[0].nplanes;
} }

View File

@ -440,7 +440,8 @@ xnestShapeWindow(WindowPtr pWin)
int const num_rects = RegionNumRects(xnestWindowPriv(pWin)->bounding_shape); int const num_rects = RegionNumRects(xnestWindowPriv(pWin)->bounding_shape);
BoxPtr const pBox = RegionRects(xnestWindowPriv(pWin)->bounding_shape); BoxPtr const pBox = RegionRects(xnestWindowPriv(pWin)->bounding_shape);
xcb_rectangle_t *rects = calloc(num_rects, sizeof(xcb_rectangle_t)); xcb_rectangle_t *rects = calloc(num_rects, sizeof(xcb_rectangle_t));
if (!rects)
return;
for (int i = 0; i < num_rects; i++) { for (int i = 0; i < num_rects; i++) {
rects[i].x = pBox[i].x1; rects[i].x = pBox[i].x1;
rects[i].y = pBox[i].y1; rects[i].y = pBox[i].y1;
@ -469,7 +470,8 @@ xnestShapeWindow(WindowPtr pWin)
int const num_rects = RegionNumRects(xnestWindowPriv(pWin)->clip_shape); int const num_rects = RegionNumRects(xnestWindowPriv(pWin)->clip_shape);
BoxPtr const pBox = RegionRects(xnestWindowPriv(pWin)->clip_shape); BoxPtr const pBox = RegionRects(xnestWindowPriv(pWin)->clip_shape);
xcb_rectangle_t *rects = calloc(num_rects, sizeof(xcb_rectangle_t)); xcb_rectangle_t *rects = calloc(num_rects, sizeof(xcb_rectangle_t));
if (!rects)
return;
for (int i = 0; i < num_rects; i++) { for (int i = 0; i < num_rects; i++) {
rects[i].x = pBox[i].x1; rects[i].x = pBox[i].x1;
rects[i].y = pBox[i].y1; rects[i].y = pBox[i].y1;

View File

@ -303,7 +303,7 @@ QuartzUpdateScreens(void)
e.u.configureNotify.height = height; e.u.configureNotify.height = height;
e.u.configureNotify.borderWidth = wBorderWidth(pRoot); e.u.configureNotify.borderWidth = wBorderWidth(pRoot);
e.u.configureNotify.override = pRoot->overrideRedirect; e.u.configureNotify.override = pRoot->overrideRedirect;
DeliverEvents(pRoot, &e, 1, NullWindow); dixDeliverEvents(pRoot, &e, 1, NullWindow);
quartzProcs->UpdateScreen(pScreen); quartzProcs->UpdateScreen(pScreen);

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

@ -92,7 +92,7 @@ extern _X_EXPORT int XIChangeDeviceProperty(DeviceIntPtr /* dev */ ,
extern _X_EXPORT int XIGetDeviceProperty(DeviceIntPtr /* dev */ , extern _X_EXPORT int XIGetDeviceProperty(DeviceIntPtr /* dev */ ,
Atom /* property */ , Atom /* property */ ,
XIPropertyValuePtr * /* value */ PropertyValuePtr * /* value */
); );
extern _X_EXPORT int XISetDevicePropertyDeletable(DeviceIntPtr /* dev */ , extern _X_EXPORT int XISetDevicePropertyDeletable(DeviceIntPtr /* dev */ ,
@ -105,7 +105,7 @@ extern _X_EXPORT long XIRegisterPropertyHandler(DeviceIntPtr dev,
dev, dev,
Atom Atom
property, property,
XIPropertyValuePtr PropertyValuePtr
prop, prop,
BOOL BOOL
checkonly), checkonly),

View File

@ -55,6 +55,7 @@ SOFTWARE.
#include "dixstruct.h" #include "dixstruct.h"
#include "cursorstr.h" #include "cursorstr.h"
#include "privates.h" #include "privates.h"
#include "property_value.h"
#define BitIsOn(ptr, bit) (!!(((const BYTE *) (ptr))[(bit)>>3] & (1 << ((bit) & 7)))) #define BitIsOn(ptr, bit) (!!(((const BYTE *) (ptr))[(bit)>>3] & (1 << ((bit) & 7))))
#define SetBit(ptr, bit) (((BYTE *) (ptr))[(bit)>>3] |= (1 << ((bit) & 7))) #define SetBit(ptr, bit) (((BYTE *) (ptr))[(bit)>>3] |= (1 << ((bit) & 7)))
@ -452,28 +453,24 @@ typedef struct _ClassesRec {
} ClassesRec; } ClassesRec;
/* Device properties */ /* Device properties */
typedef struct _XIPropertyValue {
Atom type; /* ignored by server */ /* for backwards compat with older drivers, should not be used anymore */
short format; /* format of data for swapping - 8,16,32 */ typedef PropertyValueRec XIPropertyValueRec, *XIPropertyValuePtr;
long size; /* size of data in (format/8) bytes */
void *data; /* private to client */
} XIPropertyValueRec;
typedef struct _XIProperty { typedef struct _XIProperty {
struct _XIProperty *next; struct _XIProperty *next;
Atom propertyName; Atom propertyName;
BOOL deletable; /* clients can delete this prop? */ BOOL deletable; /* clients can delete this prop? */
XIPropertyValueRec value; PropertyValueRec value;
} XIPropertyRec; } XIPropertyRec;
typedef XIPropertyRec *XIPropertyPtr; typedef XIPropertyRec *XIPropertyPtr;
typedef XIPropertyValueRec *XIPropertyValuePtr;
typedef struct _XIPropertyHandler { typedef struct _XIPropertyHandler {
struct _XIPropertyHandler *next; struct _XIPropertyHandler *next;
long id; long id;
int (*SetProperty) (DeviceIntPtr dev, int (*SetProperty) (DeviceIntPtr dev,
Atom property, XIPropertyValuePtr prop, BOOL checkonly); Atom property, PropertyValuePtr prop, BOOL checkonly);
int (*GetProperty) (DeviceIntPtr dev, Atom property); int (*GetProperty) (DeviceIntPtr dev, Atom property);
int (*DeleteProperty) (DeviceIntPtr dev, Atom property); int (*DeleteProperty) (DeviceIntPtr dev, Atom property);
} XIPropertyHandler, *XIPropertyHandlerPtr; } XIPropertyHandler, *XIPropertyHandlerPtr;

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,11 +59,9 @@ 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;
Bool deletable;
} PropertyRec; } PropertyRec;
#endif /* PROPERTYSTRUCT_H */ #endif /* PROPERTYSTRUCT_H */

View File

@ -1,3 +1,5 @@
// exports scan complete
/************************************************************ /************************************************************
Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.

View File

@ -48,6 +48,16 @@ if cc.get_id() == 'gcc' or cc.get_id() == 'clang'
'-Werror=int-to-pointer-cast', '-Werror=int-to-pointer-cast',
'-Werror=pointer-to-int-cast', '-Werror=pointer-to-int-cast',
'-Wvla', '-Wvla',
# '-fanalyzer',
# '-Wno-analyzer-mismatching-deallocation',
'-Wno-analyzer-malloc-leak',
# has some false alarms on deferred request handlers (closure on stack)
# '-Wno-error=analyzer-free-of-non-heap',
# has some false alarms on reallocarray (miinitext)
# '-Wno-error=analyzer-double-free',
# '-Wno-error=analyzer-null-dereference',
# '-Wno-error=analyzer-file-leak',
# '-Wno-error=analyzer-possible-null-dereference',
] ]
else else
test_wflags = [] test_wflags = []

View File

@ -351,7 +351,7 @@ miSendExposures(WindowPtr pWin, RegionPtr pRgn, int dx, int dy)
} }
#endif /* XINERAMA */ #endif /* XINERAMA */
DeliverEvents(pWin, pEvent, numRects, NullWindow); dixDeliverEvents(pWin, pEvent, numRects, NullWindow);
free(pEvent); free(pEvent);
} }

View File

@ -42,6 +42,7 @@
#include "scrnintstr.h" #include "scrnintstr.h"
#include "windowstr.h" #include "windowstr.h"
#include "pixmapstr.h" #include "pixmapstr.h"
#include "property_value.h"
#include "extnsionst.h" #include "extnsionst.h"
#include "servermd.h" #include "servermd.h"
#include "rrtransform.h" #include "rrtransform.h"
@ -71,7 +72,8 @@ typedef XID RRLease;
#define RRModeName(pMode) ((char *) (pMode + 1)) #define RRModeName(pMode) ((char *) (pMode + 1))
typedef struct _rrMode RRModeRec, *RRModePtr; typedef struct _rrMode RRModeRec, *RRModePtr;
typedef struct _rrPropertyValue RRPropertyValueRec, *RRPropertyValuePtr; typedef PropertyValueRec RRPropertyValueRec; // deprecated
typedef PropertyValuePtr RRPropertyValuePtr; // deprecated
typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr; typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr;
typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr;
typedef struct _rrOutput RROutputRec, *RROutputPtr; typedef struct _rrOutput RROutputRec, *RROutputPtr;
@ -86,13 +88,6 @@ struct _rrMode {
ScreenPtr userScreen; ScreenPtr userScreen;
}; };
struct _rrPropertyValue {
Atom type; /* ignored by server */
short format; /* format of data for swapping - 8,16,32 */
long size; /* size of data in (format/8) bytes */
void *data; /* private to client */
};
struct _rrProperty { struct _rrProperty {
RRPropertyPtr next; RRPropertyPtr next;
ATOM propertyName; ATOM propertyName;
@ -101,7 +96,8 @@ struct _rrProperty {
Bool immutable; Bool immutable;
int num_valid; int num_valid;
INT32 *valid_values; INT32 *valid_values;
RRPropertyValueRec current, pending; PropertyValueRec current;
PropertyValueRec pending;
}; };
struct _rrCrtc { struct _rrCrtc {
@ -224,7 +220,7 @@ typedef Bool (*RRCrtcGetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc);
typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen, typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen,
RROutputPtr output, RROutputPtr output,
Atom property, Atom property,
RRPropertyValuePtr value); PropertyValuePtr value);
typedef Bool (*RROutputValidateModeProcPtr) (ScreenPtr pScreen, typedef Bool (*RROutputValidateModeProcPtr) (ScreenPtr pScreen,
RROutputPtr output, RROutputPtr output,
@ -253,7 +249,7 @@ typedef Bool (*RRProviderGetPropertyProcPtr) (ScreenPtr pScreen,
typedef Bool (*RRProviderSetPropertyProcPtr) (ScreenPtr pScreen, typedef Bool (*RRProviderSetPropertyProcPtr) (ScreenPtr pScreen,
RRProviderPtr provider, RRProviderPtr provider,
Atom property, Atom property,
RRPropertyValuePtr value); PropertyValuePtr value);
typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation * rotations); typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation * rotations);
typedef Bool (*RRCloseScreenProcPtr) (ScreenPtr pscreen); typedef Bool (*RRCloseScreenProcPtr) (ScreenPtr pscreen);

View File

@ -459,7 +459,7 @@ rrGetPixmapSharingSyncProp(int numOutputs, RROutputPtr * outputs)
/* If one output doesn't want sync, no sync */ /* If one output doesn't want sync, no sync */
for (o = 0; o < numOutputs; o++) { for (o = 0; o < numOutputs; o++) {
RRPropertyValuePtr val; PropertyValuePtr val;
if ((val = RRGetOutputProperty(outputs[o], syncProp, TRUE)) && if ((val = RRGetOutputProperty(outputs[o], syncProp, TRUE)) &&
val->data) { val->data) {
@ -715,7 +715,7 @@ rrCheckEmulated(RROutputPtr output)
{ {
const char *emulStr = XRANDR_EMULATION_PROP; const char *emulStr = XRANDR_EMULATION_PROP;
Atom emulProp; Atom emulProp;
RRPropertyValuePtr val; PropertyValuePtr val;
emulProp = MakeAtom(emulStr, strlen(emulStr), FALSE); emulProp = MakeAtom(emulStr, strlen(emulStr), FALSE);
if (emulProp == None) if (emulProp == None)

View File

@ -97,7 +97,7 @@ RRDeleteAllOutputProperties(RROutputPtr output)
} }
static void static void
RRInitOutputPropertyValue(RRPropertyValuePtr property_value) RRInitOutputPropertyValue(PropertyValuePtr property_value)
{ {
property_value->type = None; property_value->type = None;
property_value->format = 0; property_value->format = 0;
@ -137,7 +137,7 @@ RRDeleteOutputProperty(RROutputPtr output, Atom property)
} }
static void static void
RRNoticePropertyChange(RROutputPtr output, Atom property, RRPropertyValuePtr value) RRNoticePropertyChange(RROutputPtr output, Atom property, PropertyValuePtr value)
{ {
const char *non_desktop_str = RR_PROPERTY_NON_DESKTOP; const char *non_desktop_str = RR_PROPERTY_NON_DESKTOP;
Atom non_desktop_prop = MakeAtom(non_desktop_str, strlen(non_desktop_str), FALSE); Atom non_desktop_prop = MakeAtom(non_desktop_str, strlen(non_desktop_str), FALSE);
@ -168,8 +168,8 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen); rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen);
int size_in_bytes; int size_in_bytes;
unsigned long total_len; unsigned long total_len;
RRPropertyValuePtr prop_value; PropertyValuePtr prop_value;
RRPropertyValueRec new_value; PropertyValueRec new_value;
Bool add = FALSE; Bool add = FALSE;
size_in_bytes = format >> 3; size_in_bytes = format >> 3;
@ -282,8 +282,8 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
Bool Bool
RRPostPendingProperties(RROutputPtr output) RRPostPendingProperties(RROutputPtr output)
{ {
RRPropertyValuePtr pending_value; PropertyValuePtr pending_value;
RRPropertyValuePtr current_value; PropertyValuePtr current_value;
RRPropertyPtr property; RRPropertyPtr property;
Bool ret = TRUE; Bool ret = TRUE;
@ -330,7 +330,7 @@ RRQueryOutputProperty(RROutputPtr output, Atom property)
return NULL; return NULL;
} }
RRPropertyValuePtr PropertyValuePtr
RRGetOutputProperty(RROutputPtr output, Atom property, Bool pending) RRGetOutputProperty(RROutputPtr output, Atom property, Bool pending)
{ {
RRPropertyPtr prop = RRQueryOutputProperty(output, property); RRPropertyPtr prop = RRQueryOutputProperty(output, property);
@ -621,7 +621,7 @@ ProcRRGetOutputProperty(ClientPtr client)
{ {
REQUEST(xRRGetOutputPropertyReq); REQUEST(xRRGetOutputPropertyReq);
RRPropertyPtr prop, *prev; RRPropertyPtr prop, *prev;
RRPropertyValuePtr prop_value; PropertyValuePtr prop_value;
unsigned long n, len, ind; unsigned long n, len, ind;
RROutputPtr output; RROutputPtr output;
char *extra = NULL; char *extra = NULL;

View File

@ -84,7 +84,7 @@ RRDeleteProperty(RRProviderRec * provider, RRPropertyRec * prop)
} }
static void static void
RRInitProviderPropertyValue(RRPropertyValuePtr property_value) RRInitProviderPropertyValue(PropertyValuePtr property_value)
{ {
property_value->type = None; property_value->type = None;
property_value->format = 0; property_value->format = 0;
@ -135,8 +135,8 @@ RRChangeProviderProperty(RRProviderPtr provider, Atom property, Atom type,
int size_in_bytes; int size_in_bytes;
int total_size; int total_size;
unsigned long total_len; unsigned long total_len;
RRPropertyValuePtr prop_value; PropertyValuePtr prop_value;
RRPropertyValueRec new_value; PropertyValueRec new_value;
Bool add = FALSE; Bool add = FALSE;
size_in_bytes = format >> 3; size_in_bytes = format >> 3;
@ -256,7 +256,7 @@ RRQueryProviderProperty(RRProviderPtr provider, Atom property)
return NULL; return NULL;
} }
RRPropertyValuePtr PropertyValuePtr
RRGetProviderProperty(RRProviderPtr provider, Atom property, Bool pending) RRGetProviderProperty(RRProviderPtr provider, Atom property, Bool pending)
{ {
RRPropertyPtr prop = RRQueryProviderProperty(provider, property); RRPropertyPtr prop = RRQueryProviderProperty(provider, property);
@ -528,7 +528,7 @@ ProcRRGetProviderProperty(ClientPtr client)
{ {
REQUEST(xRRGetProviderPropertyReq); REQUEST(xRRGetProviderPropertyReq);
RRPropertyPtr prop, *prev; RRPropertyPtr prop, *prev;
RRPropertyValuePtr prop_value; PropertyValuePtr prop_value;
unsigned long n, len, ind; unsigned long n, len, ind;
RRProviderPtr provider; RRProviderPtr provider;
xRRGetProviderPropertyReply reply = { xRRGetProviderPropertyReply reply = {

View File

@ -86,7 +86,7 @@ RRSendConfigNotify(ScreenPtr pScreen)
.u.configureNotify.override = pWin->overrideRedirect .u.configureNotify.override = pWin->overrideRedirect
}; };
event.u.u.type = ConfigureNotify; event.u.u.type = ConfigureNotify;
DeliverEvents(pWin, &event, 1, NullWindow); dixDeliverEvents(pWin, &event, 1, NullWindow);
} }
void void

View File

@ -128,7 +128,7 @@ xtest_properties(void)
{ {
int rc; int rc;
char value = 1; char value = 1;
XIPropertyValuePtr prop; PropertyValuePtr prop;
Atom xtest_prop; Atom xtest_prop;
xtest_init(); xtest_init();

View File

@ -351,10 +351,10 @@ SetUpRemap(InputLine * line, RemapSpec * remap)
static Bool static Bool
MatchOneOf(const char *wanted, const char *vals_defined) MatchOneOf(const char *wanted, const char *vals_defined)
{ {
const char *str, *next;
int want_len = strlen(wanted); int want_len = strlen(wanted);
for (str = vals_defined, next = NULL; str != NULL; str = next) { const char *str, *next = NULL;
for (str = vals_defined; str != NULL; str = next) {
int len; int len;
next = strchr(str, ','); next = strchr(str, ',');
@ -377,11 +377,6 @@ static Bool
CheckLine(InputLine * line, CheckLine(InputLine * line,
RemapSpec * remap, XkbRF_RulePtr rule, XkbRF_GroupPtr group) RemapSpec * remap, XkbRF_RulePtr rule, XkbRF_GroupPtr group)
{ {
char *str, *tok;
register int nread;
_Xstrtokparams strtok_buf;
Bool append = FALSE;
if (line && line->line && line->line[0] == '!') { if (line && line->line && line->line[0] == '!') {
if (line->line[1] == '$' || if (line->line[1] == '$' ||
(line->line[1] == ' ' && line->line[2] == '$')) { (line->line[1] == ' ' && line->line[2] == '$')) {
@ -424,7 +419,13 @@ CheckLine(InputLine * line,
FileSpec tmp = { 0 }; FileSpec tmp = { 0 };
str = line->line; char *str = line->line;
int nread;
_Xstrtokparams strtok_buf;
char *tok;
Bool append = FALSE;
for (nread = 0; (tok = _XStrtok(str, " ", strtok_buf)) != NULL; nread++) { for (nread = 0; (tok = _XStrtok(str, " ", strtok_buf)) != NULL; nread++) {
str = NULL; str = NULL;
if (strcmp(tok, "=") == 0) { if (strcmp(tok, "=") == 0) {
@ -480,11 +481,9 @@ CheckLine(InputLine * line,
static char * static char *
_Concat(char *str1, const char *str2) _Concat(char *str1, const char *str2)
{ {
int len;
if ((!str1) || (!str2)) if ((!str1) || (!str2))
return str1; return str1;
len = strlen(str1) + strlen(str2) + 1; int len = strlen(str1) + strlen(str2) + 1;
str1 = realloc(str1, len * sizeof(char)); str1 = realloc(str1, len * sizeof(char));
if (str1) if (str1)
strcat(str1, str2); strcat(str1, str2);
@ -505,10 +504,10 @@ squeeze_spaces(char *p1)
static Bool static Bool
MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs) MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
{ {
char *options;
memset((char *) mdefs, 0, sizeof(XkbRF_MultiDefsRec)); memset((char *) mdefs, 0, sizeof(XkbRF_MultiDefsRec));
mdefs->model = defs->model; mdefs->model = defs->model;
options = Xstrdup(defs->options);
char *options = Xstrdup(defs->options);
if (options) if (options)
squeeze_spaces(options); squeeze_spaces(options);
mdefs->options = options; mdefs->options = options;
@ -518,15 +517,12 @@ MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
mdefs->layout[0] = defs->layout; mdefs->layout[0] = defs->layout;
} }
else { else {
char *p; char *layout = Xstrdup(defs->layout);
char *layout;
layout = Xstrdup(defs->layout);
if (layout == NULL) if (layout == NULL)
return FALSE; return FALSE;
squeeze_spaces(layout); squeeze_spaces(layout);
mdefs->layout[1] = layout; mdefs->layout[1] = layout;
p = layout; char *p = layout;
for (int i = 2; i <= XkbNumKbdGroups; i++) { for (int i = 2; i <= XkbNumKbdGroups; i++) {
if ((p = strchr(p, ','))) { if ((p = strchr(p, ','))) {
*p++ = '\0'; *p++ = '\0';
@ -546,15 +542,12 @@ MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
mdefs->variant[0] = defs->variant; mdefs->variant[0] = defs->variant;
} }
else { else {
char *p; char *variant = Xstrdup(defs->variant);
char *variant;
variant = Xstrdup(defs->variant);
if (variant == NULL) if (variant == NULL)
return FALSE; return FALSE;
squeeze_spaces(variant); squeeze_spaces(variant);
mdefs->variant[1] = variant; mdefs->variant[1] = variant;
p = variant; char *p = variant;
for (int i = 2; i <= XkbNumKbdGroups; i++) { for (int i = 2; i <= XkbNumKbdGroups; i++) {
if ((p = strchr(p, ','))) { if ((p = strchr(p, ','))) {
*p++ = '\0'; *p++ = '\0';