diff options
-rw-r--r-- | randr/mirandr.c | 9 | ||||
-rw-r--r-- | randr/randrstr.h | 57 | ||||
-rw-r--r-- | randr/rrdispatch.c | 26 | ||||
-rw-r--r-- | randr/rrproperty.c | 370 | ||||
-rw-r--r-- | randr/rrsdispatch.c | 46 |
5 files changed, 384 insertions, 124 deletions
diff --git a/randr/mirandr.c b/randr/mirandr.c index 3a99bf9ed..0b763e111 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -64,10 +64,11 @@ miRRCrtcSetGamma (ScreenPtr pScreen, return TRUE; } -static Bool -miRROutputSetProperty (ScreenPtr pScreen, - RROutputPtr output, - Atom property) +Bool +miRROutputSetProperty (ScreenPtr pScreen, + RROutputPtr output, + Atom property, + RRPropertyValuePtr value) { return TRUE; } diff --git a/randr/randrstr.h b/randr/randrstr.h index 19af9b979..27ede9226 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -69,9 +69,11 @@ extern int (*SProcRandrVector[RRNumberRequests])(ClientPtr); */ #define RRModeName(pMode) ((char *) (pMode + 1)) -typedef struct _rrMode RRModeRec, *RRModePtr; -typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; -typedef struct _rrOutput RROutputRec, *RROutputPtr; +typedef struct _rrMode RRModeRec, *RRModePtr; +typedef struct _rrPropertyValue RRPropertyValueRec, *RRPropertyValuePtr; +typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr; +typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; +typedef struct _rrOutput RROutputRec, *RROutputPtr; struct _rrMode { int refcnt; @@ -81,6 +83,24 @@ struct _rrMode { Bool userDefined; }; +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 */ + pointer data; /* private to client */ +}; + +struct _rrProperty { + RRPropertyPtr next; + ATOM propertyName; + Bool is_pending; + Bool range; + Bool immutable; + int num_valid; + INT32 *valid_values; + RRPropertyValueRec current, pending; +}; + struct _rrCrtc { RRCrtc id; ScreenPtr pScreen; @@ -116,7 +136,7 @@ struct _rrOutput { int numPreferred; RRModePtr *modes; Bool changed; - PropertyPtr properties; + RRPropertyPtr properties; void *devPrivate; }; @@ -139,9 +159,10 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen, typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc); -typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen, - RROutputPtr output, - Atom property); +typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen, + RROutputPtr output, + Atom property, + RRPropertyValuePtr value); #endif @@ -363,6 +384,12 @@ miRRCrtcSet (ScreenPtr pScreen, int numOutput, RROutputPtr *outputs); +Bool +miRROutputSetProperty (ScreenPtr pScreen, + RROutputPtr output, + Atom property, + RRPropertyValuePtr value); + /* randr.c */ /* * Send all pending events @@ -676,6 +703,12 @@ RRPointerScreenConfigured (ScreenPtr pScreen); void RRDeleteAllOutputProperties (RROutputPtr output); +RRPropertyValuePtr +RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending); + +RRPropertyPtr +RRQueryOutputProperty (RROutputPtr output, Atom property); + void RRDeleteOutputProperty (RROutputPtr output, Atom property); @@ -685,6 +718,10 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type, pointer value, Bool sendevent); int +RRConfigureOutputProperty (RROutputPtr output, Atom property, + Bool pending, Bool range, Bool immutable, + int num_values, INT32 *values); +int ProcRRChangeOutputProperty (ClientPtr client); int @@ -694,6 +731,12 @@ int ProcRRListOutputProperties (ClientPtr client); int +ProcRRQueryOutputProperty (ClientPtr client); + +int +ProcRRConfigureOutputProperty (ClientPtr client); + +int ProcRRDeleteOutputProperty (ClientPtr client); /* rrxinerama.c */ diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c index 49ba10bc0..6b61b9cd7 100644 --- a/randr/rrdispatch.c +++ b/randr/rrdispatch.c @@ -192,17 +192,19 @@ int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { ProcRRGetScreenResources, /* 8 */ ProcRRGetOutputInfo, /* 9 */ ProcRRListOutputProperties, /* 10 */ - ProcRRChangeOutputProperty, /* 11 */ - ProcRRDeleteOutputProperty, /* 12 */ - ProcRRGetOutputProperty, /* 13 */ - ProcRRCreateMode, /* 14 */ - ProcRRDestroyMode, /* 15 */ - ProcRRAddOutputMode, /* 16 */ - ProcRRDeleteOutputMode, /* 17 */ - ProcRRGetCrtcInfo, /* 18 */ - ProcRRSetCrtcConfig, /* 19 */ - ProcRRGetCrtcGammaSize, /* 20 */ - ProcRRGetCrtcGamma, /* 21 */ - ProcRRSetCrtcGamma, /* 22 */ + ProcRRQueryOutputProperty, /* 11 */ + ProcRRConfigureOutputProperty, /* 12 */ + ProcRRChangeOutputProperty, /* 13 */ + ProcRRDeleteOutputProperty, /* 14 */ + ProcRRGetOutputProperty, /* 15 */ + ProcRRCreateMode, /* 16 */ + ProcRRDestroyMode, /* 17 */ + ProcRRAddOutputMode, /* 18 */ + ProcRRDeleteOutputMode, /* 19 */ + ProcRRGetCrtcInfo, /* 20 */ + ProcRRSetCrtcConfig, /* 21 */ + ProcRRGetCrtcGammaSize, /* 22 */ + ProcRRGetCrtcGamma, /* 23 */ + ProcRRSetCrtcGamma, /* 24 */ }; diff --git a/randr/rrproperty.c b/randr/rrproperty.c index 44f1f0ace..5d4c86565 100644 --- a/randr/rrproperty.c +++ b/randr/rrproperty.c @@ -33,7 +33,7 @@ RRDeliverEvent (ScreenPtr pScreen, xEvent *event, CARD32 mask) void RRDeleteAllOutputProperties (RROutputPtr output) { - PropertyPtr prop, next; + RRPropertyPtr prop, next; xRROutputPropertyNotifyEvent event; for (prop = output->properties; prop; prop = next) @@ -46,15 +46,58 @@ RRDeleteAllOutputProperties (RROutputPtr output) event.atom = prop->propertyName; event.timestamp = currentTime.milliseconds; RRDeliverEvent (output->pScreen, (xEvent *) &event, RROutputPropertyNotifyMask); - xfree(prop->data); + if (prop->current.data) + xfree(prop->current.data); + if (prop->pending.data) + xfree(prop->pending.data); xfree(prop); } } +static void +RRInitOutputPropertyValue (RRPropertyValuePtr property_value) +{ + property_value->type = None; + property_value->format = 0; + property_value->size = 0; + property_value->data = NULL; +} + +static RRPropertyPtr +RRCreateOutputProperty (Atom property) +{ + RRPropertyPtr prop; + + prop = (RRPropertyPtr)xalloc(sizeof(PropertyRec)); + if (!prop) + return NULL; + prop->propertyName = property; + prop->is_pending = FALSE; + prop->range = FALSE; + prop->immutable = FALSE; + prop->num_valid = 0; + prop->valid_values = NULL; + RRInitOutputPropertyValue (&prop->current); + RRInitOutputPropertyValue (&prop->pending); + return prop; +} + +static void +RRDestroyOutputProperty (RRPropertyPtr prop) +{ + if (prop->valid_values) + xfree (prop->valid_values); + if (prop->current.data) + xfree(prop->current.data); + if (prop->pending.data) + xfree(prop->pending.data); + xfree(prop); +} + void RRDeleteOutputProperty (RROutputPtr output, Atom property) { - PropertyPtr prop, *prev; + RRPropertyPtr prop, *prev; xRROutputPropertyNotifyEvent event; for (prev = &output->properties; (prop = *prev); prev = &(prop->next)) @@ -70,8 +113,7 @@ RRDeleteOutputProperty (RROutputPtr output, Atom property) event.atom = prop->propertyName; event.timestamp = currentTime.milliseconds; RRDeliverEvent (output->pScreen, (xEvent *) &event, RROutputPropertyNotifyMask); - xfree(prop->data); - xfree(prop); + RRDestroyOutputProperty (prop); } } @@ -80,96 +122,95 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type, int format, int mode, unsigned long len, pointer value, Bool sendevent) { - PropertyPtr prop; + RRPropertyPtr prop; xRROutputPropertyNotifyEvent event; int sizeInBytes; int totalSize; pointer data; + RRPropertyValuePtr prop_value; + Bool add = FALSE; sizeInBytes = format >> 3; totalSize = len * sizeInBytes; /* first see if property already exists */ - - for (prop = output->properties; prop; prop = prop->next) - if (prop->propertyName == property) - break; - + prop = RRQueryOutputProperty (output, property); if (!prop) /* just add to list */ { - prop = (PropertyPtr)xalloc(sizeof(PropertyRec)); + prop = RRCreateOutputProperty (property); if (!prop) return(BadAlloc); - data = (pointer)xalloc(totalSize); - if (!data && len) - { - xfree(prop); - return(BadAlloc); - } - prop->propertyName = property; - prop->type = type; - prop->format = format; - prop->data = data; - if (len) - memmove((char *)data, (char *)value, totalSize); - prop->size = len; - prop->next = output->properties; - output->properties = prop; + add = TRUE; + mode = PropModeReplace; } + if (prop->is_pending) + prop_value = &prop->pending; else + prop_value = &prop->current; + + /* 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 != prop_value->format) && (mode != PropModeReplace)) + return(BadMatch); + if ((prop_value->type != type) && (mode != PropModeReplace)) + return(BadMatch); + if (mode == PropModeReplace) { - /* 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 != prop->format) && (mode != PropModeReplace)) - return(BadMatch); - if ((prop->type != type) && (mode != PropModeReplace)) - return(BadMatch); - if (mode == PropModeReplace) - { - if (totalSize != prop->size * (prop->format >> 3)) - { - data = (pointer)xrealloc(prop->data, totalSize); - if (!data && len) - return(BadAlloc); - prop->data = data; - } - if (len) - memmove((char *)prop->data, (char *)value, totalSize); - prop->size = len; - prop->type = type; - prop->format = format; - } - else if (len == 0) + if (totalSize != prop_value->size * (prop_value->format >> 3)) { - /* do nothing */ - } - else if (mode == PropModeAppend) - { - data = (pointer)xrealloc(prop->data, - sizeInBytes * (len + prop->size)); - if (!data) - return(BadAlloc); - prop->data = data; - memmove(&((char *)data)[prop->size * sizeInBytes], - (char *)value, - totalSize); - prop->size += len; - } - else if (mode == PropModePrepend) - { - data = (pointer)xalloc(sizeInBytes * (len + prop->size)); - if (!data) + if (prop_value->data) + data = (pointer)xrealloc(prop_value->data, totalSize); + else + data = (pointer)xalloc (totalSize); + if (!data && len) + { + if (add) + RRDestroyOutputProperty (prop); return(BadAlloc); - memmove(&((char *)data)[totalSize], (char *)prop->data, - (int)(prop->size * sizeInBytes)); - memmove((char *)data, (char *)value, totalSize); - xfree(prop->data); - prop->data = data; - prop->size += len; + } + prop_value->data = data; } + if (len) + memmove((char *)prop_value->data, (char *)value, totalSize); + prop_value->size = len; + prop_value->type = type; + prop_value->format = format; + } + else if (len == 0) + { + /* do nothing */ + } + else if (mode == PropModeAppend) + { + data = (pointer)xrealloc(prop_value->data, + sizeInBytes * (len + prop_value->size)); + if (!data) + return(BadAlloc); + prop_value->data = data; + memmove(&((char *)data)[prop_value->size * sizeInBytes], + (char *)value, + totalSize); + prop_value->size += len; + } + else if (mode == PropModePrepend) + { + data = (pointer)xalloc(sizeInBytes * (len + prop_value->size)); + if (!data) + return(BadAlloc); + memmove(&((char *)data)[totalSize], (char *)prop_value->data, + (int)(prop_value->size * sizeInBytes)); + memmove((char *)data, (char *)value, totalSize); + xfree(prop_value->data); + prop_value->data = data; + prop_value->size += len; + } + if (add) + { + prop->next = output->properties; + output->properties = prop; } if (sendevent) { @@ -184,6 +225,81 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type, return(Success); } +RRPropertyPtr +RRQueryOutputProperty (RROutputPtr output, Atom property) +{ + RRPropertyPtr prop; + + for (prop = output->properties; prop; prop = prop->next) + if (prop->propertyName == property) + return prop; + return NULL; +} + +RRPropertyValuePtr +RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending) +{ + RRPropertyPtr prop = RRQueryOutputProperty (output, property); + + if (!prop) + return NULL; + if (pending && prop->is_pending) + return &prop->pending; + else + return &prop->current; +} + +int +RRConfigureOutputProperty (RROutputPtr output, Atom property, + Bool pending, Bool range, Bool immutable, + int num_values, INT32 *values) +{ + RRPropertyPtr prop = RRQueryOutputProperty (output, property); + Bool add = FALSE; + INT32 *new_values; + + if (!prop) + { + prop = RRCreateOutputProperty (property); + if (!prop) + return(BadAlloc); + add = TRUE; + } else if (prop->immutable && !immutable) + return(BadAccess); + + /* + * ranges must have even number of values + */ + if (range && (num_values & 1)) + return BadMatch; + + new_values = xalloc (num_values * sizeof (INT32)); + if (!new_values && num_values) + return BadAlloc; + if (num_values) + memcpy (new_values, values, num_values * sizeof (INT32)); + + /* + * Property moving from pending to non-pending + * loses any pending values + */ + if (prop->is_pending && !pending) + { + if (prop->pending.data) + xfree (prop->pending.data); + RRInitOutputPropertyValue (&prop->pending); + } + + prop->is_pending = pending; + prop->range = range; + prop->immutable = immutable; + prop->num_valid = num_values; + if (prop->valid_values) + xfree (prop->valid_values); + prop->valid_values = new_values; + return Success; +} + int ProcRRListOutputProperties (ClientPtr client) { @@ -192,7 +308,7 @@ ProcRRListOutputProperties (ClientPtr client) xRRListOutputPropertiesReply rep; int numProps = 0; RROutputPtr output; - PropertyPtr prop; + RRPropertyPtr prop; REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq); @@ -211,6 +327,12 @@ ProcRRListOutputProperties (ClientPtr client) rep.nProperties = numProps; rep.length = (numProps * sizeof(Atom)) >> 2; rep.sequenceNumber = client->sequence; + if (client->swapped) + { + int n; + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + } temppAtoms = pAtoms; for (prop = output->properties; prop; prop = prop->next) *temppAtoms++ = prop->propertyName; @@ -226,6 +348,68 @@ ProcRRListOutputProperties (ClientPtr client) } int +ProcRRQueryOutputProperty (ClientPtr client) +{ + REQUEST(xRRQueryOutputPropertyReq); + xRRQueryOutputPropertyReply rep; + RROutputPtr output; + RRPropertyPtr prop; + + REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq); + + output = LookupOutput (client, stuff->output, SecurityReadAccess); + + if (!output) + return RRErrorBase + BadRROutput; + + prop = RRQueryOutputProperty (output, stuff->property); + if (!prop) + return BadName; + + rep.type = X_Reply; + rep.length = prop->num_valid; + rep.sequenceNumber = client->sequence; + rep.pending = prop->is_pending; + rep.range = prop->range; + rep.immutable = prop->immutable; + if (client->swapped) + { + int n; + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + } + WriteReplyToClient (client, sizeof (xRRQueryOutputPropertyReply), &rep); + if (prop->num_valid) + { + client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write; + WriteSwappedDataToClient(client, prop->num_valid * sizeof(INT32), + prop->valid_values); + } + return(client->noClientException); +} + +int +ProcRRConfigureOutputProperty (ClientPtr client) +{ + REQUEST(xRRConfigureOutputPropertyReq); + RROutputPtr output; + int num_valid; + + REQUEST_SIZE_MATCH(xRRConfigureOutputPropertyReq); + + output = LookupOutput (client, stuff->output, SecurityReadAccess); + + if (!output) + return RRErrorBase + BadRROutput; + + num_valid = stuff->length - (sizeof (xRRConfigureOutputPropertyReq) >> 2); + return RRConfigureOutputProperty (output, stuff->property, + stuff->pending, stuff->range, + FALSE, num_valid, + (INT32 *) (stuff + 1)); +} + +int ProcRRChangeOutputProperty (ClientPtr client) { REQUEST(xRRChangeOutputPropertyReq); @@ -309,7 +493,8 @@ int ProcRRGetOutputProperty (ClientPtr client) { REQUEST(xRRGetOutputPropertyReq); - PropertyPtr prop, *prev; + RRPropertyPtr prop, *prev; + RRPropertyValuePtr prop_value; unsigned long n, len, ind; RROutputPtr output; xRRGetOutputPropertyReply reply; @@ -356,18 +541,26 @@ ProcRRGetOutputProperty (ClientPtr client) return(client->noClientException); } + if (prop->immutable && stuff->delete) + return BadAccess; + + if (stuff->pending && prop->is_pending) + prop_value = &prop->pending; + else + prop_value = &prop->current; + /* If the request type and actual type don't match. Return the property information, but not the data. */ - if (((stuff->type != prop->type) && + if (((stuff->type != prop_value->type) && (stuff->type != AnyPropertyType)) ) { - reply.bytesAfter = prop->size; - reply.format = prop->format; + reply.bytesAfter = prop_value->size; + reply.format = prop_value->format; reply.length = 0; reply.nItems = 0; - reply.propertyType = prop->type; + reply.propertyType = prop_value->type; WriteReplyToClient(client, sizeof(xRRGetOutputPropertyReply), &reply); return(client->noClientException); } @@ -375,7 +568,7 @@ ProcRRGetOutputProperty (ClientPtr client) /* * Return type, format, value to client */ - n = (prop->format/8) * prop->size; /* size (bytes) of prop */ + n = (prop_value->format/8) * prop_value->size; /* size (bytes) of prop */ ind = stuff->longOffset << 2; /* If longOffset is invalid such that it causes "len" to @@ -390,10 +583,10 @@ ProcRRGetOutputProperty (ClientPtr client) len = min(n - ind, 4 * stuff->longLength); reply.bytesAfter = n - (ind + len); - reply.format = prop->format; + reply.format = prop_value->format; reply.length = (len + 3) >> 2; - reply.nItems = len / (prop->format / 8 ); - reply.propertyType = prop->type; + reply.nItems = len / (prop_value->format / 8 ); + reply.propertyType = prop_value->type; if (stuff->delete && (reply.bytesAfter == 0)) { @@ -417,14 +610,13 @@ ProcRRGetOutputProperty (ClientPtr client) default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break; } WriteSwappedDataToClient(client, len, - (char *)prop->data + ind); + (char *)prop_value->data + ind); } if (stuff->delete && (reply.bytesAfter == 0)) { /* delete the Property */ *prev = prop->next; - xfree(prop->data); - xfree(prop); + RRDestroyOutputProperty (prop); } return(client->noClientException); } diff --git a/randr/rrsdispatch.c b/randr/rrsdispatch.c index 67af75306..4a6a6e43f 100644 --- a/randr/rrsdispatch.c +++ b/randr/rrsdispatch.c @@ -132,6 +132,26 @@ SProcRRListOutputProperties (ClientPtr client) } static int +SProcRRQueryOutputProperty (ClientPtr client) +{ + REQUEST(xRRQueryOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRConfigureOutputProperty (ClientPtr client) +{ + REQUEST(xRRConfigureOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRConfigureOutputPropertyReq); + (void) stuff; + return BadImplementation; +} + +static int SProcRRChangeOutputProperty (ClientPtr client) { REQUEST(xRRChangeOutputPropertyReq); @@ -267,17 +287,19 @@ int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = { SProcRRGetScreenResources, /* 8 */ SProcRRGetOutputInfo, /* 9 */ SProcRRListOutputProperties,/* 10 */ - SProcRRChangeOutputProperty,/* 11 */ - SProcRRDeleteOutputProperty,/* 12 */ - SProcRRGetOutputProperty, /* 13 */ - SProcRRCreateMode, /* 14 */ - SProcRRDestroyMode, /* 15 */ - SProcRRAddOutputMode, /* 16 */ - SProcRRDeleteOutputMode, /* 17 */ - SProcRRGetCrtcInfo, /* 18 */ - SProcRRSetCrtcConfig, /* 19 */ - SProcRRGetCrtcGammaSize, /* 20 */ - SProcRRGetCrtcGamma, /* 21 */ - SProcRRSetCrtcGamma, /* 22 */ + SProcRRQueryOutputProperty, /* 11 */ + SProcRRConfigureOutputProperty, /* 12 */ + SProcRRChangeOutputProperty,/* 13 */ + SProcRRDeleteOutputProperty,/* 14 */ + SProcRRGetOutputProperty, /* 15 */ + SProcRRCreateMode, /* 16 */ + SProcRRDestroyMode, /* 17 */ + SProcRRAddOutputMode, /* 18 */ + SProcRRDeleteOutputMode, /* 19 */ + SProcRRGetCrtcInfo, /* 20 */ + SProcRRSetCrtcConfig, /* 21 */ + SProcRRGetCrtcGammaSize, /* 22 */ + SProcRRGetCrtcGamma, /* 23 */ + SProcRRSetCrtcGamma, /* 24 */ }; |