Compare commits
14 Commits
master
...
incubate_n
Author | SHA1 | Date | |
---|---|---|---|
|
aa49563def | ||
|
bd3232404b | ||
|
92e9176def | ||
|
e2901cd496 | ||
|
4f8b584717 | ||
|
611055db8d | ||
|
04cd1ac05a | ||
|
a46077cfc9 | ||
|
07d67a07e2 | ||
|
628e36226c | ||
|
2ba1178e22 | ||
|
db18f717ac | ||
|
fba0c84ab5 | ||
|
8b5aaebdb9 |
|
@ -191,8 +191,22 @@ mingw-cross-build:
|
|||
extends: .common-build-and-test
|
||||
script:
|
||||
- .gitlab-ci/meson-build.sh --run-install
|
||||
- find / -name libX*.dll
|
||||
variables:
|
||||
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:
|
||||
stage: build-and-test
|
||||
|
|
|
@ -583,7 +583,7 @@ InitXTestDevices(void)
|
|||
*/
|
||||
static int
|
||||
DeviceSetXTestProperty(DeviceIntPtr dev, Atom property,
|
||||
XIPropertyValuePtr prop, BOOL checkonly)
|
||||
PropertyValuePtr prop, BOOL checkonly)
|
||||
{
|
||||
if (property == XIGetKnownProperty(XI_PROP_XTEST_DEVICE))
|
||||
return BadAccess;
|
||||
|
|
|
@ -244,7 +244,7 @@ get_property(ClientPtr client, DeviceIntPtr dev, Atom property, Atom type,
|
|||
unsigned long n, len, ind;
|
||||
int rc;
|
||||
XIPropertyPtr prop;
|
||||
XIPropertyValuePtr prop_value;
|
||||
PropertyValuePtr prop_value;
|
||||
|
||||
if (!ValidAtom(property)) {
|
||||
client->errorValue = property;
|
||||
|
@ -418,7 +418,7 @@ XIResetProperties(void)
|
|||
* @return Success or the error code if an error occurred.
|
||||
*/
|
||||
int
|
||||
XIPropToInt(XIPropertyValuePtr val, int *nelem_return, int **buf_return)
|
||||
XIPropToInt(PropertyValuePtr val, int *nelem_return, int **buf_return)
|
||||
{
|
||||
int i;
|
||||
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.
|
||||
*/
|
||||
int
|
||||
XIPropToFloat(XIPropertyValuePtr val, int *nelem_return, float **buf_return)
|
||||
XIPropToFloat(PropertyValuePtr val, int *nelem_return, float **buf_return)
|
||||
{
|
||||
int i;
|
||||
float *buf;
|
||||
|
@ -528,11 +528,11 @@ long
|
|||
XIRegisterPropertyHandler(DeviceIntPtr dev,
|
||||
int (*SetProperty) (DeviceIntPtr dev,
|
||||
Atom property,
|
||||
XIPropertyValuePtr prop,
|
||||
PropertyValuePtr prop,
|
||||
BOOL checkonly),
|
||||
int (*GetProperty) (DeviceIntPtr dev,
|
||||
Atom property),
|
||||
int (*DeleteProperty) (DeviceIntPtr dev,
|
||||
int (*DelProperty) (DeviceIntPtr dev,
|
||||
Atom property))
|
||||
{
|
||||
XIPropertyHandlerPtr new_handler;
|
||||
|
@ -544,7 +544,7 @@ XIRegisterPropertyHandler(DeviceIntPtr dev,
|
|||
new_handler->id = XIPropHandlerID++;
|
||||
new_handler->SetProperty = SetProperty;
|
||||
new_handler->GetProperty = GetProperty;
|
||||
new_handler->DeleteProperty = DeleteProperty;
|
||||
new_handler->DeleteProperty = DelProperty;
|
||||
new_handler->next = dev->properties.handlers;
|
||||
dev->properties.handlers = new_handler;
|
||||
|
||||
|
@ -687,8 +687,8 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
|
|||
XIPropertyPtr prop;
|
||||
int size_in_bytes;
|
||||
unsigned long total_len;
|
||||
XIPropertyValuePtr prop_value;
|
||||
XIPropertyValueRec new_value;
|
||||
PropertyValuePtr prop_value;
|
||||
PropertyValueRec new_value;
|
||||
Bool add = FALSE;
|
||||
int rc;
|
||||
|
||||
|
@ -804,7 +804,7 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
|
|||
}
|
||||
|
||||
int
|
||||
XIGetDeviceProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr *value)
|
||||
XIGetDeviceProperty(DeviceIntPtr dev, Atom property, PropertyValuePtr *value)
|
||||
{
|
||||
XIPropertyPtr prop = XIFetchDeviceProperty(dev, property);
|
||||
int rc;
|
||||
|
|
|
@ -474,7 +474,7 @@ TellNoMap(WindowPtr pwin, Colormap * pmid)
|
|||
#ifdef XINERAMA
|
||||
if (noPanoramiXExtension || !pwin->drawable.pScreen->myNum)
|
||||
#endif /* XINERAMA */
|
||||
DeliverEvents(pwin, &xE, 1, (WindowPtr) NULL);
|
||||
dixDeliverEvents(pwin, &xE, 1, (WindowPtr) NULL);
|
||||
if (pwin->optional) {
|
||||
pwin->optional->colormap = None;
|
||||
CheckWindowOptionalNeed(pwin);
|
||||
|
@ -503,7 +503,7 @@ TellLostMap(WindowPtr pwin, void *value)
|
|||
.u.colormap.state = ColormapUninstalled
|
||||
};
|
||||
xE.u.u.type = ColormapNotify;
|
||||
DeliverEvents(pwin, &xE, 1, (WindowPtr) NULL);
|
||||
dixDeliverEvents(pwin, &xE, 1, (WindowPtr) NULL);
|
||||
}
|
||||
|
||||
return WT_WALKCHILDREN;
|
||||
|
@ -528,7 +528,7 @@ TellGainedMap(WindowPtr pwin, void *value)
|
|||
.u.colormap.state = ColormapInstalled
|
||||
};
|
||||
xE.u.u.type = ColormapNotify;
|
||||
DeliverEvents(pwin, &xE, 1, (WindowPtr) NULL);
|
||||
dixDeliverEvents(pwin, &xE, 1, (WindowPtr) NULL);
|
||||
}
|
||||
|
||||
return WT_WALKCHILDREN;
|
||||
|
|
|
@ -147,7 +147,7 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform_data)
|
|||
* DIX property handler.
|
||||
*/
|
||||
static int
|
||||
DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
|
||||
DeviceSetProperty(DeviceIntPtr dev, Atom property, PropertyValuePtr prop,
|
||||
BOOL checkonly)
|
||||
{
|
||||
if (property == XIGetKnownProperty(XI_PROP_ENABLED)) {
|
||||
|
|
|
@ -2944,7 +2944,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
|
|||
* @return event delivery state (@see 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;
|
||||
int deliveries;
|
||||
|
|
|
@ -155,8 +155,8 @@ void XTestDeviceSendEvents(DeviceIntPtr dev,
|
|||
int flags,
|
||||
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 */
|
||||
|
|
|
@ -24,6 +24,7 @@ srcs_dix = [
|
|||
'pixmap.c',
|
||||
'privates.c',
|
||||
'property.c',
|
||||
'property_list.c',
|
||||
'ptrveloc.c',
|
||||
'region.c',
|
||||
'registry.c',
|
||||
|
|
132
dix/property.c
132
dix/property.c
|
@ -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) {
|
||||
|
@ -166,7 +166,7 @@ deliverPropertyNotifyEvent(WindowPtr pWin, int state, PropertyPtr pProp)
|
|||
};
|
||||
event.u.u.type = PropertyNotify;
|
||||
|
||||
DeliverEvents(pWin, &event, 1, (WindowPtr) NULL);
|
||||
dixDeliverEvents(pWin, &event, 1, (WindowPtr) NULL);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -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:
|
||||
|
@ -325,11 +325,9 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
|
|||
{
|
||||
PropertyPtr pProp;
|
||||
PropertyRec savedProp;
|
||||
int sizeInBytes, totalSize, rc;
|
||||
int rc;
|
||||
Mask access_mode;
|
||||
|
||||
sizeInBytes = format >> 3;
|
||||
totalSize = len * sizeInBytes;
|
||||
access_mode = (mode == PropModeReplace) ? DixWriteAccess : DixBlendAccess;
|
||||
|
||||
/* 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 (!MakeWindowOptional(pWin))
|
||||
return BadAlloc;
|
||||
pProp = dixAllocateObjectWithPrivates(PropertyRec, PRIVATE_PROPERTY);
|
||||
|
||||
pProp = dixPropertyCreate(type, property, format, len, value);
|
||||
if (!pProp)
|
||||
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,
|
||||
DixCreateAccess | DixWriteAccess);
|
||||
if (rc != Success) {
|
||||
free(data);
|
||||
dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
|
||||
dixPropertyFree(pProp);
|
||||
pClient->errorValue = property;
|
||||
return rc;
|
||||
}
|
||||
|
@ -366,14 +352,17 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
|
|||
pWin->properties = pProp;
|
||||
}
|
||||
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
|
||||
must match those of the already defined property. The
|
||||
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 */
|
||||
|
@ -386,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;
|
||||
}
|
||||
|
@ -441,7 +430,7 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
|
|||
int
|
||||
DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName)
|
||||
{
|
||||
PropertyPtr pProp, prevProp;
|
||||
PropertyPtr pProp;
|
||||
int rc;
|
||||
|
||||
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 */
|
||||
|
||||
if (rc == Success) {
|
||||
if (pWin->properties == pProp) {
|
||||
/* Takes care of head */
|
||||
if (!(pWin->properties = pProp->next))
|
||||
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;
|
||||
}
|
||||
dixPropertyUnlinkPtr(&pWin->properties, pProp);
|
||||
if (!pWin->properties)
|
||||
CheckWindowOptionalNeed(pWin);
|
||||
|
||||
deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp);
|
||||
notifyVRRMode(client, pWin, PropertyDelete, pProp);
|
||||
free(pProp->data);
|
||||
dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
|
||||
dixPropertyFree(pProp);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -473,17 +452,13 @@ DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName)
|
|||
void
|
||||
DeleteAllWindowProperties(WindowPtr pWin)
|
||||
{
|
||||
PropertyPtr pProp = pWin->properties;
|
||||
PropertyPtr pProp;
|
||||
|
||||
while (pProp) {
|
||||
while ((pProp = pWin->properties)) {
|
||||
deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp);
|
||||
PropertyPtr pNextProp = pProp->next;
|
||||
free(pProp->data);
|
||||
dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
|
||||
pProp = pNextProp;
|
||||
dixPropertyUnlinkPtr(&pWin->properties, pProp);
|
||||
dixPropertyFree(pProp);
|
||||
}
|
||||
|
||||
pWin->properties = NULL;
|
||||
}
|
||||
|
||||
/*****************
|
||||
|
@ -564,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);
|
||||
|
@ -584,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
|
||||
|
@ -601,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)) {
|
||||
|
@ -615,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 */
|
||||
|
@ -632,8 +607,7 @@ ProcGetProperty(ClientPtr client)
|
|||
prevProp->next = pProp->next;
|
||||
}
|
||||
|
||||
free(pProp->data);
|
||||
dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
|
||||
dixPropertyFree(pProp);
|
||||
}
|
||||
|
||||
if (client->swapped) {
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -53,6 +53,8 @@ SOFTWARE.
|
|||
|
||||
#include <X11/X.h>
|
||||
|
||||
#include "include/privates.h"
|
||||
|
||||
#include "dix.h"
|
||||
#include "window.h"
|
||||
#include "property.h"
|
||||
|
@ -99,4 +101,36 @@ int dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom proprty,
|
|||
|
||||
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 */
|
||||
|
|
|
@ -191,7 +191,7 @@ AccelerationDefaultCleanup(DeviceIntPtr dev)
|
|||
*/
|
||||
static int
|
||||
AccelSetProfileProperty(DeviceIntPtr dev, Atom atom,
|
||||
XIPropertyValuePtr val, BOOL checkOnly)
|
||||
PropertyValuePtr val, BOOL checkOnly)
|
||||
{
|
||||
DeviceVelocityPtr vel;
|
||||
int profile, *ptr = &profile;
|
||||
|
@ -236,7 +236,7 @@ AccelInitProfileProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
|
|||
*/
|
||||
static int
|
||||
AccelSetDecelProperty(DeviceIntPtr dev, Atom atom,
|
||||
XIPropertyValuePtr val, BOOL checkOnly)
|
||||
PropertyValuePtr val, BOOL checkOnly)
|
||||
{
|
||||
DeviceVelocityPtr vel;
|
||||
float v, *ptr = &v;
|
||||
|
@ -280,7 +280,7 @@ AccelInitDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
|
|||
*/
|
||||
static int
|
||||
AccelSetAdaptDecelProperty(DeviceIntPtr dev, Atom atom,
|
||||
XIPropertyValuePtr val, BOOL checkOnly)
|
||||
PropertyValuePtr val, BOOL checkOnly)
|
||||
{
|
||||
DeviceVelocityPtr veloc;
|
||||
float v, *ptr = &v;
|
||||
|
@ -327,7 +327,7 @@ AccelInitAdaptDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
|
|||
*/
|
||||
static int
|
||||
AccelSetScaleProperty(DeviceIntPtr dev, Atom atom,
|
||||
XIPropertyValuePtr val, BOOL checkOnly)
|
||||
PropertyValuePtr val, BOOL checkOnly)
|
||||
{
|
||||
DeviceVelocityPtr vel;
|
||||
float v, *ptr = &v;
|
||||
|
|
30
dix/window.c
30
dix/window.c
|
@ -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;
|
||||
}
|
||||
|
@ -931,7 +931,7 @@ dixCreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w,
|
|||
.u.createNotify.override = pWin->overrideRedirect
|
||||
};
|
||||
event.u.u.type = CreateNotify;
|
||||
DeliverEvents(pParent, &event, 1, NullWindow);
|
||||
dixDeliverEvents(pParent, &event, 1, NullWindow);
|
||||
}
|
||||
return pWin;
|
||||
}
|
||||
|
@ -1018,7 +1018,7 @@ CrushTree(WindowPtr pWin)
|
|||
if (SubStrSend(pChild, pParent)) {
|
||||
xEvent event = { .u.u.type = DestroyNotify };
|
||||
event.u.destroyNotify.window = pChild->drawable.id;
|
||||
DeliverEvents(pChild, &event, 1, NullWindow);
|
||||
dixDeliverEvents(pChild, &event, 1, NullWindow);
|
||||
}
|
||||
FreeResource(pChild->drawable.id, X11_RESTYPE_WINDOW);
|
||||
pSib = pChild->nextSib;
|
||||
|
@ -1060,7 +1060,7 @@ DeleteWindow(void *value, XID wid)
|
|||
if (wid && pParent && SubStrSend(pWin, pParent)) {
|
||||
xEvent event = { .u.u.type = DestroyNotify };
|
||||
event.u.destroyNotify.window = pWin->drawable.id;
|
||||
DeliverEvents(pWin, &event, 1, NullWindow);
|
||||
dixDeliverEvents(pWin, &event, 1, NullWindow);
|
||||
}
|
||||
|
||||
FreeWindowResources(pWin);
|
||||
|
@ -1455,7 +1455,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
|
|||
.u.colormap.state = IsMapInstalled(cmap, pWin)
|
||||
};
|
||||
xE.u.u.type = ColormapNotify;
|
||||
DeliverEvents(pWin, &xE, 1, NullWindow);
|
||||
dixDeliverEvents(pWin, &xE, 1, NullWindow);
|
||||
}
|
||||
break;
|
||||
case CWCursor:
|
||||
|
@ -1851,7 +1851,7 @@ ResizeChildrenWinSize(WindowPtr pWin, int dx, int dy, int dw, int dh)
|
|||
.u.gravity.y = cwsy - wBorderWidth(pSib)
|
||||
};
|
||||
event.u.u.type = GravityNotify;
|
||||
DeliverEvents(pSib, &event, 1, NullWindow);
|
||||
dixDeliverEvents(pSib, &event, 1, NullWindow);
|
||||
pSib->origin.x = cwsx;
|
||||
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;
|
||||
}
|
||||
#endif /* XINERAMA */
|
||||
DeliverEvents(pWin, &event, 1, NullWindow);
|
||||
dixDeliverEvents(pWin, &event, 1, NullWindow);
|
||||
}
|
||||
if (mask & CWBorderWidth) {
|
||||
if (action == RESTACK_WIN) {
|
||||
|
@ -2462,7 +2462,7 @@ CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
|
|||
}
|
||||
|
||||
event.u.u.type = CirculateNotify;
|
||||
DeliverEvents(pWin, &event, 1, NullWindow);
|
||||
dixDeliverEvents(pWin, &event, 1, NullWindow);
|
||||
ReflectStackChange(pWin,
|
||||
(direction == RaiseLowest) ? pFirst : NullWindow,
|
||||
VTStack);
|
||||
|
@ -2519,7 +2519,7 @@ ReparentWindow(WindowPtr pWin, WindowPtr pParent,
|
|||
event.u.reparent.y += screenInfo.screens[0]->y;
|
||||
}
|
||||
#endif /* XINERAMA */
|
||||
DeliverEvents(pWin, &event, 1, pParent);
|
||||
dixDeliverEvents(pWin, &event, 1, pParent);
|
||||
|
||||
/* take out of sibling chain */
|
||||
|
||||
|
@ -2627,7 +2627,7 @@ DeliverMapNotify(WindowPtr pWin)
|
|||
.u.mapNotify.override = pWin->overrideRedirect,
|
||||
};
|
||||
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
|
||||
};
|
||||
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
|
||||
};
|
||||
event.u.u.type = VisibilityNotify;
|
||||
DeliverEvents(pWin, &event, 1, NullWindow);
|
||||
dixDeliverEvents(pWin, &event, 1, NullWindow);
|
||||
}
|
||||
|
||||
#define RANDOM_WIDTH 32
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
srcs_xorg_compat = [
|
||||
'clientexception.c',
|
||||
'deliverevents.c',
|
||||
'log.c',
|
||||
'ones.c',
|
||||
'xf86Helper.c',
|
||||
|
|
|
@ -3169,7 +3169,7 @@ drmmode_output_create_resources(xf86OutputPtr output)
|
|||
|
||||
static Bool
|
||||
drmmode_output_set_property(xf86OutputPtr output, Atom property,
|
||||
RRPropertyValuePtr value)
|
||||
PropertyValuePtr value)
|
||||
{
|
||||
drmmode_output_private_ptr drmmode_output = output->driver_private;
|
||||
drmmode_ptr drmmode = drmmode_output->drmmode;
|
||||
|
|
|
@ -509,7 +509,7 @@ typedef struct _xf86OutputFuncs {
|
|||
*/
|
||||
Bool
|
||||
(*set_property) (xf86OutputPtr output,
|
||||
Atom property, RRPropertyValuePtr value);
|
||||
Atom property, PropertyValuePtr value);
|
||||
#endif
|
||||
#ifdef RANDR_13_INTERFACE
|
||||
/**
|
||||
|
@ -668,7 +668,7 @@ typedef struct _xf86ProviderFuncs {
|
|||
*/
|
||||
Bool
|
||||
(*set_property) (ScrnInfoPtr scrn,
|
||||
Atom property, RRPropertyValuePtr value);
|
||||
Atom property, PropertyValuePtr value);
|
||||
|
||||
/**
|
||||
* Callback to get an updated property value
|
||||
|
|
|
@ -1524,7 +1524,7 @@ xf86RandR12InitGamma(ScrnInfoPtr pScrn, unsigned gammaSize) {
|
|||
static Bool
|
||||
xf86RandR12OutputSetProperty(ScreenPtr pScreen,
|
||||
RROutputPtr randr_output,
|
||||
Atom property, RRPropertyValuePtr value)
|
||||
Atom property, PropertyValuePtr value)
|
||||
{
|
||||
xf86OutputPtr output = randr_output->devPrivate;
|
||||
|
||||
|
@ -2144,7 +2144,7 @@ xf86RandR14ProviderSetOffloadSink(ScreenPtr pScreen,
|
|||
static Bool
|
||||
xf86RandR14ProviderSetProperty(ScreenPtr pScreen,
|
||||
RRProviderPtr randr_provider,
|
||||
Atom property, RRPropertyValuePtr value)
|
||||
Atom property, PropertyValuePtr value)
|
||||
{
|
||||
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -148,9 +148,10 @@ xnestChangeGC(GCPtr pGC, unsigned long mask)
|
|||
if (mask & GCTileStipYOrigin)
|
||||
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;
|
||||
|
||||
}
|
||||
if (mask & GCSubwindowMode)
|
||||
values.subwindow_mode = pGC->subWindowMode;
|
||||
|
||||
|
|
|
@ -190,8 +190,10 @@ xnestBitBlitHelper(GCPtr pGC)
|
|||
default:
|
||||
{
|
||||
struct xnest_event_queue *q = malloc(sizeof(struct xnest_event_queue));
|
||||
q->event = event;
|
||||
xorg_list_add(&q->entry, &xnestUpstreamInfo.eventQueue.entry);
|
||||
if (q) {
|
||||
q->event = event;
|
||||
xorg_list_add(&q->entry, &xnestUpstreamInfo.eventQueue.entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
int const bufsize = sizeof(xTextElt) + count;
|
||||
uint8_t *buffer = malloc(bufsize);
|
||||
if (!buffer)
|
||||
return 0;
|
||||
|
||||
xTextElt *elt = (xTextElt*)buffer;
|
||||
elt->len = count;
|
||||
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()
|
||||
int const bufsize = sizeof(xTextElt) + count*2;
|
||||
uint8_t *buffer = malloc(bufsize);
|
||||
if (!buffer)
|
||||
return 0;
|
||||
xTextElt *elt = (xTextElt*)buffer;
|
||||
elt->len = count;
|
||||
elt->delta = 0;
|
||||
|
|
|
@ -293,6 +293,7 @@ breakout:
|
|||
|
||||
if (!found_default_visual) {
|
||||
ErrorF("Xnest: can't find matching visual for user specified depth %d\n", xnestDefaultDepth);
|
||||
assert(visuals);
|
||||
defaultVisual = visuals[0].vid;
|
||||
rootDepth = visuals[0].nplanes;
|
||||
}
|
||||
|
|
|
@ -440,7 +440,8 @@ xnestShapeWindow(WindowPtr pWin)
|
|||
int const num_rects = RegionNumRects(xnestWindowPriv(pWin)->bounding_shape);
|
||||
BoxPtr const pBox = RegionRects(xnestWindowPriv(pWin)->bounding_shape);
|
||||
xcb_rectangle_t *rects = calloc(num_rects, sizeof(xcb_rectangle_t));
|
||||
|
||||
if (!rects)
|
||||
return;
|
||||
for (int i = 0; i < num_rects; i++) {
|
||||
rects[i].x = pBox[i].x1;
|
||||
rects[i].y = pBox[i].y1;
|
||||
|
@ -469,7 +470,8 @@ xnestShapeWindow(WindowPtr pWin)
|
|||
int const num_rects = RegionNumRects(xnestWindowPriv(pWin)->clip_shape);
|
||||
BoxPtr const pBox = RegionRects(xnestWindowPriv(pWin)->clip_shape);
|
||||
xcb_rectangle_t *rects = calloc(num_rects, sizeof(xcb_rectangle_t));
|
||||
|
||||
if (!rects)
|
||||
return;
|
||||
for (int i = 0; i < num_rects; i++) {
|
||||
rects[i].x = pBox[i].x1;
|
||||
rects[i].y = pBox[i].y1;
|
||||
|
|
|
@ -303,7 +303,7 @@ QuartzUpdateScreens(void)
|
|||
e.u.configureNotify.height = height;
|
||||
e.u.configureNotify.borderWidth = wBorderWidth(pRoot);
|
||||
e.u.configureNotify.override = pRoot->overrideRedirect;
|
||||
DeliverEvents(pRoot, &e, 1, NullWindow);
|
||||
dixDeliverEvents(pRoot, &e, 1, NullWindow);
|
||||
|
||||
quartzProcs->UpdateScreen(pScreen);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -92,7 +92,7 @@ extern _X_EXPORT int XIChangeDeviceProperty(DeviceIntPtr /* dev */ ,
|
|||
|
||||
extern _X_EXPORT int XIGetDeviceProperty(DeviceIntPtr /* dev */ ,
|
||||
Atom /* property */ ,
|
||||
XIPropertyValuePtr * /* value */
|
||||
PropertyValuePtr * /* value */
|
||||
);
|
||||
|
||||
extern _X_EXPORT int XISetDevicePropertyDeletable(DeviceIntPtr /* dev */ ,
|
||||
|
@ -105,7 +105,7 @@ extern _X_EXPORT long XIRegisterPropertyHandler(DeviceIntPtr dev,
|
|||
dev,
|
||||
Atom
|
||||
property,
|
||||
XIPropertyValuePtr
|
||||
PropertyValuePtr
|
||||
prop,
|
||||
BOOL
|
||||
checkonly),
|
||||
|
|
|
@ -55,6 +55,7 @@ SOFTWARE.
|
|||
#include "dixstruct.h"
|
||||
#include "cursorstr.h"
|
||||
#include "privates.h"
|
||||
#include "property_value.h"
|
||||
|
||||
#define BitIsOn(ptr, bit) (!!(((const 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;
|
||||
|
||||
/* Device properties */
|
||||
typedef struct _XIPropertyValue {
|
||||
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 */
|
||||
} XIPropertyValueRec;
|
||||
|
||||
/* for backwards compat with older drivers, should not be used anymore */
|
||||
typedef PropertyValueRec XIPropertyValueRec, *XIPropertyValuePtr;
|
||||
|
||||
typedef struct _XIProperty {
|
||||
struct _XIProperty *next;
|
||||
Atom propertyName;
|
||||
BOOL deletable; /* clients can delete this prop? */
|
||||
XIPropertyValueRec value;
|
||||
PropertyValueRec value;
|
||||
} XIPropertyRec;
|
||||
|
||||
typedef XIPropertyRec *XIPropertyPtr;
|
||||
typedef XIPropertyValueRec *XIPropertyValuePtr;
|
||||
|
||||
typedef struct _XIPropertyHandler {
|
||||
struct _XIPropertyHandler *next;
|
||||
long id;
|
||||
int (*SetProperty) (DeviceIntPtr dev,
|
||||
Atom property, XIPropertyValuePtr prop, BOOL checkonly);
|
||||
Atom property, PropertyValuePtr prop, BOOL checkonly);
|
||||
int (*GetProperty) (DeviceIntPtr dev, Atom property);
|
||||
int (*DeleteProperty) (DeviceIntPtr dev, Atom property);
|
||||
} XIPropertyHandler, *XIPropertyHandlerPtr;
|
||||
|
|
|
@ -458,6 +458,7 @@ if build_xorg
|
|||
'pixmapstr.h',
|
||||
'privates.h',
|
||||
'property.h',
|
||||
'property_value.h',
|
||||
'ptrveloc.h',
|
||||
'region.h',
|
||||
'regionstr.h',
|
||||
|
|
|
@ -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 */
|
|
@ -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,11 +59,9 @@ 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;
|
||||
Bool deletable;
|
||||
} PropertyRec;
|
||||
|
||||
#endif /* PROPERTYSTRUCT_H */
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// exports scan complete
|
||||
|
||||
/************************************************************
|
||||
Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
|
|
10
meson.build
10
meson.build
|
@ -48,6 +48,16 @@ if cc.get_id() == 'gcc' or cc.get_id() == 'clang'
|
|||
'-Werror=int-to-pointer-cast',
|
||||
'-Werror=pointer-to-int-cast',
|
||||
'-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
|
||||
test_wflags = []
|
||||
|
|
|
@ -351,7 +351,7 @@ miSendExposures(WindowPtr pWin, RegionPtr pRgn, int dx, int dy)
|
|||
}
|
||||
#endif /* XINERAMA */
|
||||
|
||||
DeliverEvents(pWin, pEvent, numRects, NullWindow);
|
||||
dixDeliverEvents(pWin, pEvent, numRects, NullWindow);
|
||||
|
||||
free(pEvent);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "scrnintstr.h"
|
||||
#include "windowstr.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "property_value.h"
|
||||
#include "extnsionst.h"
|
||||
#include "servermd.h"
|
||||
#include "rrtransform.h"
|
||||
|
@ -71,7 +72,8 @@ typedef XID RRLease;
|
|||
|
||||
#define RRModeName(pMode) ((char *) (pMode + 1))
|
||||
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 _rrCrtc RRCrtcRec, *RRCrtcPtr;
|
||||
typedef struct _rrOutput RROutputRec, *RROutputPtr;
|
||||
|
@ -86,13 +88,6 @@ struct _rrMode {
|
|||
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 {
|
||||
RRPropertyPtr next;
|
||||
ATOM propertyName;
|
||||
|
@ -101,7 +96,8 @@ struct _rrProperty {
|
|||
Bool immutable;
|
||||
int num_valid;
|
||||
INT32 *valid_values;
|
||||
RRPropertyValueRec current, pending;
|
||||
PropertyValueRec current;
|
||||
PropertyValueRec pending;
|
||||
};
|
||||
|
||||
struct _rrCrtc {
|
||||
|
@ -224,7 +220,7 @@ typedef Bool (*RRCrtcGetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc);
|
|||
typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen,
|
||||
RROutputPtr output,
|
||||
Atom property,
|
||||
RRPropertyValuePtr value);
|
||||
PropertyValuePtr value);
|
||||
|
||||
typedef Bool (*RROutputValidateModeProcPtr) (ScreenPtr pScreen,
|
||||
RROutputPtr output,
|
||||
|
@ -253,7 +249,7 @@ typedef Bool (*RRProviderGetPropertyProcPtr) (ScreenPtr pScreen,
|
|||
typedef Bool (*RRProviderSetPropertyProcPtr) (ScreenPtr pScreen,
|
||||
RRProviderPtr provider,
|
||||
Atom property,
|
||||
RRPropertyValuePtr value);
|
||||
PropertyValuePtr value);
|
||||
|
||||
typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation * rotations);
|
||||
typedef Bool (*RRCloseScreenProcPtr) (ScreenPtr pscreen);
|
||||
|
|
|
@ -459,7 +459,7 @@ rrGetPixmapSharingSyncProp(int numOutputs, RROutputPtr * outputs)
|
|||
|
||||
/* If one output doesn't want sync, no sync */
|
||||
for (o = 0; o < numOutputs; o++) {
|
||||
RRPropertyValuePtr val;
|
||||
PropertyValuePtr val;
|
||||
|
||||
if ((val = RRGetOutputProperty(outputs[o], syncProp, TRUE)) &&
|
||||
val->data) {
|
||||
|
@ -715,7 +715,7 @@ rrCheckEmulated(RROutputPtr output)
|
|||
{
|
||||
const char *emulStr = XRANDR_EMULATION_PROP;
|
||||
Atom emulProp;
|
||||
RRPropertyValuePtr val;
|
||||
PropertyValuePtr val;
|
||||
|
||||
emulProp = MakeAtom(emulStr, strlen(emulStr), FALSE);
|
||||
if (emulProp == None)
|
||||
|
|
|
@ -97,7 +97,7 @@ RRDeleteAllOutputProperties(RROutputPtr output)
|
|||
}
|
||||
|
||||
static void
|
||||
RRInitOutputPropertyValue(RRPropertyValuePtr property_value)
|
||||
RRInitOutputPropertyValue(PropertyValuePtr property_value)
|
||||
{
|
||||
property_value->type = None;
|
||||
property_value->format = 0;
|
||||
|
@ -137,7 +137,7 @@ RRDeleteOutputProperty(RROutputPtr output, Atom property)
|
|||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
int size_in_bytes;
|
||||
unsigned long total_len;
|
||||
RRPropertyValuePtr prop_value;
|
||||
RRPropertyValueRec new_value;
|
||||
PropertyValuePtr prop_value;
|
||||
PropertyValueRec new_value;
|
||||
Bool add = FALSE;
|
||||
|
||||
size_in_bytes = format >> 3;
|
||||
|
@ -282,8 +282,8 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
|
|||
Bool
|
||||
RRPostPendingProperties(RROutputPtr output)
|
||||
{
|
||||
RRPropertyValuePtr pending_value;
|
||||
RRPropertyValuePtr current_value;
|
||||
PropertyValuePtr pending_value;
|
||||
PropertyValuePtr current_value;
|
||||
RRPropertyPtr property;
|
||||
Bool ret = TRUE;
|
||||
|
||||
|
@ -330,7 +330,7 @@ RRQueryOutputProperty(RROutputPtr output, Atom property)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
RRPropertyValuePtr
|
||||
PropertyValuePtr
|
||||
RRGetOutputProperty(RROutputPtr output, Atom property, Bool pending)
|
||||
{
|
||||
RRPropertyPtr prop = RRQueryOutputProperty(output, property);
|
||||
|
@ -621,7 +621,7 @@ ProcRRGetOutputProperty(ClientPtr client)
|
|||
{
|
||||
REQUEST(xRRGetOutputPropertyReq);
|
||||
RRPropertyPtr prop, *prev;
|
||||
RRPropertyValuePtr prop_value;
|
||||
PropertyValuePtr prop_value;
|
||||
unsigned long n, len, ind;
|
||||
RROutputPtr output;
|
||||
char *extra = NULL;
|
||||
|
|
|
@ -84,7 +84,7 @@ RRDeleteProperty(RRProviderRec * provider, RRPropertyRec * prop)
|
|||
}
|
||||
|
||||
static void
|
||||
RRInitProviderPropertyValue(RRPropertyValuePtr property_value)
|
||||
RRInitProviderPropertyValue(PropertyValuePtr property_value)
|
||||
{
|
||||
property_value->type = None;
|
||||
property_value->format = 0;
|
||||
|
@ -135,8 +135,8 @@ RRChangeProviderProperty(RRProviderPtr provider, Atom property, Atom type,
|
|||
int size_in_bytes;
|
||||
int total_size;
|
||||
unsigned long total_len;
|
||||
RRPropertyValuePtr prop_value;
|
||||
RRPropertyValueRec new_value;
|
||||
PropertyValuePtr prop_value;
|
||||
PropertyValueRec new_value;
|
||||
Bool add = FALSE;
|
||||
|
||||
size_in_bytes = format >> 3;
|
||||
|
@ -256,7 +256,7 @@ RRQueryProviderProperty(RRProviderPtr provider, Atom property)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
RRPropertyValuePtr
|
||||
PropertyValuePtr
|
||||
RRGetProviderProperty(RRProviderPtr provider, Atom property, Bool pending)
|
||||
{
|
||||
RRPropertyPtr prop = RRQueryProviderProperty(provider, property);
|
||||
|
@ -528,7 +528,7 @@ ProcRRGetProviderProperty(ClientPtr client)
|
|||
{
|
||||
REQUEST(xRRGetProviderPropertyReq);
|
||||
RRPropertyPtr prop, *prev;
|
||||
RRPropertyValuePtr prop_value;
|
||||
PropertyValuePtr prop_value;
|
||||
unsigned long n, len, ind;
|
||||
RRProviderPtr provider;
|
||||
xRRGetProviderPropertyReply reply = {
|
||||
|
|
|
@ -86,7 +86,7 @@ RRSendConfigNotify(ScreenPtr pScreen)
|
|||
.u.configureNotify.override = pWin->overrideRedirect
|
||||
};
|
||||
event.u.u.type = ConfigureNotify;
|
||||
DeliverEvents(pWin, &event, 1, NullWindow);
|
||||
dixDeliverEvents(pWin, &event, 1, NullWindow);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -128,7 +128,7 @@ xtest_properties(void)
|
|||
{
|
||||
int rc;
|
||||
char value = 1;
|
||||
XIPropertyValuePtr prop;
|
||||
PropertyValuePtr prop;
|
||||
Atom xtest_prop;
|
||||
|
||||
xtest_init();
|
||||
|
|
|
@ -351,10 +351,10 @@ SetUpRemap(InputLine * line, RemapSpec * remap)
|
|||
static Bool
|
||||
MatchOneOf(const char *wanted, const char *vals_defined)
|
||||
{
|
||||
const char *str, *next;
|
||||
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;
|
||||
|
||||
next = strchr(str, ',');
|
||||
|
@ -377,11 +377,6 @@ static Bool
|
|||
CheckLine(InputLine * line,
|
||||
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[1] == '$' ||
|
||||
(line->line[1] == ' ' && line->line[2] == '$')) {
|
||||
|
@ -424,7 +419,13 @@ CheckLine(InputLine * line,
|
|||
|
||||
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++) {
|
||||
str = NULL;
|
||||
if (strcmp(tok, "=") == 0) {
|
||||
|
@ -480,11 +481,9 @@ CheckLine(InputLine * line,
|
|||
static char *
|
||||
_Concat(char *str1, const char *str2)
|
||||
{
|
||||
int len;
|
||||
|
||||
if ((!str1) || (!str2))
|
||||
return str1;
|
||||
len = strlen(str1) + strlen(str2) + 1;
|
||||
int len = strlen(str1) + strlen(str2) + 1;
|
||||
str1 = realloc(str1, len * sizeof(char));
|
||||
if (str1)
|
||||
strcat(str1, str2);
|
||||
|
@ -505,10 +504,10 @@ squeeze_spaces(char *p1)
|
|||
static Bool
|
||||
MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
|
||||
{
|
||||
char *options;
|
||||
memset((char *) mdefs, 0, sizeof(XkbRF_MultiDefsRec));
|
||||
mdefs->model = defs->model;
|
||||
options = Xstrdup(defs->options);
|
||||
|
||||
char *options = Xstrdup(defs->options);
|
||||
if (options)
|
||||
squeeze_spaces(options);
|
||||
mdefs->options = options;
|
||||
|
@ -518,15 +517,12 @@ MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
|
|||
mdefs->layout[0] = defs->layout;
|
||||
}
|
||||
else {
|
||||
char *p;
|
||||
char *layout;
|
||||
|
||||
layout = Xstrdup(defs->layout);
|
||||
char *layout = Xstrdup(defs->layout);
|
||||
if (layout == NULL)
|
||||
return FALSE;
|
||||
squeeze_spaces(layout);
|
||||
mdefs->layout[1] = layout;
|
||||
p = layout;
|
||||
char *p = layout;
|
||||
for (int i = 2; i <= XkbNumKbdGroups; i++) {
|
||||
if ((p = strchr(p, ','))) {
|
||||
*p++ = '\0';
|
||||
|
@ -546,15 +542,12 @@ MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
|
|||
mdefs->variant[0] = defs->variant;
|
||||
}
|
||||
else {
|
||||
char *p;
|
||||
char *variant;
|
||||
|
||||
variant = Xstrdup(defs->variant);
|
||||
char *variant = Xstrdup(defs->variant);
|
||||
if (variant == NULL)
|
||||
return FALSE;
|
||||
squeeze_spaces(variant);
|
||||
mdefs->variant[1] = variant;
|
||||
p = variant;
|
||||
char *p = variant;
|
||||
for (int i = 2; i <= XkbNumKbdGroups; i++) {
|
||||
if ((p = strchr(p, ','))) {
|
||||
*p++ = '\0';
|
||||
|
|
Loading…
Reference in New Issue