diff options
author | Keith Packard <keithp@neko.keithp.com> | 2006-11-21 01:15:26 -0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2006-11-28 11:13:43 -0800 |
commit | 24abce8032940e96bb2ccf9e463a7fff6f36283a (patch) | |
tree | 4f41479e14760470e9da45e5f06c065bf829c8c5 /randr | |
parent | f62ac3ec39c6593df476985c630e499864c19c72 (diff) |
Change RandR property datatype to include pending/valid values.
This patch tracks the protocol changes which introduce more complex
semantics for RandR output properties including pending and valid value
information.
(cherry picked from commit af55c65bea40669fdc038aa34c6a1ec9ecb33e87)
Diffstat (limited to 'randr')
-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 */ }; |