diff options
Diffstat (limited to 'xorg-server')
42 files changed, 2197 insertions, 930 deletions
diff --git a/xorg-server/Xext/Makefile.am b/xorg-server/Xext/Makefile.am index cb432e00e..5929a3e49 100644 --- a/xorg-server/Xext/Makefile.am +++ b/xorg-server/Xext/Makefile.am @@ -50,7 +50,7 @@ MODULE_SRCS += $(XV_SRCS) endif # XResource extension: lets clients get data about per-client resource usage -RES_SRCS = xres.c +RES_SRCS = hashtable.c xres.c if RES MODULE_SRCS += $(RES_SRCS) endif diff --git a/xorg-server/Xext/hashtable.c b/xorg-server/Xext/hashtable.c new file mode 100644 index 000000000..2adf92e56 --- /dev/null +++ b/xorg-server/Xext/hashtable.c @@ -0,0 +1,291 @@ +#include <stdlib.h> +#include "misc.h" +#include "hashtable.h" + +/* HashResourceID */ +#include "resource.h" + +#define INITHASHSIZE 6 +#define MAXHASHSIZE 11 + +struct HashTableRec { + int keySize; + int dataSize; + + int elements; /* number of elements inserted */ + int bucketBits; /* number of buckets is 1 << bucketBits */ + struct xorg_list *buckets; /* array of bucket list heads */ + + HashFunc hash; + HashCompareFunc compare; + + pointer cdata; +}; + +typedef struct { + struct xorg_list l; + void *key; + void *data; +} BucketRec, *BucketPtr; + +HashTable +ht_create(int keySize, + int dataSize, + HashFunc hash, + HashCompareFunc compare, + pointer cdata) +{ + int c; + int numBuckets; + HashTable ht = malloc(sizeof(struct HashTableRec)); + + if (!ht) { + return NULL; + } + + ht->keySize = keySize; + ht->dataSize = dataSize; + ht->hash = hash; + ht->compare = compare; + ht->elements = 0; + ht->bucketBits = INITHASHSIZE; + numBuckets = 1 << ht->bucketBits; + ht->buckets = malloc(numBuckets * sizeof(*ht->buckets)); + ht->cdata = cdata; + + if (ht->buckets) { + for (c = 0; c < numBuckets; ++c) { + xorg_list_init(&ht->buckets[c]); + } + return ht; + } else { + free(ht); + return NULL; + } +} + +void +ht_destroy(HashTable ht) +{ + int c; + BucketPtr it, tmp; + int numBuckets = 1 << ht->bucketBits; + for (c = 0; c < numBuckets; ++c) { + xorg_list_for_each_entry_safe(it, tmp, &ht->buckets[c], l) { + xorg_list_del(&it->l); + free(it); + } + } + free(ht->buckets); +} + +static Bool +double_size(HashTable ht) +{ + struct xorg_list *newBuckets; + int numBuckets = 1 << ht->bucketBits; + int newBucketBits = ht->bucketBits + 1; + int newNumBuckets = 1 << newBucketBits; + int c; + + newBuckets = malloc(newNumBuckets * sizeof(*ht->buckets)); + if (newBuckets) { + for (c = 0; c < newNumBuckets; ++c) { + xorg_list_init(&newBuckets[c]); + } + + for (c = 0; c < numBuckets; ++c) { + BucketPtr it, tmp; + xorg_list_for_each_entry_safe(it, tmp, &ht->buckets[c], l) { + struct xorg_list *newBucket = + &newBuckets[ht->hash(ht->cdata, it->key, newBucketBits)]; + xorg_list_del(&it->l); + xorg_list_add(&it->l, newBucket); + } + } + free(ht->buckets); + + ht->buckets = newBuckets; + ht->bucketBits = newBucketBits; + return TRUE; + } else { + return FALSE; + } +} + +pointer +ht_add(HashTable ht, pointer key) +{ + unsigned index = ht->hash(ht->cdata, key, ht->bucketBits); + struct xorg_list *bucket = &ht->buckets[index]; + BucketRec *elem = calloc(1, sizeof(BucketRec)); + if (!elem) { + goto outOfMemory; + } + elem->key = malloc(ht->keySize); + if (!elem->key) { + goto outOfMemory; + } + /* we avoid signaling an out-of-memory error if dataSize is 0 */ + elem->data = calloc(1, ht->dataSize); + if (ht->dataSize && !elem->data) { + goto outOfMemory; + } + xorg_list_add(&elem->l, bucket); + ++ht->elements; + + memcpy(elem->key, key, ht->keySize); + + if (ht->elements > 4 * (1 << ht->bucketBits) && + ht->bucketBits < MAXHASHSIZE) { + if (!double_size(ht)) { + --ht->elements; + xorg_list_del(&elem->l); + goto outOfMemory; + } + } + + /* if memory allocation has failed due to dataSize being 0, return + a "dummy" pointer pointing at the of the key */ + return elem->data ? elem->data : ((char*) elem->key + ht->keySize); + + outOfMemory: + if (elem) { + free(elem->key); + free(elem->data); + free(elem); + } + + return NULL; +} + +void +ht_remove(HashTable ht, pointer key) +{ + unsigned index = ht->hash(ht->cdata, key, ht->bucketBits); + struct xorg_list *bucket = &ht->buckets[index]; + BucketPtr it; + + xorg_list_for_each_entry(it, bucket, l) { + if (ht->compare(ht->cdata, key, it->key) == 0) { + xorg_list_del(&it->l); + --ht->elements; + free(it->key); + free(it->data); + free(it); + return; + } + } +} + +pointer +ht_find(HashTable ht, pointer key) +{ + unsigned index = ht->hash(ht->cdata, key, ht->bucketBits); + struct xorg_list *bucket = &ht->buckets[index]; + BucketPtr it; + + xorg_list_for_each_entry(it, bucket, l) { + if (ht->compare(ht->cdata, key, it->key) == 0) { + return it->data ? it->data : ((char*) it->key + ht->keySize); + } + } + + return NULL; +} + +void +ht_dump_distribution(HashTable ht) +{ + int c; + int numBuckets = 1 << ht->bucketBits; + for (c = 0; c < numBuckets; ++c) { + BucketPtr it; + int n = 0; + + xorg_list_for_each_entry(it, &ht->buckets[c], l) { + ++n; + } + printf("%d: %d\n", c, n); + } +} + +/* Picked the function from http://burtleburtle.net/bob/hash/doobs.html by + Bob Jenkins, which is released in public domain */ +static CARD32 +one_at_a_time_hash(const void *data, int len) +{ + CARD32 hash; + int i; + const char *key = data; + for (hash=0, i=0; i<len; ++i) { + hash += key[i]; + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + return hash; +} + +unsigned +ht_generic_hash(void *cdata, const void *ptr, int numBits) +{ + HtGenericHashSetupPtr setup = cdata; + return one_at_a_time_hash(ptr, setup->keySize) & ~((~0) << numBits); +} + +int +ht_generic_compare(void *cdata, const void *l, const void *r) +{ + HtGenericHashSetupPtr setup = cdata; + return memcmp(l, r, setup->keySize); +} + +unsigned +ht_resourceid_hash(void * cdata, const void * data, int numBits) +{ + const XID* idPtr = data; + XID id = *idPtr & RESOURCE_ID_MASK; + (void) cdata; + return HashResourceID(id, numBits); +} + +int +ht_resourceid_compare(void* cdata, const void* a, const void* b) +{ + const XID* xa = a; + const XID* xb = b; + (void) cdata; + return + *xa < *xb ? -1 : + *xa > *xb ? 1 : + 0; +} + +void +ht_dump_contents(HashTable ht, + void (*print_key)(void *opaque, void *key), + void (*print_value)(void *opaque, void *value), + void* opaque) +{ + int c; + int numBuckets = 1 << ht->bucketBits; + for (c = 0; c < numBuckets; ++c) { + BucketPtr it; + int n = 0; + + printf("%d: ", c); + xorg_list_for_each_entry(it, &ht->buckets[c], l) { + if (n > 0) { + printf(", "); + } + print_key(opaque, it->key); + printf("->"); + print_value(opaque, it->data); + ++n; + } + printf("\n"); + } +} diff --git a/xorg-server/Xext/hashtable.h b/xorg-server/Xext/hashtable.h new file mode 100644 index 000000000..5d1598425 --- /dev/null +++ b/xorg-server/Xext/hashtable.h @@ -0,0 +1,137 @@ +#ifndef HASHTABLE_H +#define HASHTABLE_H 1 + +#include <dix-config.h> +#include <X11/Xfuncproto.h> +#include <X11/Xdefs.h> +#include "list.h" + +/** @brief A hashing function. + + @param[in/out] cdata Opaque data that can be passed to HtInit that will + eventually end up here + @param[in] ptr The data to be hashed. The size of the data, if + needed, can be configured via a record that can be + passed via cdata. + @param[in] numBits The number of bits this hash needs to have in the + resulting hash + + @return A numBits-bit hash of the data +*/ +typedef unsigned (*HashFunc)(void * cdata, const void * ptr, int numBits); + +/** @brief A comparison function for hashed keys. + + @param[in/out] cdata Opaque data that ca be passed to Htinit that will + eventually end up here + @param[in] l The left side data to be compared + @param[in] r The right side data to be compared + + @return -1 if l < r, 0 if l == r, 1 if l > r +*/ +typedef int (*HashCompareFunc)(void * cdata, const void * l, const void * r); + +struct HashTableRec; + +typedef struct HashTableRec *HashTable; + +/** @brief A configuration for HtGenericHash */ +typedef struct { + int keySize; +} HtGenericHashSetupRec, *HtGenericHashSetupPtr; + +/** @brief ht_create initalizes a hash table for a certain hash table + configuration + + @param[out] ht The hash table structure to initialize + @param[in] keySize The key size in bytes + @param[in] dataSize The data size in bytes + @param[in] hash The hash function to use for hashing keys + @param[in] compare The comparison function for hashing keys + @param[in] cdata Opaque data that will be passed to hash and + comparison functions +*/ +extern _X_EXPORT HashTable ht_create(int keySize, + int dataSize, + HashFunc hash, + HashCompareFunc compare, + pointer cdata); +/** @brief HtDestruct deinitializes the structure. It does not free the + memory allocated to HashTableRec +*/ +extern _X_EXPORT void ht_destroy(HashTable ht); + +/** @brief Adds a new key to the hash table. The key will be copied + and a pointer to the value will be returned. The data will + be initialized with zeroes. + + @param[in/out] ht The hash table + @param[key] key The key. The contents of the key will be copied. + + @return On error NULL is returned, otherwise a pointer to the data + associated with the newly inserted key. + + @note If dataSize is 0, a pointer to the end of the key may be returned + to avoid returning NULL. Obviously the data pointed cannot be + modified, as implied by dataSize being 0. +*/ +extern _X_EXPORT pointer ht_add(HashTable ht, pointer key); + +/** @brief Removes a key from the hash table along with its + associated data, which will be free'd. +*/ +extern _X_EXPORT void ht_remove(HashTable ht, pointer key); + +/** @brief Finds the associated data of a key from the hash table. + + @return If the key cannot be found, the function returns NULL. + Otherwise it returns a pointer to the data associated + with the key. + + @note If dataSize == 0, this function may return NULL + even if the key has been inserted! If dataSize == NULL, + use HtMember instead to determine if a key has been + inserted. +*/ +extern _X_EXPORT pointer ht_find(HashTable ht, pointer key); + +/** @brief A generic hash function */ +extern _X_EXPORT unsigned ht_generic_hash(void *cdata, + const void *ptr, + int numBits); + +/** @brief A generic comparison function. It compares data byte-wise. */ +extern _X_EXPORT int ht_generic_compare(void *cdata, + const void *l, + const void *r); + +/** @brief A debugging function that dumps the distribution of the + hash table: for each bucket, list the number of elements + contained within. */ +extern _X_EXPORT void ht_dump_distribution(HashTable ht); + +/** @brief A debugging function that dumps the contents of the hash + table: for each bucket, list the elements contained + within. */ +extern _X_EXPORT void ht_dump_contents(HashTable ht, + void (*print_key)(void *opaque, void *key), + void (*print_value)(void *opaque, void *value), + void* opaque); + +/** @brief A hashing function to be used for hashing resource IDs when + used with HashTables. It makes no use of cdata, so that can + be NULL. It uses HashXID underneath, and should HashXID be + unable to hash the value, it switches into using the generic + hash function. */ +extern _X_EXPORT unsigned ht_resourceid_hash(void *cdata, + const void * data, + int numBits); + +/** @brief A comparison function to be used for comparing resource + IDs when used with HashTables. It makes no use of cdata, + so that can be NULL. */ +extern _X_EXPORT int ht_resourceid_compare(void *cdata, + const void *a, + const void *b); + +#endif // HASHTABLE_H diff --git a/xorg-server/Xext/xres.c b/xorg-server/Xext/xres.c index 9d89b6550..ecef0c032 100644 --- a/xorg-server/Xext/xres.c +++ b/xorg-server/Xext/xres.c @@ -10,6 +10,7 @@ #include <string.h> #include <X11/X.h> #include <X11/Xproto.h> +#include <assert.h> #include "misc.h" #include "os.h" #include "dixstruct.h" @@ -22,6 +23,169 @@ #include "gcstruct.h" #include "modinit.h" #include "protocol-versions.h" +#include "client.h" +#include "list.h" +#include "misc.h" +#include <string.h> +#include "hashtable.h" +#include "picturestr.h" +#include "compint.h" + +/** @brief Holds fragments of responses for ConstructClientIds. + * + * note: there is no consideration for data alignment */ +typedef struct { + struct xorg_list l; + int bytes; + /* data follows */ +} FragmentList; + +#define FRAGMENT_DATA(ptr) ((void*) ((char*) (ptr) + sizeof(FragmentList))) + +/** @brief Holds structure for the generated response to + ProcXResQueryClientIds; used by ConstructClientId* -functions */ +typedef struct { + int numIds; + int resultBytes; + struct xorg_list response; + int sentClientMasks[MAXCLIENTS]; +} ConstructClientIdCtx; + +/** @brief Holds the structure for information required to + generate the response to XResQueryResourceBytes. In addition + to response it contains information on the query as well, + as well as some volatile information required by a few + functions that cannot take that information directly + via a parameter, as they are called via already-existing + higher order functions. */ +typedef struct { + ClientPtr sendClient; + int numSizes; + int resultBytes; + struct xorg_list response; + int status; + long numSpecs; + xXResResourceIdSpec *specs; + HashTable visitedResources; + + /* Used by AddSubResourceSizeSpec when AddResourceSizeValue is + handling crossreferences */ + HashTable visitedSubResources; + + /* used when ConstructResourceBytesCtx is passed to + AddResourceSizeValue2 via FindClientResourcesByType */ + RESTYPE resType; + + /* used when ConstructResourceBytesCtx is passed to + AddResourceSizeValueByResource from ConstructResourceBytesByResource */ + xXResResourceIdSpec *curSpec; + + /** Used when iterating through a single resource's subresources + + @see AddSubResourceSizeSpec */ + xXResResourceSizeValue *sizeValue; +} ConstructResourceBytesCtx; + +/** @brief Allocate and add a sequence of bytes at the end of a fragment list. + Call DestroyFragments to release the list. + + @param frags A pointer to head of an initialized linked list + @param bytes Number of bytes to allocate + @return Returns a pointer to the allocated non-zeroed region + that is to be filled by the caller. On error (out of memory) + returns NULL and makes no changes to the list. +*/ +static void * +AddFragment(struct xorg_list *frags, int bytes) +{ + FragmentList *f = malloc(sizeof(FragmentList) + bytes); + if (!f) { + return NULL; + } else { + f->bytes = bytes; + xorg_list_add(&f->l, frags->prev); + return (char*) f + sizeof(*f); + } +} + +/** @brief Sends all fragments in the list to the client. Does not + free anything. + + @param client The client to send the fragments to + @param frags The head of the list of fragments +*/ +static void +WriteFragmentsToClient(ClientPtr client, struct xorg_list *frags) +{ + FragmentList *it; + xorg_list_for_each_entry(it, frags, l) { + WriteToClient(client, it->bytes, (char*) it + sizeof(*it)); + } +} + +/** @brief Frees a list of fragments. Does not free() root node. + + @param frags The head of the list of fragments +*/ +static void +DestroyFragments(struct xorg_list *frags) +{ + FragmentList *it, *tmp; + xorg_list_for_each_entry_safe(it, tmp, frags, l) { + xorg_list_del(&it->l); + free(it); + } +} + +/** @brief Constructs a context record for ConstructClientId* functions + to use */ +static void +InitConstructClientIdCtx(ConstructClientIdCtx *ctx) +{ + ctx->numIds = 0; + ctx->resultBytes = 0; + xorg_list_init(&ctx->response); + memset(ctx->sentClientMasks, 0, sizeof(ctx->sentClientMasks)); +} + +/** @brief Destroys a context record, releases all memory (except the storage + for *ctx itself) */ +static void +DestroyConstructClientIdCtx(ConstructClientIdCtx *ctx) +{ + DestroyFragments(&ctx->response); +} + +static Bool +InitConstructResourceBytesCtx(ConstructResourceBytesCtx *ctx, + ClientPtr sendClient, + long numSpecs, + xXResResourceIdSpec *specs) +{ + ctx->sendClient = sendClient; + ctx->numSizes = 0; + ctx->resultBytes = 0; + xorg_list_init(&ctx->response); + ctx->status = Success; + ctx->numSpecs = numSpecs; + ctx->specs = specs; + ctx->visitedResources = ht_create(sizeof(XID), 0, + ht_resourceid_hash, ht_resourceid_compare, + NULL); + + if (!ctx->visitedResources) { + return FALSE; + } else { + return TRUE; + } +} + +static void +DestroyConstructResourceBytesCtx(ConstructResourceBytesCtx *ctx) +{ + DestroyFragments(&ctx->response); + ht_destroy(ctx->visitedResources); +} static int ProcXResQueryVersion(ClientPtr client) @@ -195,6 +359,17 @@ ResGetApproxPixmapBytes(PixmapPtr pix) } static void +ResFindResourcePixmaps(pointer value, XID id, RESTYPE type, pointer cdata) +{ + SizeType sizeFunc = GetResourceTypeSizeFunc(type); + ResourceSizeRec size = { 0, 0, 0 }; + unsigned long *bytes = cdata; + + sizeFunc(value, id, &size); + *bytes += size.pixmapRefSize; +} + +static void ResFindPixmaps(pointer value, XID id, pointer cdata) { unsigned long *bytes = (unsigned long *) cdata; @@ -229,6 +404,22 @@ ResFindGCPixmaps(pointer value, XID id, pointer cdata) *bytes += ResGetApproxPixmapBytes(pGC->tile.pixmap); } +static void +ResFindPicturePixmaps(pointer value, XID id, pointer cdata) +{ +#ifdef RENDER + ResFindResourcePixmaps(value, id, PictureType, cdata); +#endif +} + +static void +ResFindCompositeClientWindowPixmaps (pointer value, XID id, pointer cdata) +{ +#ifdef COMPOSITE + ResFindResourcePixmaps(value, id, CompositeClientWindowType, cdata); +#endif +} + static int ProcXResQueryClientPixmapBytes(ClientPtr client) { @@ -263,8 +454,18 @@ ProcXResQueryClientPixmapBytes(ClientPtr client) FindClientResourcesByType(clients[clientID], RT_GC, ResFindGCPixmaps, (pointer) (&bytes)); +#ifdef RENDER + /* Render extension picture pixmaps. */ + FindClientResourcesByType(clients[clientID], PictureType, + ResFindPicturePixmaps, + (pointer)(&bytes)); +#endif + #ifdef COMPOSITE - /* FIXME: include composite pixmaps too */ + /* Composite extension client window pixmaps. */ + FindClientResourcesByType(clients[clientID], CompositeClientWindowType, + ResFindCompositeClientWindowPixmaps, + (pointer)(&bytes)); #endif rep.type = X_Reply; @@ -288,6 +489,584 @@ ProcXResQueryClientPixmapBytes(ClientPtr client) return Success; } +/** @brief Finds out if a client's information need to be put into the + response; marks client having been handled, if that is the case. + + @param client The client to send information about + @param mask The request mask (0 to send everything, otherwise a + bitmask of X_XRes*Mask) + @param ctx The context record that tells which clients and id types + have been already handled + @param sendMask Which id type are we now considering. One of X_XRes*Mask. + + @return Returns TRUE if the client information needs to be on the + response, otherwise FALSE. +*/ +static Bool +WillConstructMask(ClientPtr client, CARD32 mask, + ConstructClientIdCtx *ctx, int sendMask) +{ + if ((!mask || (mask & sendMask)) + && !(ctx->sentClientMasks[client->index] & sendMask)) { + ctx->sentClientMasks[client->index] |= sendMask; + return TRUE; + } else { + return FALSE; + } +} + +/** @brief Constructs a response about a single client, based on a certain + client id spec + + @param sendClient Which client wishes to receive this answer. Used for + byte endianess. + @param client Which client are we considering. + @param mask The client id spec mask indicating which information + we want about this client. + @param ctx The context record containing the constructed response + and information on which clients and masks have been + already handled. + + @return Return TRUE if everything went OK, otherwise FALSE which indicates + a memory allocation problem. +*/ +static Bool +ConstructClientIdValue(ClientPtr sendClient, ClientPtr client, CARD32 mask, + ConstructClientIdCtx *ctx) +{ + xXResClientIdValue rep; + + rep.spec.client = client->clientAsMask; + if (client->swapped) { + swapl (&rep.spec.client); + } + + if (WillConstructMask(client, mask, ctx, X_XResClientXIDMask)) { + void *ptr = AddFragment(&ctx->response, sizeof(rep)); + if (!ptr) { + return FALSE; + } + + rep.spec.mask = X_XResClientXIDMask; + rep.length = 0; + if (sendClient->swapped) { + swapl (&rep.spec.mask); + /* swapl (&rep.length, n); - not required for rep.length = 0 */ + } + + memcpy(ptr, &rep, sizeof(rep)); + + ctx->resultBytes += sizeof(rep); + ++ctx->numIds; + } + if (WillConstructMask(client, mask, ctx, X_XResLocalClientPIDMask)) { + pid_t pid = GetClientPid(client); + + if (pid != -1) { + void *ptr = AddFragment(&ctx->response, + sizeof(rep) + sizeof(CARD32)); + CARD32 *value = (void*) ((char*) ptr + sizeof(rep)); + + if (!ptr) { + return FALSE; + } + + rep.spec.mask = X_XResLocalClientPIDMask; + rep.length = 4; + + if (sendClient->swapped) { + swapl (&rep.spec.mask); + swapl (&rep.length); + } + + if (sendClient->swapped) { + swapl (value); + } + memcpy(ptr, &rep, sizeof(rep)); + *value = pid; + + ctx->resultBytes += sizeof(rep) + sizeof(CARD32); + ++ctx->numIds; + } + } + + /* memory allocation errors earlier may return with FALSE */ + return TRUE; +} + +/** @brief Constructs a response about all clients, based on a client id specs + + @param client Which client which we are constructing the response for. + @param numSpecs Number of client id specs in specs + @param specs Client id specs + + @return Return Success if everything went OK, otherwise a Bad* (currently + BadAlloc or BadValue) +*/ +static int +ConstructClientIds(ClientPtr client, + int numSpecs, xXResClientIdSpec* specs, + ConstructClientIdCtx *ctx) +{ + int specIdx; + + for (specIdx = 0; specIdx < numSpecs; ++specIdx) { + if (specs[specIdx].client == 0) { + int c; + for (c = 0; c < currentMaxClients; ++c) { + if (clients[c]) { + if (!ConstructClientIdValue(client, clients[c], + specs[specIdx].mask, ctx)) { + return BadAlloc; + } + } + } + } else { + int clientID = CLIENT_ID(specs[specIdx].client); + + if ((clientID < currentMaxClients) && clients[clientID]) { + if (!ConstructClientIdValue(client, clients[clientID], + specs[specIdx].mask, ctx)) { + return BadAlloc; + } + } + } + } + + /* memory allocation errors earlier may return with BadAlloc */ + return Success; +} + +/** @brief Response to XResQueryClientIds request introduced in XResProto v1.2 + + @param client Which client which we are constructing the response for. + + @return Returns the value returned from ConstructClientIds with the same + semantics +*/ +static int +ProcXResQueryClientIds (ClientPtr client) +{ + REQUEST(xXResQueryClientIdsReq); + + xXResQueryClientIdsReply rep; + xXResClientIdSpec *specs = (void*) ((char*) stuff + sizeof(*stuff)); + int rc; + ConstructClientIdCtx ctx; + + InitConstructClientIdCtx(&ctx); + + REQUEST_AT_LEAST_SIZE(xXResQueryClientIdsReq); + REQUEST_FIXED_SIZE(xXResQueryClientIdsReq, + stuff->numSpecs * sizeof(specs[0])); + + rc = ConstructClientIds(client, stuff->numSpecs, specs, &ctx); + + if (rc == Success) { + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + + assert((ctx.resultBytes & 3) == 0); + rep.length = bytes_to_int32(ctx.resultBytes); + rep.numIds = ctx.numIds; + + if (client->swapped) { + swaps (&rep.sequenceNumber); + swapl (&rep.length); + swapl (&rep.numIds); + } + + WriteToClient(client,sizeof(rep),(char*)&rep); + WriteFragmentsToClient(client, &ctx.response); + } + + DestroyConstructClientIdCtx(&ctx); + + return rc; +} + +/** @brief Swaps xXResResourceIdSpec endianess */ +static void +SwapXResResourceIdSpec(xXResResourceIdSpec *spec) +{ + swapl(&spec->resource); + swapl(&spec->type); +} + +/** @brief Swaps xXResResourceSizeSpec endianess */ +static void +SwapXResResourceSizeSpec(xXResResourceSizeSpec *size) +{ + SwapXResResourceIdSpec(&size->spec); + swapl(&size->bytes); + swapl(&size->refCount); + swapl(&size->useCount); +} + +/** @brief Swaps xXResResourceSizeValue endianess */ +static void +SwapXResResourceSizeValue(xXResResourceSizeValue *rep) +{ + SwapXResResourceSizeSpec(&rep->size); + swapl(&rep->numCrossReferences); +} + +/** @brief Swaps the response bytes */ +static void +SwapXResQueryResourceBytes(struct xorg_list *response) +{ + struct xorg_list *it = response->next; + int c; + + while (it != response) { + xXResResourceSizeValue *value = FRAGMENT_DATA(it); + it = it->next; + for (c = 0; c < value->numCrossReferences; ++c) { + xXResResourceSizeSpec *spec = FRAGMENT_DATA(it); + SwapXResResourceSizeSpec(spec); + it = it->next; + } + SwapXResResourceSizeValue(value); + } +} + +/** @brief Adds xXResResourceSizeSpec describing a resource's size into + the buffer contained in the context. The resource is considered + to be a subresource. + + @see AddResourceSizeValue + + @param[in] value The X resource object on which to add information + about to the buffer + @param[in] id The ID of the X resource + @param[in] type The type of the X resource + @param[in/out] cdata The context object of type ConstructResourceBytesCtx. + Void pointer type is used here to satisfy the type + FindRes +*/ +static void +AddSubResourceSizeSpec(pointer value, + XID id, + RESTYPE type, + pointer cdata) +{ + ConstructResourceBytesCtx *ctx = cdata; + + if (ctx->status == Success) { + xXResResourceSizeSpec **prevCrossRef = + ht_find(ctx->visitedSubResources, &value); + if (!prevCrossRef) { + Bool ok = TRUE; + xXResResourceSizeSpec *crossRef = + AddFragment(&ctx->response, sizeof(xXResResourceSizeSpec)); + ok = ok && crossRef != NULL; + if (ok) { + xXResResourceSizeSpec **p; + p = ht_add(ctx->visitedSubResources, &value); + if (!p) { + ok = FALSE; + } else { + *p = crossRef; + } + } + if (!ok) { + ctx->status = BadAlloc; + } else { + SizeType sizeFunc = GetResourceTypeSizeFunc(type); + ResourceSizeRec size = { 0, 0, 0 }; + sizeFunc(value, id, &size); + + crossRef->spec.resource = id; + crossRef->spec.type = type; + crossRef->bytes = size.resourceSize; + crossRef->refCount = size.refCnt; + crossRef->useCount = 1; + + ++ctx->sizeValue->numCrossReferences; + + ctx->resultBytes += sizeof(*crossRef); + } + } else { + /* if we have visited the subresource earlier (from current parent + resource), just increase its use count by one */ + ++(*prevCrossRef)->useCount; + } + } +} + +/** @brief Adds xXResResourceSizeValue describing a resource's size into + the buffer contained in the context. In addition, the + subresources are iterated and added as xXResResourceSizeSpec's + by using AddSubResourceSizeSpec + + @see AddSubResourceSizeSpec + + @param[in] value The X resource object on which to add information + about to the buffer + @param[in] id The ID of the X resource + @param[in] type The type of the X resource + @param[in/out] cdata The context object of type ConstructResourceBytesCtx. + Void pointer type is used here to satisfy the type + FindRes +*/ +static void +AddResourceSizeValue(pointer ptr, XID id, RESTYPE type, pointer cdata) +{ + ConstructResourceBytesCtx *ctx = cdata; + if (ctx->status == Success && + !ht_find(ctx->visitedResources, &id)) { + Bool ok = TRUE; + HashTable ht; + HtGenericHashSetupRec htSetup = { + .keySize = sizeof(void*) + }; + + /* it doesn't matter that we don't undo the work done here + * immediately. All but ht_init will be undone at the end + * of the request and there can happen no failure after + * ht_init, so we don't need to clean it up here in any + * special way */ + + xXResResourceSizeValue *value = + AddFragment(&ctx->response, sizeof(xXResResourceSizeValue)); + if (!value) { + ok = FALSE; + } + ok = ok && ht_add(ctx->visitedResources, &id); + if (ok) { + ht = ht_create(htSetup.keySize, + sizeof(xXResResourceSizeSpec*), + ht_generic_hash, ht_generic_compare, + &htSetup); + ok = ok && ht; + } + + if (!ok) { + ctx->status = BadAlloc; + } else { + SizeType sizeFunc = GetResourceTypeSizeFunc(type); + ResourceSizeRec size = { 0, 0, 0 }; + + sizeFunc(ptr, id, &size); + + value->size.spec.resource = id; + value->size.spec.type = type; + value->size.bytes = size.resourceSize; + value->size.refCount = size.refCnt; + value->size.useCount = 1; + value->numCrossReferences = 0; + + ctx->sizeValue = value; + ctx->visitedSubResources = ht; + FindSubResources(ptr, type, AddSubResourceSizeSpec, ctx); + ctx->visitedSubResources = NULL; + ctx->sizeValue = NULL; + + ctx->resultBytes += sizeof(*value); + ++ctx->numSizes; + + ht_destroy(ht); + } + } +} + +/** @brief A variant of AddResourceSizeValue that passes the resource type + through the context object to satisfy the type FindResType + + @see AddResourceSizeValue + + @param[in] ptr The resource + @param[in] id The resource ID + @param[in/out] cdata The context object that contains the resource type +*/ +static void +AddResourceSizeValueWithResType(pointer ptr, XID id, pointer cdata) +{ + ConstructResourceBytesCtx *ctx = cdata; + AddResourceSizeValue(ptr, id, ctx->resType, cdata); +} + +/** @brief Adds the information of a resource into the buffer if it matches + the match condition. + + @see AddResourceSizeValue + + @param[in] ptr The resource + @param[in] id The resource ID + @param[in] type The resource type + @param[in/out] cdata The context object as a void pointer to satisfy the + type FindAllRes +*/ +static void +AddResourceSizeValueByResource(pointer ptr, XID id, RESTYPE type, pointer cdata) +{ + ConstructResourceBytesCtx *ctx = cdata; + xXResResourceIdSpec *spec = ctx->curSpec; + + if ((!spec->type || spec->type == type) && + (!spec->resource || spec->resource == id)) { + AddResourceSizeValue(ptr, id, type, ctx); + } +} + +/** @brief Add all resources of the client into the result buffer + disregarding all those specifications that specify the + resource by its ID. Those are handled by + ConstructResourceBytesByResource + + @see ConstructResourceBytesByResource + + @param[in] aboutClient Which client is being considered + @param[in/out] ctx The context that contains the resource id + specifications as well as the result buffer +*/ +static void +ConstructClientResourceBytes(ClientPtr aboutClient, + ConstructResourceBytesCtx *ctx) +{ + int specIdx; + for (specIdx = 0; specIdx < ctx->numSpecs; ++specIdx) { + xXResResourceIdSpec* spec = ctx->specs + specIdx; + if (spec->resource) { + /* these specs are handled elsewhere */ + } else if (spec->type) { + ctx->resType = spec->type; + FindClientResourcesByType(aboutClient, spec->type, + AddResourceSizeValueWithResType, ctx); + } else { + FindAllClientResources(aboutClient, AddResourceSizeValue, ctx); + } + } +} + +/** @brief Add the sizes of all such resources that can are specified by + their ID in the resource id specification. The scan can + by limited to a client with the aboutClient parameter + + @see ConstructResourceBytesByResource + + @param[in] aboutClient Which client is being considered. This may be None + to mean all clients. + @param[in/out] ctx The context that contains the resource id + specifications as well as the result buffer. In + addition this function uses the curSpec field to + keep a pointer to the current resource id + specification in it, which can be used by + AddResourceSizeValueByResource . +*/ +static void +ConstructResourceBytesByResource(XID aboutClient, ConstructResourceBytesCtx *ctx) +{ + int specIdx; + for (specIdx = 0; specIdx < ctx->numSpecs; ++specIdx) { + xXResResourceIdSpec *spec = ctx->specs + specIdx; + if (spec->resource) { + int cid = CLIENT_ID(spec->resource); + if (cid < currentMaxClients && + (aboutClient == None || cid == aboutClient)) { + ClientPtr client = clients[cid]; + if (client) { + ctx->curSpec = spec; + FindAllClientResources(client, + AddResourceSizeValueByResource, + ctx); + } + } + } + } +} + +/** @brief Build the resource size response for the given client + (or all if not specified) per the parameters set up + in the context object. + + @param[in] aboutClient Which client to consider or None for all clients + @param[in/out] ctx The context object that contains the request as well + as the response buffer. +*/ +static int +ConstructResourceBytes(XID aboutClient, + ConstructResourceBytesCtx *ctx) +{ + if (aboutClient) { + int clientIdx = CLIENT_ID(aboutClient); + ClientPtr client = NullClient; + + if ((clientIdx >= currentMaxClients) || !clients[clientIdx]) { + ctx->sendClient->errorValue = aboutClient; + return BadValue; + } + + client = clients[clientIdx]; + + ConstructClientResourceBytes(client, ctx); + ConstructResourceBytesByResource(aboutClient, ctx); + } else { + int clientIdx; + + ConstructClientResourceBytes(NULL, ctx); + + for (clientIdx = 0; clientIdx < currentMaxClients; ++clientIdx) { + ClientPtr client = clients[clientIdx]; + + if (client) { + ConstructClientResourceBytes(client, ctx); + } + } + + ConstructResourceBytesByResource(None, ctx); + } + + + return ctx->status; +} + +/** @brief Implements the XResQueryResourceBytes of XResProto v1.2 */ +static int +ProcXResQueryResourceBytes (ClientPtr client) +{ + REQUEST(xXResQueryResourceBytesReq); + + xXResQueryResourceBytesReply rep; + int rc; + ConstructResourceBytesCtx ctx; + + REQUEST_AT_LEAST_SIZE(xXResQueryResourceBytesReq); + REQUEST_FIXED_SIZE(xXResQueryResourceBytesReq, + stuff->numSpecs * sizeof(ctx.specs[0])); + + if (!InitConstructResourceBytesCtx(&ctx, client, + stuff->numSpecs, + (void*) ((char*) stuff + + sz_xXResQueryResourceBytesReq))) { + return BadAlloc; + } + + rc = ConstructResourceBytes(stuff->client, &ctx); + + if (rc == Success) { + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.numSizes = ctx.numSizes; + rep.length = bytes_to_int32(ctx.resultBytes); + + if (client->swapped) { + swaps (&rep.sequenceNumber); + swapl (&rep.length); + swapl (&rep.numSizes); + + SwapXResQueryResourceBytes(&ctx.response); + } + + WriteToClient(client,sizeof(rep),(char*)&rep); + WriteFragmentsToClient(client, &ctx.response); + } + + DestroyConstructResourceBytesCtx(&ctx); + + return rc; +} + static int ProcResDispatch(ClientPtr client) { @@ -301,8 +1080,11 @@ ProcResDispatch(ClientPtr client) return ProcXResQueryClientResources(client); case X_XResQueryClientPixmapBytes: return ProcXResQueryClientPixmapBytes(client); - default: - break; + case X_XResQueryClientIds: + return ProcXResQueryClientIds(client); + case X_XResQueryResourceBytes: + return ProcXResQueryResourceBytes(client); + default: break; } return BadRequest; @@ -335,7 +1117,39 @@ SProcXResQueryClientPixmapBytes(ClientPtr client) } static int -SProcResDispatch(ClientPtr client) +SProcXResQueryClientIds (ClientPtr client) +{ + REQUEST(xXResQueryClientIdsReq); + + REQUEST_AT_LEAST_SIZE (xXResQueryClientIdsReq); + swapl(&stuff->numSpecs); + return ProcXResQueryClientIds(client); +} + +/** @brief Implements the XResQueryResourceBytes of XResProto v1.2. + This variant byteswaps request contents before issuing the + rest of the work to ProcXResQueryResourceBytes */ +static int +SProcXResQueryResourceBytes (ClientPtr client) +{ + REQUEST(xXResQueryResourceBytesReq); + int c; + xXResResourceIdSpec *specs = (void*) ((char*) stuff + sizeof(*stuff)); + + swapl(&stuff->numSpecs); + REQUEST_AT_LEAST_SIZE(xXResQueryResourceBytesReq); + REQUEST_FIXED_SIZE(xXResQueryResourceBytesReq, + stuff->numSpecs * sizeof(specs[0])); + + for (c = 0; c < stuff->numSpecs; ++c) { + SwapXResResourceIdSpec(specs + c); + } + + return ProcXResQueryResourceBytes(client); +} + +static int +SProcResDispatch (ClientPtr client) { REQUEST(xReq); swaps(&stuff->length); @@ -349,8 +1163,11 @@ SProcResDispatch(ClientPtr client) return SProcXResQueryClientResources(client); case X_XResQueryClientPixmapBytes: return SProcXResQueryClientPixmapBytes(client); - default: - break; + case X_XResQueryClientIds: + return SProcXResQueryClientIds(client); + case X_XResQueryResourceBytes: + return SProcXResQueryResourceBytes(client); + default: break; } return BadRequest; diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c index c05c22604..e9f02072a 100644 --- a/xorg-server/Xi/exevents.c +++ b/xorg-server/Xi/exevents.c @@ -1234,14 +1234,6 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource, } } - /* If there are no other listeners left, and the touchpoint is pending - * finish, then we can just kill it now. */ - if (ti->num_listeners == 1 && ti->pending_finish) { - TouchEndTouch(sourcedev, ti); - CheckOldestTouch(sourcedev); - return; - } - /* Remove the resource from the listener list, updating * ti->num_listeners, as well as ti->num_grabs if it was a grab. */ if (TouchRemoveListener(ti, resource)) { @@ -1254,6 +1246,8 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource, * the TouchOwnership or TouchBegin event to the new owner. */ if (ev && ti->num_listeners > 0 && was_owner) TouchPuntToNextOwner(sourcedev, ti, ev); + else if (ti->num_listeners == 0) + TouchEndTouch(sourcedev, ti); CheckOldestTouch(sourcedev); } @@ -1273,9 +1267,18 @@ ProcessTouchOwnershipEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, if (ev->reason == XIRejectTouch) TouchRejected(dev, ti, ev->resource, ev); else if (ev->reason == XIAcceptTouch) { + int i; + + /* Go through the motions of ending the touch if the listener has + * already seen the end. This ensures that the touch record is ended in + * the server. */ + if (ti->listeners[0].state == LISTENER_HAS_END) + EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[0].listener); + /* The touch owner has accepted the touch. Send TouchEnd events to * everyone else, and truncate the list of listeners. */ - EmitTouchEnd(dev, ti, TOUCH_ACCEPT, 0); + for (i = 1; i < ti->num_listeners; i++) + EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[i].listener); while (ti->num_listeners > 1) TouchRemoveListener(ti, ti->listeners[1].listener); @@ -1327,6 +1330,7 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti, { int rc; InputClients *iclients = NULL; + *mask = NULL; if (listener->type == LISTENER_GRAB || listener->type == LISTENER_POINTER_GRAB) { @@ -1377,6 +1381,9 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti, BUG_WARN(!iclients); if (!iclients) return FALSE; + + *mask = iclients->xi2mask; + *client = rClient(iclients); } else if (listener->level == XI) { int xi_type = GetXIType(TouchGetPointerEventType(ev)); @@ -1389,21 +1396,24 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti, BUG_WARN(!iclients); if (!iclients) return FALSE; + + *client = rClient(iclients); } else { int coretype = GetCoreType(TouchGetPointerEventType(ev)); Mask core_filter = event_get_filter_from_type(dev, coretype); + OtherClients *oclients; /* all others */ - nt_list_for_each_entry(iclients, - (InputClients *) wOtherClients(*win), next) - if (iclients->mask[XIAllDevices] & core_filter) - break; - /* if owner selected, iclients is NULL */ + nt_list_for_each_entry(oclients, + (OtherClients *) wOtherClients(*win), next) + if (oclients->mask & core_filter) + break; + + /* if owner selected, oclients is NULL */ + *client = oclients ? rClient(oclients) : wClient(*win); } - *client = iclients ? rClient(iclients) : wClient(*win); - *mask = iclients ? iclients->xi2mask : NULL; *grab = NULL; } @@ -1459,7 +1469,14 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, if (!deliveries) DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype); + /* We must accept the touch sequence once a pointer listener has + * received one event past ButtonPress. */ + if (deliveries && ev->any.type != ET_TouchBegin && + !(ev->device_event.flags & TOUCH_CLIENT_ID)) + TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch); + if (ev->any.type == ET_TouchEnd && + !(ev->device_event.flags & TOUCH_CLIENT_ID) && !dev->button->buttonsDown && dev->deviceGrab.fromPassiveGrab && GrabIsPointerGrab(grab)) { (*dev->deviceGrab.DeactivateGrab) (dev); @@ -1580,6 +1597,9 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev) else touchid = ev->device_event.touchid; + if (emulate_pointer) + UpdateDeviceState(dev, &ev->device_event); + if (type == ET_TouchBegin) { ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid, emulate_pointer); @@ -1587,6 +1607,34 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev) else ti = TouchFindByClientID(dev, touchid); + /* Under the following circumstances we create a new touch record for an + * existing touch: + * + * - The touch may be pointer emulated + * - An explicit grab is active on the device + * - The grab is a pointer grab + * + * This allows for an explicit grab to receive pointer events for an already + * active touch. + */ + if (!ti && type != ET_TouchBegin && emulate_pointer && + dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab && + (dev->deviceGrab.grab->grabtype == CORE || + dev->deviceGrab.grab->grabtype == XI || + !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin))) { + ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid, + emulate_pointer); + if (!ti) { + DebugF("[Xi] %s: Failed to create new dix record for explicitly " + "grabbed touchpoint %d\n", + dev->name, type, touchid); + return; + } + + TouchBuildSprite(dev, ti, ev); + TouchSetupListeners(dev, ti, ev); + } + if (!ti) { DebugF("[Xi] %s: Failed to get event %d for touchpoint %d\n", dev->name, type, touchid); @@ -1602,9 +1650,11 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev) CheckMotion(&ev->device_event, dev); /* Make sure we have a valid window trace for event delivery; must be - * called after event type mutation. */ + * called after event type mutation. Touch end events are always processed + * in order to end touch records. */ /* FIXME: check this */ - if (!TouchEnsureSprite(dev, ti, ev)) + if ((type == ET_TouchBegin && !TouchBuildSprite(dev, ti, ev)) || + (type != ET_TouchEnd && ti->sprite.spriteTraceGood == 0)) return; /* TouchOwnership events are handled separately from the rest, as they @@ -1834,7 +1884,8 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev, if (ti->num_listeners > 1) { ev->any.type = ET_TouchUpdate; ev->device_event.flags |= TOUCH_PENDING_END; - ti->pending_finish = TRUE; + if (!(ev->device_event.flags & TOUCH_CLIENT_ID)) + ti->pending_finish = TRUE; } goto out; @@ -1948,9 +1999,6 @@ DeliverTouchEvents(DeviceIntPtr dev, TouchPointInfoPtr ti, DeliverTouchEvent(dev, ti, ev, listener, client, win, grab, mask); } - - if (ti->emulate_pointer) - UpdateDeviceState(dev, &ev->device_event); } int diff --git a/xorg-server/composite/compext.c b/xorg-server/composite/compext.c index 940eed1fc..1d4d8bf97 100644 --- a/xorg-server/composite/compext.c +++ b/xorg-server/composite/compext.c @@ -497,6 +497,28 @@ SProcCompositeDispatch(ClientPtr client) return BadRequest; } +/** @see GetDefaultBytes */ +static void +GetCompositeClientWindowBytes(pointer value, XID id, ResourceSizePtr size) +{ + WindowPtr window = value; + + /* Currently only pixmap bytes are reported to clients. */ + size->resourceSize = 0; + + /* Calculate pixmap reference sizes. */ + size->pixmapRefSize = 0; + if (window->redirectDraw != RedirectDrawNone) + { + SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); + ResourceSizeRec pixmapSize = { 0, 0 }; + ScreenPtr screen = window->drawable.pScreen; + PixmapPtr pixmap = screen->GetWindowPixmap(window); + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } +} + void CompositeExtensionInit(void) { @@ -529,6 +551,9 @@ CompositeExtensionInit(void) if (!CompositeClientWindowType) return; + SetResourceTypeSizeFunc(CompositeClientWindowType, + GetCompositeClientWindowBytes); + CompositeClientSubwindowsType = CreateNewResourceType (FreeCompositeClientSubwindows, "CompositeClientSubwindows"); if (!CompositeClientSubwindowsType) diff --git a/xorg-server/composite/compint.h b/xorg-server/composite/compint.h index 6c4272e5b..9e2713e93 100644 --- a/xorg-server/composite/compint.h +++ b/xorg-server/composite/compint.h @@ -71,6 +71,7 @@ #include "damageextint.h" #include "xfixes.h" #include <X11/extensions/compositeproto.h> +#include "compositeext.h" #include <assert.h> /* @@ -182,7 +183,6 @@ extern DevPrivateKeyRec CompSubwindowsPrivateKeyRec; #define GetCompSubwindows(w) ((CompSubwindowsPtr) \ dixLookupPrivate(&(w)->devPrivates, CompSubwindowsPrivateKey)) -extern RESTYPE CompositeClientWindowType; extern RESTYPE CompositeClientSubwindowsType; extern RESTYPE CompositeClientOverlayType; diff --git a/xorg-server/composite/compositeext.h b/xorg-server/composite/compositeext.h index 600604d8d..0b148f029 100644 --- a/xorg-server/composite/compositeext.h +++ b/xorg-server/composite/compositeext.h @@ -35,4 +35,6 @@ extern _X_EXPORT Bool CompositeRegisterAlternateVisuals(ScreenPtr pScreen, VisualID * vids, int nVisuals); +extern _X_EXPORT RESTYPE CompositeClientWindowType; + #endif /* _COMPOSITEEXT_H_ */ diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index 65d29f206..4afac8268 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -699,11 +699,21 @@ dnl DDX Detection... Yes, it's ugly to have it here... but we need to dnl handle this early on so that we don't require unsupported extensions case $host_os in cygwin*) + CONFIG_DBUS_API=no + CONFIG_HAL=no + CONFIG_UDEV=no DGA=no DRI2=no + INT10MODULE=no + PCI=no + VGAHW=no + VBE=no + XAA=no + XF86UTILS=no XF86VIDMODE=no XSELINUX=no XV=no + SYMBOL_VISIBILITY=no ;; darwin*) PCI=no @@ -759,7 +769,7 @@ VIDEOPROTO="videoproto" COMPOSITEPROTO="compositeproto >= 0.4" RECORDPROTO="recordproto >= 1.13.99.1" SCRNSAVERPROTO="scrnsaverproto >= 1.1" -RESOURCEPROTO="resourceproto" +RESOURCEPROTO="resourceproto >= 1.2.0" DRIPROTO="xf86driproto >= 2.1.0" DRI2PROTO="dri2proto >= 2.6" XINERAMAPROTO="xineramaproto" @@ -1060,6 +1070,7 @@ if test "x$GLX_USE_TLS" = xyes ; then GLX_SYS_LIBS="$GLX_SYS_LIBS -lpthread" fi AC_SUBST([GLX_DEFINES]) +AC_SUBST([GLX_SYS_LIBS]) AM_CONDITIONAL(DRI, test "x$DRI" = xyes) if test "x$DRI" = xyes; then @@ -1461,7 +1472,21 @@ AC_SUBST([UTILS_SYS_LIBS]) # Some platforms require extra flags to do this. libtool should set the # necessary flags for each platform when -export-dynamic is passed to it. LD_EXPORT_SYMBOLS_FLAG="-export-dynamic" +LD_NO_UNDEFINED_FLAG= +XORG_DRIVER_LIBS= +case "$host_os" in + cygwin*) + LD_EXPORT_SYMBOLS_FLAG="-Wl,--export-all,--out-implib,lib\$@.a" + LD_NO_UNDEFINED_FLAG="-no-undefined -Wl,\$(top_builddir)/hw/xfree86/libXorg.exe.a" + XORG_DRIVER_LIBS="-lXorg.exe -L\${moduledir} -lshadow -lfb -no-undefined" + CYGWIN=yes + ;; +esac AC_SUBST([LD_EXPORT_SYMBOLS_FLAG]) +AC_SUBST([LD_NO_UNDEFINED_FLAG]) +AC_SUBST([XORG_DRIVER_LIBS]) +AM_CONDITIONAL([CYGWIN], [test x"$CYGWIN" = xyes]) +AM_CONDITIONAL([NO_UNDEFINED], [test x"$LD_NO_UNDEFINED_FLAG" != x]) dnl Imake defines SVR4 on SVR4 systems, and many files check for it, so dnl we need to replicate that here until those can all be fixed diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c index 104dcc9b3..d97180548 100644 --- a/xorg-server/dix/dispatch.c +++ b/xorg-server/dix/dispatch.c @@ -214,7 +214,7 @@ UpdateCurrentTimeIf(void) systime.milliseconds = GetTimeInMillis(); if (systime.milliseconds < currentTime.milliseconds) systime.months++; - if (*checkForInput[0] == *checkForInput[1]) + if (CompareTimeStamps(systime, currentTime) == LATER) currentTime = systime; } @@ -393,6 +393,9 @@ Dispatch(void) } /* now, finally, deal with client requests */ + /* Update currentTime so request time checks, such as for input + * device grabs, are calculated correctly */ + UpdateCurrentTimeIf(); result = ReadRequestFromClient(client); if (result <= 0) { if (result < 0) @@ -413,8 +416,8 @@ Dispatch(void) if (XSERVER_REQUEST_START_ENABLED()) XSERVER_REQUEST_START(LookupMajorName(client->majorOp), client->majorOp, - ((xReq *) client->requestBuffer)-> - length, client->index, + ((xReq *) client->requestBuffer)->length, + client->index, client->requestBuffer); #endif if (result > (maxBigRequestSize << 2)) diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c index b9f9cfa3c..9496b6f19 100644 --- a/xorg-server/dix/events.c +++ b/xorg-server/dix/events.c @@ -1273,18 +1273,11 @@ ComputeFreezes(void) event->root_x, event->root_y); if (!CheckDeviceGrabs(replayDev, event, syncEvents.replayWin)) { if (IsTouchEvent((InternalEvent *) event)) { - InternalEvent *events = InitEventList(GetMaximumEventsNum()); - int i, nev; TouchPointInfoPtr ti = TouchFindByClientID(replayDev, event->touchid); BUG_WARN(!ti); - nev = - GetTouchOwnershipEvents(events, replayDev, ti, - XIRejectTouch, - ti->listeners[0].listener, 0); - for (i = 0; i < nev; i++) - mieqProcessDeviceEvent(replayDev, events + i, NULL); - ProcessInputEvents(); + + TouchListenerAcceptReject(replayDev, ti, 0, XIRejectTouch); } else if (replayDev->focus && !IsPointerEvent((InternalEvent *) event)) @@ -1416,6 +1409,38 @@ ReattachToOldMaster(DeviceIntPtr dev) } /** + * Update touch records when an explicit grab is activated. Any touches owned by + * the grabbing client are updated so the listener state reflects the new grab. + */ +static void +UpdateTouchesForGrab(DeviceIntPtr mouse) +{ + int i; + + if (!mouse->touch || mouse->deviceGrab.fromPassiveGrab) + return; + + for (i = 0; i < mouse->touch->num_touches; i++) { + TouchPointInfoPtr ti = mouse->touch->touches + i; + GrabPtr grab = mouse->deviceGrab.grab; + + if (ti->active && + CLIENT_BITS(ti->listeners[0].listener) == grab->resource) { + ti->listeners[0].listener = grab->resource; + ti->listeners[0].level = grab->grabtype; + ti->listeners[0].state = LISTENER_IS_OWNER; + ti->listeners[0].window = grab->window; + + if (grab->grabtype == CORE || grab->grabtype == XI || + !xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin)) + ti->listeners[0].type = LISTENER_POINTER_GRAB; + else + ti->listeners[0].type = LISTENER_GRAB; + } + } +} + +/** * Activate a pointer grab on the given device. A pointer grab will cause all * core pointer events of this device to be delivered to the grabbing client only. * No other device will send core events to the grab client while the grab is @@ -1464,6 +1489,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab, grabinfo->fromPassiveGrab = isPassive; grabinfo->implicitGrab = autoGrab & ImplicitGrabMask; PostNewCursor(mouse); + UpdateTouchesForGrab(mouse); CheckGrabForSyncs(mouse, (Bool) grab->pointerMode, (Bool) grab->keyboardMode); } @@ -1480,6 +1506,8 @@ DeactivatePointerGrab(DeviceIntPtr mouse) DeviceIntPtr dev; Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab && mouse->deviceGrab.implicitGrab); + XID grab_resource = grab->resource; + int i; TouchRemovePointerGrab(mouse); @@ -1504,6 +1532,15 @@ DeactivatePointerGrab(DeviceIntPtr mouse) ReattachToOldMaster(mouse); ComputeFreezes(); + + /* If an explicit grab was deactivated, we must remove it from the head of + * all the touches' listener lists. */ + for (i = 0; mouse->touch && i < mouse->touch->num_touches; i++) { + TouchPointInfoPtr ti = mouse->touch->touches + i; + + if (ti->active && TouchResourceIsOwner(ti, grab_resource)) + TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch); + } } /** diff --git a/xorg-server/dix/resource.c b/xorg-server/dix/resource.c index 89d077642..2aafa343c 100644 --- a/xorg-server/dix/resource.c +++ b/xorg-server/dix/resource.c @@ -141,6 +141,7 @@ Equipment Corporation. #include "xace.h" #include <assert.h> #include "registry.h" +#include "gcstruct.h" #ifdef XSERVER_DTRACE #include <sys/types.h> @@ -182,50 +183,313 @@ RESTYPE TypeMask; struct ResourceType { DeleteType deleteFunc; + SizeType sizeFunc; + FindTypeSubResources findSubResFunc; int errorValue; }; +/** + * Used by all resources that don't specify a function to calculate + * resource size. Currently this is used for all resources with + * insignificant memory usage. + * + * @see GetResourceTypeSizeFunc, SetResourceTypeSizeFunc + * + * @param[in] value Pointer to resource object. + * + * @param[in] id Resource ID for the object. + * + * @param[out] size Fill all fields to zero to indicate that size of + * resource can't be determined. + */ +static void +GetDefaultBytes(pointer value, XID id, ResourceSizePtr size) +{ + size->resourceSize = 0; + size->pixmapRefSize = 0; + size->refCnt = 1; +} + +/** + * Used by all resources that don't specify a function to iterate + * through subresources. Currently this is used for all resources with + * insignificant memory usage. + * + * @see FindSubResources, SetResourceTypeFindSubResFunc + * + * @param[in] value Pointer to resource object. + * + * @param[in] func Function to call for each subresource. + + * @param[out] cdata Pointer to opaque data. + */ +static void +DefaultFindSubRes(pointer value, FindAllRes func, pointer cdata) +{ + /* do nothing */ +} + +/** + * Calculate drawable size in bytes. Reference counting is not taken + * into account. + * + * @param[in] drawable Pointer to a drawable. + * + * @return Estimate of total memory usage for the drawable. + */ +static unsigned long +GetDrawableBytes(DrawablePtr drawable) +{ + int bytes = 0; + + if (drawable) + { + int bytesPerPixel = drawable->bitsPerPixel >> 3; + int numberOfPixels = drawable->width * drawable->height; + bytes = numberOfPixels * bytesPerPixel; + } + + return bytes; +} + +/** + * Calculate pixmap size in bytes. Reference counting is taken into + * account. Any extra data attached by extensions and drivers is not + * taken into account. The purpose of this function is to estimate + * memory usage that can be attributed to single reference of the + * pixmap. + * + * @param[in] value Pointer to a pixmap. + * + * @param[in] id Resource ID of pixmap. If the pixmap hasn't been + * added as resource, just pass value->drawable.id. + * + * @param[out] size Estimate of memory usage attributed to a single + * pixmap reference. + */ +static void +GetPixmapBytes(pointer value, XID id, ResourceSizePtr size) +{ + PixmapPtr pixmap = value; + + size->resourceSize = 0; + size->pixmapRefSize = 0; + size->refCnt = pixmap->refcnt; + + if (pixmap && pixmap->refcnt) + { + DrawablePtr drawable = &pixmap->drawable; + size->resourceSize = GetDrawableBytes(drawable); + size->pixmapRefSize = size->resourceSize / pixmap->refcnt; + } +} + +/** + * Calculate window size in bytes. The purpose of this function is to + * estimate memory usage that can be attributed to all pixmap + * references of the window. + * + * @param[in] value Pointer to a window. + * + * @param[in] id Resource ID of window. + * + * @param[out] size Estimate of memory usage attributed to a all + * pixmap references of a window. + */ +static void +GetWindowBytes(pointer value, XID id, ResourceSizePtr size) +{ + SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); + ResourceSizeRec pixmapSize = { 0, 0, 0 }; + WindowPtr window = value; + + /* Currently only pixmap bytes are reported to clients. */ + size->resourceSize = 0; + + /* Calculate pixmap reference sizes. */ + size->pixmapRefSize = 0; + + size->refCnt = 1; + + if (window->backgroundState == BackgroundPixmap) + { + PixmapPtr pixmap = window->background.pixmap; + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } + if (window->border.pixmap && !window->borderIsPixel) + { + PixmapPtr pixmap = window->border.pixmap; + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } +} + +/** + * Iterate through subresources of a window. The purpose of this + * function is to gather accurate information on what resources + * a resource uses. + * + * @note Currently only sub-pixmaps are iterated + * + * @param[in] value Pointer to a window + * + * @param[in] func Function to call with each subresource + * + * @param[out] cdata Pointer to opaque data + */ +static void +FindWindowSubRes(pointer value, FindAllRes func, pointer cdata) +{ + WindowPtr window = value; + + /* Currently only pixmap subresources are reported to clients. */ + + if (window->backgroundState == BackgroundPixmap) + { + PixmapPtr pixmap = window->background.pixmap; + func(window->background.pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); + } + if (window->border.pixmap && !window->borderIsPixel) + { + PixmapPtr pixmap = window->border.pixmap; + func(window->background.pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); + } +} + +/** + * Calculate graphics context size in bytes. The purpose of this + * function is to estimate memory usage that can be attributed to all + * pixmap references of the graphics context. + * + * @param[in] value Pointer to a graphics context. + * + * @param[in] id Resource ID of graphics context. + * + * @param[out] size Estimate of memory usage attributed to a all + * pixmap references of a graphics context. + */ +static void +GetGcBytes(pointer value, XID id, ResourceSizePtr size) +{ + SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); + ResourceSizeRec pixmapSize = { 0, 0, 0 }; + GCPtr gc = value; + + /* Currently only pixmap bytes are reported to clients. */ + size->resourceSize = 0; + + /* Calculate pixmap reference sizes. */ + size->pixmapRefSize = 0; + + size->refCnt = 1; + if (gc->stipple) + { + PixmapPtr pixmap = gc->stipple; + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } + if (gc->tile.pixmap && !gc->tileIsPixel) + { + PixmapPtr pixmap = gc->tile.pixmap; + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } +} + +/** + * Iterate through subresources of a graphics context. The purpose of + * this function is to gather accurate information on what resources a + * resource uses. + * + * @note Currently only sub-pixmaps are iterated + * + * @param[in] value Pointer to a window + * + * @param[in] func Function to call with each subresource + * + * @param[out] cdata Pointer to opaque data + */ +static void +FindGCSubRes(pointer value, FindAllRes func, pointer cdata) +{ + GCPtr gc = value; + + /* Currently only pixmap subresources are reported to clients. */ + + if (gc->stipple) + { + PixmapPtr pixmap = gc->stipple; + func(pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); + } + if (gc->tile.pixmap && !gc->tileIsPixel) + { + PixmapPtr pixmap = gc->tile.pixmap; + func(pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); + } +} + static struct ResourceType *resourceTypes; static const struct ResourceType predefTypes[] = { [RT_NONE & (RC_LASTPREDEF - 1)] = { .deleteFunc = (DeleteType) NoopDDA, + .sizeFunc = GetDefaultBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadValue, }, [RT_WINDOW & (RC_LASTPREDEF - 1)] = { .deleteFunc = DeleteWindow, + .sizeFunc = GetWindowBytes, + .findSubResFunc = FindWindowSubRes, .errorValue = BadWindow, }, [RT_PIXMAP & (RC_LASTPREDEF - 1)] = { .deleteFunc = dixDestroyPixmap, + .sizeFunc = GetPixmapBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadPixmap, }, [RT_GC & (RC_LASTPREDEF - 1)] = { .deleteFunc = FreeGC, + .sizeFunc = GetGcBytes, + .findSubResFunc = FindGCSubRes, .errorValue = BadGC, }, [RT_FONT & (RC_LASTPREDEF - 1)] = { .deleteFunc = CloseFont, + .sizeFunc = GetDefaultBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadFont, }, [RT_CURSOR & (RC_LASTPREDEF - 1)] = { .deleteFunc = FreeCursor, + .sizeFunc = GetDefaultBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadCursor, }, [RT_COLORMAP & (RC_LASTPREDEF - 1)] = { .deleteFunc = FreeColormap, + .sizeFunc = GetDefaultBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadColor, }, [RT_CMAPENTRY & (RC_LASTPREDEF - 1)] = { .deleteFunc = FreeClientPixels, + .sizeFunc = GetDefaultBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadColor, }, [RT_OTHERCLIENT & (RC_LASTPREDEF - 1)] = { .deleteFunc = OtherClientGone, + .sizeFunc = GetDefaultBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadValue, }, [RT_PASSIVEGRAB & (RC_LASTPREDEF - 1)] = { .deleteFunc = DeletePassiveGrab, + .sizeFunc = GetDefaultBytes, + .findSubResFunc = DefaultFindSubRes, .errorValue = BadValue, }, }; @@ -256,6 +520,8 @@ CreateNewResourceType(DeleteType deleteFunc, const char *name) lastResourceType = next; resourceTypes = types; resourceTypes[next].deleteFunc = deleteFunc; + resourceTypes[next].sizeFunc = GetDefaultBytes; + resourceTypes[next].findSubResFunc = DefaultFindSubRes; resourceTypes[next].errorValue = BadValue; /* Called even if name is NULL, to remove any previous entry */ @@ -264,6 +530,57 @@ CreateNewResourceType(DeleteType deleteFunc, const char *name) return next; } +/** + * Get the function used to calculate resource size. Extensions and + * drivers need to be able to determine the current size calculation + * function if they want to wrap or override it. + * + * @param[in] type Resource type used in size calculations. + * + * @return Function to calculate the size of a single + * resource. + */ +SizeType +GetResourceTypeSizeFunc(RESTYPE type) +{ + return resourceTypes[type & TypeMask].sizeFunc; +} + +/** + * Override the default function that calculates resource size. For + * example, video driver knows better how to calculate pixmap memory + * usage and can therefore wrap or override size calculation for + * RT_PIXMAP. + * + * @param[in] type Resource type used in size calculations. + * + * @param[in] sizeFunc Function to calculate the size of a single + * resource. + */ +void +SetResourceTypeSizeFunc(RESTYPE type, SizeType sizeFunc) +{ + resourceTypes[type & TypeMask].sizeFunc = sizeFunc; +} + +/** + * Provide a function for iterating the subresources of a resource. + * This allows for example more accurate accounting of the (memory) + * resources consumed by a resource. + * + * @see FindSubResources + * + * @param[in] type Resource type used in size calculations. + * + * @param[in] sizeFunc Function to calculate the size of a single + * resource. + */ +void +SetResourceTypeFindSubResFunc(RESTYPE type, FindTypeSubResources findFunc) +{ + resourceTypes[type & TypeMask].findSubResFunc = findFunc; +} + void SetResourceTypeErrorValue(RESTYPE type, int errorValue) { @@ -326,25 +643,32 @@ InitClientResources(ClientPtr client) return TRUE; } -static int -Hash(int client, XID id) +int +HashResourceID(XID id, int numBits) { id &= RESOURCE_ID_MASK; - switch (clientTable[client].hashsize) { - case 6: - return ((int) (0x03F & (id ^ (id >> 6) ^ (id >> 12)))); - case 7: - return ((int) (0x07F & (id ^ (id >> 7) ^ (id >> 13)))); - case 8: - return ((int) (0x0FF & (id ^ (id >> 8) ^ (id >> 16)))); - case 9: - return ((int) (0x1FF & (id ^ (id >> 9)))); - case 10: - return ((int) (0x3FF & (id ^ (id >> 10)))); - case 11: - return ((int) (0x7FF & (id ^ (id >> 11)))); - } - return -1; + switch (numBits) + { + case 6: + return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12)))); + case 7: + return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13)))); + case 8: + return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16)))); + case 9: + return ((int)(0x1FF & (id ^ (id>>9)))); + case 10: + return ((int)(0x3FF & (id ^ (id>>10)))); + case 11: + return ((int)(0x7FF & (id ^ (id>>11)))); + } + if (numBits >= 11) + return ((int)(0x7FF & (id ^ (id>>11)))); + else + { + assert(numBits >= 0); + return id & ~((~0) << numBits); + } } static XID @@ -355,7 +679,7 @@ AvailableID(int client, XID id, XID maxid, XID goodid) if ((goodid >= id) && (goodid <= maxid)) return goodid; for (; id <= maxid; id++) { - res = clientTable[client].resources[Hash(client, id)]; + res = clientTable[client].resources[HashResourceID(id, clientTable[client].hashsize)]; while (res && (res->id != id)) res = res->next; if (!res) @@ -481,7 +805,7 @@ AddResource(XID id, RESTYPE type, pointer value) } if ((rrec->elements >= 4 * rrec->buckets) && (rrec->hashsize < MAXHASHSIZE)) RebuildTable(client); - head = &rrec->resources[Hash(client, id)]; + head = &rrec->resources[HashResourceID(id, clientTable[client].hashsize)]; res = malloc(sizeof(ResourceRec)); if (!res) { (*resourceTypes[type & TypeMask].deleteFunc) (value, id); @@ -529,7 +853,7 @@ RebuildTable(int client) for (res = *rptr; res; res = next) { next = res->next; res->next = NULL; - tptr = &tails[Hash(client, res->id)]; + tptr = &tails[HashResourceID(res->id, clientTable[client].hashsize)]; **tptr = res; *tptr = &res->next; } @@ -561,7 +885,7 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType) int elements; if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) { - head = &clientTable[cid].resources[Hash(cid, id)]; + head = &clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; eltptr = &clientTable[cid].elements; prev = head; @@ -595,7 +919,7 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree) ResourcePtr *prev, *head; if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) { - head = &clientTable[cid].resources[Hash(cid, id)]; + head = &clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; prev = head; while ((res = *prev)) { @@ -630,7 +954,7 @@ ChangeResourceValue(XID id, RESTYPE rtype, pointer value) ResourcePtr res; if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) { - res = clientTable[cid].resources[Hash(cid, id)]; + res = clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; for (; res; res = res->next) if ((res->id == id) && (res->type == rtype)) { @@ -674,6 +998,15 @@ FindClientResourcesByType(ClientPtr client, } } +void FindSubResources(pointer resource, + RESTYPE type, + FindAllRes func, + pointer cdata) +{ + struct ResourceType rtype = resourceTypes[type & TypeMask]; + rtype.findSubResFunc(resource, func, cdata); +} + void FindAllClientResources(ClientPtr client, FindAllRes func, pointer cdata) { @@ -859,7 +1192,7 @@ dixLookupResourceByType(pointer *result, XID id, RESTYPE rtype, return BadImplementation; if ((cid < MAXCLIENTS) && clientTable[cid].buckets) { - res = clientTable[cid].resources[Hash(cid, id)]; + res = clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; for (; res; res = res->next) if (res->id == id && res->type == rtype) @@ -892,7 +1225,7 @@ dixLookupResourceByClass(pointer *result, XID id, RESTYPE rclass, *result = NULL; if ((cid < MAXCLIENTS) && clientTable[cid].buckets) { - res = clientTable[cid].resources[Hash(cid, id)]; + res = clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; for (; res; res = res->next) if (res->id == id && (res->type & rclass)) diff --git a/xorg-server/dix/touch.c b/xorg-server/dix/touch.c index 0829b6545..dd16367d0 100644 --- a/xorg-server/dix/touch.c +++ b/xorg-server/dix/touch.c @@ -364,14 +364,6 @@ TouchEndTouch(DeviceIntPtr dev, TouchPointInfoPtr ti) { if (ti->emulate_pointer) { GrabPtr grab; - DeviceEvent ev; - - memset(&ev, 0, sizeof(ev)); - ev.type = ET_TouchEnd; - ev.detail.button = 1; - ev.touchid = ti->client_id; - ev.flags = TOUCH_POINTER_EMULATED | TOUCH_END; - UpdateDeviceState(dev, &ev); if ((grab = dev->deviceGrab.grab)) { if (dev->deviceGrab.fromPassiveGrab && @@ -482,10 +474,22 @@ TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource) flags = TOUCH_CLIENT_ID | TOUCH_REPLAYING; if (ti->emulate_pointer) flags |= TOUCH_POINTER_EMULATED; - /* send fake begin event to next owner */ + /* Generate events based on a fake touch begin event to get DCCE events if + * needed */ + /* FIXME: This needs to be cleaned up */ nev = GetTouchEvents(tel, dev, ti->client_id, XI_TouchBegin, flags, mask); - for (i = 0; i < nev; i++) - DeliverTouchEvents(dev, ti, tel + i, resource); + for (i = 0; i < nev; i++) { + /* Send saved touch begin event */ + if (tel[i].any.type == ET_TouchBegin) { + DeviceEvent *ev = &ti->history[0]; + ev->flags |= TOUCH_REPLAYING; + DeliverTouchEvents(dev, ti, (InternalEvent*)ev, resource); + } + else {/* Send DCCE event */ + tel[i].any.time = ti->history[0].time; + DeliverTouchEvents(dev, ti, tel + i, resource); + } + } valuator_mask_free(&mask); FreeEventList(tel, GetMaximumEventsNum()); @@ -542,22 +546,12 @@ TouchBuildDependentSpriteTrace(DeviceIntPtr dev, SpritePtr sprite) * TouchBegin events. */ Bool -TouchEnsureSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, - InternalEvent *ev) +TouchBuildSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, + InternalEvent *ev) { TouchClassPtr t = sourcedev->touch; SpritePtr sprite = &ti->sprite; - /* We may not have a sprite if there are no applicable grabs or - * event selections, or if they've disappeared, or if all the grab - * owners have rejected the touch. Don't bother delivering motion - * events if not, but TouchEnd events still need to be processed so - * we can call FinishTouchPoint and release it for later use. */ - if (ev->any.type == ET_TouchEnd) - return TRUE; - else if (ev->any.type != ET_TouchBegin) - return (sprite->spriteTraceGood > 0); - if (t->mode == XIDirectTouch) { /* Focus immediately under the touchpoint in direct touch mode. * XXX: Do we need to handle crossing screens here? */ @@ -821,6 +815,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, if (mask & EVENT_CORE_MASK) { int coretype = GetCoreType(TouchGetPointerEventType(ev)); Mask core_filter = event_get_filter_from_type(dev, coretype); + OtherClients *oclients; /* window owner */ if (IsMaster(dev) && (win->eventMask & core_filter)) { @@ -832,13 +827,12 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, } /* all others */ - nt_list_for_each_entry(iclients, (InputClients *) wOtherClients(win), - next) { - if (!(iclients->mask[XIAllDevices] & core_filter)) + nt_list_for_each_entry(oclients, wOtherClients(win), next) { + if (!(oclients->mask & core_filter)) continue; TouchEventHistoryAllocate(ti); - TouchAddListener(ti, iclients->resource, CORE, + TouchAddListener(ti, oclients->resource, CORE, type, LISTENER_AWAITING_BEGIN, win); return TRUE; } @@ -874,6 +868,11 @@ TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev) if (dev->deviceGrab.grab) TouchAddActiveGrabListener(dev, ti, ev, dev->deviceGrab.grab); + /* We set up an active touch listener for existing touches, but not any + * passive grab or regular listeners. */ + if (ev->any.type != ET_TouchBegin) + return; + /* First, find all grabbing clients from the root window down * to the deepest child window. */ for (i = 0; i < sprite->spriteTraceGood; i++) { @@ -960,15 +959,48 @@ TouchListenerGone(XID resource) } int +TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, int listener, + int mode) +{ + InternalEvent *events; + int nev; + int i; + + if (listener > 0) { + if (mode == XIRejectTouch) + TouchRejected(dev, ti, ti->listeners[listener].listener, NULL); + else + ti->listeners[listener].state = LISTENER_EARLY_ACCEPT; + + return Success; + } + + events = InitEventList(GetMaximumEventsNum()); + if (!events) { + BUG_WARN_MSG(TRUE, "Failed to allocate touch ownership events\n"); + return BadAlloc; + } + + nev = GetTouchOwnershipEvents(events, dev, ti, mode, + ti->listeners[0].listener, 0); + BUG_WARN_MSG(nev == 0, "Failed to get touch ownership events\n"); + + for (i = 0; i < nev; i++) + mieqProcessDeviceEvent(dev, events + i, NULL); + + ProcessInputEvents(); + + FreeEventList(events, GetMaximumEventsNum()); + + return nev ? Success : BadMatch; +} + +int TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode, uint32_t touchid, Window grab_window, XID *error) { TouchPointInfoPtr ti; - int nev, i; - InternalEvent *events = InitEventList(GetMaximumEventsNum()); - - if (!events) - return BadAlloc; + int i; if (!dev->touch) { *error = dev->id; @@ -989,24 +1021,5 @@ TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode, if (i == ti->num_listeners) return BadAccess; - if (i > 0) { - if (mode == XIRejectTouch) - TouchRejected(dev, ti, ti->listeners[i].listener, NULL); - else - ti->listeners[i].state = LISTENER_EARLY_ACCEPT; - - return Success; - } - - nev = GetTouchOwnershipEvents(events, dev, ti, mode, - ti->listeners[0].listener, 0); - if (nev == 0) - return BadAlloc; - for (i = 0; i < nev; i++) - mieqProcessDeviceEvent(dev, events + i, NULL); - - ProcessInputEvents(); - - FreeEventList(events, GetMaximumEventsNum()); - return Success; + return TouchListenerAcceptReject(dev, ti, i, mode); } diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am index 72be8891c..d61c6401b 100644 --- a/xorg-server/hw/xfree86/Makefile.am +++ b/xorg-server/hw/xfree86/Makefile.am @@ -25,9 +25,9 @@ if INT10MODULE INT10_SUBDIR = int10 endif -SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw os-support parser \ - ramdac shadowfb $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \ - loader dixmods exa modes \ +SUBDIRS = common ddc x86emu $(INT10_SUBDIR) os-support parser \ + ramdac $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \ + loader modes . i2c dixmods fbdevhw shadowfb exa \ $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) doc man DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \ @@ -92,6 +92,9 @@ if INSTALL_SETUID chown root $(DESTDIR)$(bindir)/Xorg chmod u+s $(DESTDIR)$(bindir)/Xorg endif +if CYGWIN + $(INSTALL_DATA) libXorg.exe.a $(DESTDIR)$(libdir)/libXorg.exe.a +endif # Use variables from XORG_MANPAGE_SECTIONS and X Server configuration # Do not include manpages.am as values are not appropriate for rc files @@ -113,3 +116,12 @@ sdksyms.dep sdksyms.c: sdksyms.sh SDKSYMS_DEP = sdksyms.dep include $(SDKSYMS_DEP) + +i2c/libi2c.la: + $(AM_V_at)cd i2c && $(MAKE) libi2c.la + +dixmods/libdixmods.la: + $(AM_V_at)cd dixmods && $(MAKE) libdixmods.la + +dixmods/libxorgxkb.la: + $(AM_V_at)cd dixmods && $(MAKE) libxorgxkb.la diff --git a/xorg-server/hw/xfree86/common/xf86Config.c b/xorg-server/hw/xfree86/common/xf86Config.c index ec679df16..b22b617a4 100644 --- a/xorg-server/hw/xfree86/common/xf86Config.c +++ b/xorg-server/hw/xfree86/common/xf86Config.c @@ -125,6 +125,11 @@ static ModuleDefault ModuleDefaults[] = { #ifdef DRI2 {.name = "dri2",.toLoad = TRUE,.load_opt = NULL}, #endif +#ifdef __CYGWIN__ + /* load DIX modules used by drivers first */ + {.name = "fb",.toLoad = TRUE,.load_opt = NULL}, + {.name = "shadow",.toLoad = TRUE,.load_opt = NULL}, +#endif {.name = NULL,.toLoad = FALSE,.load_opt = NULL} }; diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c index 2a7d0a37e..f42dd1083 100644 --- a/xorg-server/hw/xfree86/common/xf86Init.c +++ b/xorg-server/hw/xfree86/common/xf86Init.c @@ -1580,3 +1580,10 @@ xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth) else return 0; } + +#ifdef DDXBEFORERESET +void +ddxBeforeReset(void) +{ +} +#endif diff --git a/xorg-server/hw/xfree86/dixmods/Makefile.am b/xorg-server/hw/xfree86/dixmods/Makefile.am index a5be3ae00..6f4af6c2c 100644 --- a/xorg-server/hw/xfree86/dixmods/Makefile.am +++ b/xorg-server/hw/xfree86/dixmods/Makefile.am @@ -30,35 +30,39 @@ INCLUDES = @XORG_INCS@ \ -I$(top_srcdir)/miext/shadow \ -I$(top_srcdir)/glx -libdbe_la_LDFLAGS = -module -avoid-version +libdbe_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libdbe_la_LIBADD = $(top_builddir)/dbe/libdbe.la libdbe_la_SOURCES = dbemodule.c -libfb_la_LDFLAGS = -module -avoid-version +libfb_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libfb_la_LIBADD = $(top_builddir)/fb/libfb.la libfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c libfb_la_CFLAGS = $(AM_CFLAGS) -libwfb_la_LDFLAGS = -module -avoid-version +libwfb_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libwfb_la_LIBADD = $(top_builddir)/fb/libwfb.la libwfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c libwfb_la_CFLAGS = $(AM_CFLAGS) -DFB_ACCESS_WRAPPER -libglx_la_LDFLAGS = -module -avoid-version +libglx_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) +libglx_la_LIBADD = $(top_builddir)/glx/libglx.la $(GLX_SYS_LIBS) if AIGLX_DRI_LOADER -GLXDRI_LIBRARY = $(top_builddir)/glx/libglxdri.la +libglx_la_LIBADD += $(top_builddir)/glx/libglxdri.la +if NO_UNDEFINED +libglx_la_LIBADD += ../dri/libdri.la ../dri2/libdri2.la +endif endif -libglx_la_LIBADD = \ - $(top_builddir)/glx/libglx.la \ - $(GLXDRI_LIBRARY) libglx_la_SOURCES = glxmodule.c -librecord_la_LDFLAGS = -module -avoid-version +librecord_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) librecord_la_LIBADD = $(top_builddir)/record/librecord.la librecord_la_SOURCES = recordmod.c -libshadow_la_LDFLAGS = -module -avoid-version +libshadow_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libshadow_la_LIBADD = $(top_builddir)/miext/shadow/libshadow.la +if NO_UNDEFINED +libshadow_la_LIBADD += libfb.la +endif libshadow_la_SOURCES = shmodule.c libdixmods_la_SOURCES = $(top_srcdir)/mi/miinitext.c diff --git a/xorg-server/hw/xfree86/dixmods/extmod/Makefile.am b/xorg-server/hw/xfree86/dixmods/extmod/Makefile.am index 87c28a421..d08e9ad15 100644 --- a/xorg-server/hw/xfree86/dixmods/extmod/Makefile.am +++ b/xorg-server/hw/xfree86/dixmods/extmod/Makefile.am @@ -21,7 +21,7 @@ INCLUDES = @XORG_INCS@ \ -I$(top_srcdir)/hw/xfree86/loader \ -I$(top_srcdir)/miext/shadow -libextmod_la_LDFLAGS = -module -avoid-version +libextmod_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libextmod_la_SOURCES = modinit.c \ modinit.h \ $(DGA_SRCS) \ diff --git a/xorg-server/hw/xfree86/dri/Makefile.am b/xorg-server/hw/xfree86/dri/Makefile.am index a7b491c6e..194cf8e3f 100644 --- a/xorg-server/hw/xfree86/dri/Makefile.am +++ b/xorg-server/hw/xfree86/dri/Makefile.am @@ -12,7 +12,8 @@ libdri_la_CFLAGS = -I$(top_srcdir)/hw/xfree86/common \ @DIX_CFLAGS@ @XORG_CFLAGS@ @DRIPROTO_CFLAGS@ \ @LIBDRM_CFLAGS@ \ @DRI_CFLAGS@ -libdri_la_LDFLAGS = -module -avoid-version @LIBDRM_LIBS@ +libdri_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) +libdri_la_LIBADD = @LIBDRM_LIBS@ libdri_ladir = $(moduledir)/extensions libdri_la_SOURCES = \ dri.c \ diff --git a/xorg-server/hw/xfree86/dri2/Makefile.am b/xorg-server/hw/xfree86/dri2/Makefile.am index c9fdde2f8..0e40fbcf2 100644 --- a/xorg-server/hw/xfree86/dri2/Makefile.am +++ b/xorg-server/hw/xfree86/dri2/Makefile.am @@ -6,7 +6,8 @@ libdri2_la_CFLAGS = \ -I$(top_srcdir)/hw/xfree86/common \ -I$(top_srcdir)/hw/xfree86/os-support/bus -libdri2_la_LDFLAGS = -module -avoid-version @LIBDRM_LIBS@ +libdri2_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) +libdri2_la_LIBADD = @LIBDRM_LIBS@ libdri2_ladir = $(moduledir)/extensions libdri2_la_SOURCES = \ dri2.c \ diff --git a/xorg-server/hw/xfree86/exa/Makefile.am b/xorg-server/hw/xfree86/exa/Makefile.am index 3ced531fa..433908411 100644 --- a/xorg-server/hw/xfree86/exa/Makefile.am +++ b/xorg-server/hw/xfree86/exa/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS = man module_LTLIBRARIES = libexa.la -libexa_la_LDFLAGS = -module -avoid-version +libexa_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) INCLUDES = \ $(XORG_INCS) \ @@ -15,4 +15,4 @@ libexa_la_SOURCES = \ examodule.c libexa_la_LIBADD = \ - ../../../exa/libexa.la + ../../../exa/libexa.la $(PIXMAN_LIBS) diff --git a/xorg-server/hw/xfree86/fbdevhw/Makefile.am b/xorg-server/hw/xfree86/fbdevhw/Makefile.am index 4472acd91..1fa9321cb 100644 --- a/xorg-server/hw/xfree86/fbdevhw/Makefile.am +++ b/xorg-server/hw/xfree86/fbdevhw/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS = man module_LTLIBRARIES = libfbdevhw.la -libfbdevhw_la_LDFLAGS = -module -avoid-version +libfbdevhw_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) if FBDEVHW libfbdevhw_la_SOURCES = fbdevhw.c diff --git a/xorg-server/hw/xfree86/i2c/Makefile.am b/xorg-server/hw/xfree86/i2c/Makefile.am index 0b80cc8a6..f08541cf0 100644 --- a/xorg-server/hw/xfree86/i2c/Makefile.am +++ b/xorg-server/hw/xfree86/i2c/Makefile.am @@ -21,23 +21,26 @@ sdk_HEADERS = xf86i2c.h bt829.h fi1236.h msp3430.h tda8425.h tda9850.h tda9885.h # # i2c drivers # -bt829_drv_la_LDFLAGS = -module -avoid-version +bt829_drv_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) bt829_drv_la_SOURCES = bt829.c bt829.h bt829_module.c -fi1236_drv_la_LDFLAGS = -module -avoid-version +fi1236_drv_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) fi1236_drv_la_SOURCES = fi1236.c fi1236.h fi1236_module.c +if NO_UNDEFINED +fi1236_drv_la_LIBADD = tda9885_drv.la +endif -msp3430_drv_la_LDFLAGS = -module -avoid-version +msp3430_drv_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) msp3430_drv_la_SOURCES = msp3430.c msp3430.h msp3430_module.c -tda8425_drv_la_LDFLAGS = -module -avoid-version +tda8425_drv_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) tda8425_drv_la_SOURCES = tda8425.c tda8425.h tda8425_module.c -tda9850_drv_la_LDFLAGS = -module -avoid-version +tda9850_drv_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) tda9850_drv_la_SOURCES = tda9850.c tda9850.h tda9850_module.c -tda9885_drv_la_LDFLAGS = -module -avoid-version +tda9885_drv_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) tda9885_drv_la_SOURCES = tda9885.c tda9885.h tda9885_module.c -uda1380_drv_la_LDFLAGS = -module -avoid-version +uda1380_drv_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) uda1380_drv_la_SOURCES = uda1380.c uda1380.h uda1380_module.c diff --git a/xorg-server/hw/xfree86/loader/loadmod.c b/xorg-server/hw/xfree86/loader/loadmod.c index c6b559072..706b9b3e8 100644 --- a/xorg-server/hw/xfree86/loader/loadmod.c +++ b/xorg-server/hw/xfree86/loader/loadmod.c @@ -212,9 +212,15 @@ static const char *stdSubdirs[] = { * to port this DDX to, say, Darwin, we'll need to fix this. */ static PatternRec stdPatterns[] = { +#ifdef __CYGWIN__ + {"^cyg(.*)\\.dll$",}, + {"(.*)_drv\\.dll$",}, + {"(.*)\\.dll$",}, +#else {"^lib(.*)\\.so$",}, {"(.*)_drv\\.so$",}, {"(.*)\\.so$",}, +#endif {NULL,} }; @@ -408,21 +414,33 @@ FindModuleInSubdir(const char *dirpath, const char *module) continue; } +#ifdef __CYGWIN__ + snprintf(tmpBuf, PATH_MAX, "cyg%s.dll", module); +#else snprintf(tmpBuf, PATH_MAX, "lib%s.so", module); +#endif if (strcmp(direntry->d_name, tmpBuf) == 0) { if (asprintf(&ret, "%s%s", dirpath, tmpBuf) == -1) ret = NULL; break; } +#ifdef __CYGWIN__ + snprintf(tmpBuf, PATH_MAX, "%s_drv.dll", module); +#else snprintf(tmpBuf, PATH_MAX, "%s_drv.so", module); +#endif if (strcmp(direntry->d_name, tmpBuf) == 0) { if (asprintf(&ret, "%s%s", dirpath, tmpBuf) == -1) ret = NULL; break; } +#ifdef __CYGWIN__ + snprintf(tmpBuf, PATH_MAX, "%s.dll", module); +#else snprintf(tmpBuf, PATH_MAX, "%s.so", module); +#endif if (strcmp(direntry->d_name, tmpBuf) == 0) { if (asprintf(&ret, "%s%s", dirpath, tmpBuf) == -1) ret = NULL; diff --git a/xorg-server/hw/xfree86/man/xorg.conf.man b/xorg-server/hw/xfree86/man/xorg.conf.man index 72e57136c..da67f59c9 100644 --- a/xorg-server/hw/xfree86/man/xorg.conf.man +++ b/xorg-server/hw/xfree86/man/xorg.conf.man @@ -701,7 +701,7 @@ This instructs the server to load the module called The module name given should be the module's standard name, not the module file name. The standard name is case\-sensitive, and does not include the \(lqlib\(rq -prefix, or the \(lq.a\(rq, \(lq.o\(rq, or \(lq.so\(rq suffixes. +or \(lqcyg\(rq prefixes, or the \(lq.so\(rq or \(lq.dll\(rq suffixes. .PP .RS 7 Example: the DRI extension module can be loaded with the following entry: diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c index 6d5e92f12..fee1ae774 100644 --- a/xorg-server/hw/xfree86/modes/xf86Crtc.c +++ b/xorg-server/hw/xfree86/modes/xf86Crtc.c @@ -44,7 +44,9 @@ #include "X11/Xatom.h" #include "picturestr.h" +#ifdef XV #include "xf86xv.h" +#endif #define NO_OUTPUT_DEFAULT_WIDTH 1024 #define NO_OUTPUT_DEFAULT_HEIGHT 768 diff --git a/xorg-server/hw/xfree86/os-support/xf86_OSlib.h b/xorg-server/hw/xfree86/os-support/xf86_OSlib.h index 9161e181e..e931b09a1 100644 --- a/xorg-server/hw/xfree86/os-support/xf86_OSlib.h +++ b/xorg-server/hw/xfree86/os-support/xf86_OSlib.h @@ -171,7 +171,7 @@ /**************************************************************************/ /* Linux or Glibc-based system */ /**************************************************************************/ -#if defined(__linux__) || defined(__GLIBC__) +#if defined(__linux__) || defined(__GLIBC__) || defined(__CYGWIN__) #include <sys/ioctl.h> #include <signal.h> #include <stdlib.h> diff --git a/xorg-server/hw/xfree86/sdksyms.sh b/xorg-server/hw/xfree86/sdksyms.sh index 40ea7c8da..3815525fa 100644 --- a/xorg-server/hw/xfree86/sdksyms.sh +++ b/xorg-server/hw/xfree86/sdksyms.sh @@ -252,6 +252,8 @@ cat > sdksyms.c << EOF */ +#include "compositeext.h" + /* xfixes/Makefile.am */ #include "xfixes.h" diff --git a/xorg-server/hw/xfree86/shadowfb/Makefile.am b/xorg-server/hw/xfree86/shadowfb/Makefile.am index 39c66109e..5756fca3b 100644 --- a/xorg-server/hw/xfree86/shadowfb/Makefile.am +++ b/xorg-server/hw/xfree86/shadowfb/Makefile.am @@ -1,6 +1,7 @@ module_LTLIBRARIES = libshadowfb.la -libshadowfb_la_LDFLAGS = -module -avoid-version +libshadowfb_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libshadowfb_la_SOURCES = sfbmodule.c shadow.c +libshadowfb_la_LIBADD = $(PIXMAN_LIBS) sdk_HEADERS = shadowfb.h diff --git a/xorg-server/hw/xfree86/vbe/Makefile.am b/xorg-server/hw/xfree86/vbe/Makefile.am index 4b794e647..0b24faf1f 100644 --- a/xorg-server/hw/xfree86/vbe/Makefile.am +++ b/xorg-server/hw/xfree86/vbe/Makefile.am @@ -1,6 +1,9 @@ module_LTLIBRARIES = libvbe.la -libvbe_la_LDFLAGS = -module -avoid-version +libvbe_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libvbe_la_SOURCES = vbe.c vbeModes.c vbe_module.c +if NO_UNDEFINED +libvbe_la_LIBADD = ../int10/libint10.la +endif sdk_HEADERS = vbe.h vbeModes.h diff --git a/xorg-server/hw/xfree86/xaa/Makefile.am b/xorg-server/hw/xfree86/xaa/Makefile.am index 78d934876..f6480a713 100644 --- a/xorg-server/hw/xfree86/xaa/Makefile.am +++ b/xorg-server/hw/xfree86/xaa/Makefile.am @@ -10,7 +10,7 @@ POLYSEG = s-xaaLine.c s-xaaDashLine.c if XAA -libxaa_la_LDFLAGS = -module -avoid-version +libxaa_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) if COMPOSITE libxaa_la_LIBADD = $(top_builddir)/miext/cw/libcw.la endif diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h index d891fe5db..991d64813 100644 --- a/xorg-server/include/input.h +++ b/xorg-server/include/input.h @@ -563,8 +563,8 @@ extern void TouchAddListener(TouchPointInfoPtr ti, XID resource, extern Bool TouchRemoveListener(TouchPointInfoPtr ti, XID resource); extern void TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev); -extern Bool TouchEnsureSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, - InternalEvent *ev); +extern Bool TouchBuildSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, + InternalEvent *ev); extern Bool TouchBuildDependentSpriteTrace(DeviceIntPtr dev, SpritePtr sprite); extern int TouchConvertToPointerEvent(const InternalEvent *ev, InternalEvent *motion, @@ -572,6 +572,8 @@ extern int TouchConvertToPointerEvent(const InternalEvent *ev, extern int TouchGetPointerEventType(const InternalEvent *ev); extern void TouchRemovePointerGrab(DeviceIntPtr dev); extern void TouchListenerGone(XID resource); +extern int TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, + int listener, int mode); extern int TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode, uint32_t touchid, Window grab_window, XID *error); diff --git a/xorg-server/include/protocol-versions.h b/xorg-server/include/protocol-versions.h index 479ac2f77..cb8e213bb 100644 --- a/xorg-server/include/protocol-versions.h +++ b/xorg-server/include/protocol-versions.h @@ -135,7 +135,7 @@ /* Resource */ #define SERVER_XRES_MAJOR_VERSION 1 -#define SERVER_XRES_MINOR_VERSION 0 +#define SERVER_XRES_MINOR_VERSION 2 /* XvMC */ #define SERVER_XVMC_MAJOR_VERSION 1 diff --git a/xorg-server/include/resource.h b/xorg-server/include/resource.h index 068057013..19f46d108 100644 --- a/xorg-server/include/resource.h +++ b/xorg-server/include/resource.h @@ -152,12 +152,46 @@ typedef Bool (*FindComplexResType) (pointer /*value */ , XID /*id */ , pointer /*cdata */ ); +/* Structure for estimating resource memory usage. Memory usage + * consists of space allocated for the resource itself and of + * references to other resources. Currently the most important use for + * this structure is to estimate pixmap usage of different resources + * more accurately. */ +typedef struct { + /* Size of resource itself. Zero if not implemented. */ + unsigned long resourceSize; + /* Size attributed to pixmap references from the resource. */ + unsigned long pixmapRefSize; + /* Number of references to this resource; typically 1 */ + unsigned long refCnt; +} ResourceSizeRec, *ResourceSizePtr; + +typedef void (*SizeType)(pointer /*value*/, + XID /*id*/, + ResourceSizePtr /*size*/); + extern _X_EXPORT RESTYPE CreateNewResourceType(DeleteType /*deleteFunc */ , const char * /*name */ ); +typedef void (*FindTypeSubResources)(pointer /* value */, + FindAllRes /* func */, + pointer /* cdata */); + extern _X_EXPORT void SetResourceTypeErrorValue(RESTYPE /*type */ , int /*errorValue */ ); +extern _X_EXPORT SizeType GetResourceTypeSizeFunc( + RESTYPE /*type*/); + +extern _X_EXPORT void SetResourceTypeFindSubResFunc( + RESTYPE /*type*/, FindTypeSubResources /*findFunc*/); + +extern _X_EXPORT void SetResourceTypeSizeFunc( + RESTYPE /*type*/, SizeType /*sizeFunc*/); + +extern _X_EXPORT void SetResourceTypeErrorValue( + RESTYPE /*type*/, int /*errorValue*/); + extern _X_EXPORT RESTYPE CreateNewResourceClass(void); extern _X_EXPORT Bool InitClientResources(ClientPtr /*client */ ); @@ -193,6 +227,15 @@ extern _X_EXPORT void FindAllClientResources(ClientPtr /*client */ , FindAllRes /*func */ , pointer /*cdata */ ); +/** @brief Iterate through all subresources of a resource. + + @note The XID argument provided to the FindAllRes function + may be 0 for subresources that don't have an XID */ +extern _X_EXPORT void FindSubResources(pointer /*resource*/, + RESTYPE /*type*/, + FindAllRes /*func*/, + pointer /*cdata*/); + extern _X_EXPORT void FreeClientNeverRetainResources(ClientPtr /*client */ ); extern _X_EXPORT void FreeClientResources(ClientPtr /*client */ ); @@ -231,4 +274,17 @@ extern _X_EXPORT unsigned int GetXIDList(ClientPtr /*client */ , extern _X_EXPORT RESTYPE lastResourceType; extern _X_EXPORT RESTYPE TypeMask; -#endif /* RESOURCE_H */ +/** @brief A hashing function to be used for hashing resource IDs + + @param id The resource ID to hash + @param numBits The number of bits in the resulting hash. Must be >=0. + + @note This function is really only for handling + INITHASHSIZE..MAXHASHSIZE bit hashes, but will handle any number + of bits by either masking numBits lower bits of the ID or by + providing at most MAXHASHSIZE hashes. +*/ +extern _X_EXPORT int HashResourceID(XID id, + int numBits); + +#endif /* RESOURCE_H */ diff --git a/xorg-server/render/picture.c b/xorg-server/render/picture.c index 2fd13fc37..da3e49936 100644 --- a/xorg-server/render/picture.c +++ b/xorg-server/render/picture.c @@ -591,6 +591,29 @@ PictureParseCmapPolicy(const char *name) return PictureCmapPolicyInvalid; } +/** @see GetDefaultBytes */ +static void +GetPictureBytes(pointer value, XID id, ResourceSizePtr size) +{ + PicturePtr picture = value; + + /* Currently only pixmap bytes are reported to clients. */ + size->resourceSize = 0; + + size->refCnt = picture->refcnt; + + /* Calculate pixmap reference sizes. */ + size->pixmapRefSize = 0; + if (picture->pDrawable && (picture->pDrawable->type == DRAWABLE_PIXMAP)) + { + SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); + ResourceSizeRec pixmapSize = { 0, 0, 0 }; + PixmapPtr pixmap = (PixmapPtr)picture->pDrawable; + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } +} + Bool PictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats) { @@ -602,6 +625,7 @@ PictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats) PictureType = CreateNewResourceType(FreePicture, "PICTURE"); if (!PictureType) return FALSE; + SetResourceTypeSizeFunc(PictureType, GetPictureBytes); PictFormatType = CreateNewResourceType(FreePictFormat, "PICTFORMAT"); if (!PictFormatType) return FALSE; diff --git a/xorg-server/test/Makefile.am b/xorg-server/test/Makefile.am index eb6147021..8c7e412c3 100644 --- a/xorg-server/test/Makefile.am +++ b/xorg-server/test/Makefile.am @@ -5,7 +5,7 @@ if XORG # Tests that require at least some DDX functions in order to fully link # For now, requires xf86 ddx, could be adjusted to use another SUBDIRS += xi2 -noinst_PROGRAMS += xkb input xtest misc fixes xfree86 +noinst_PROGRAMS += xkb input xtest misc fixes xfree86 hashtabletest endif check_LTLIBRARIES = libxservertest.la @@ -36,6 +36,7 @@ misc_LDADD=$(TEST_LDADD) fixes_LDADD=$(TEST_LDADD) xfree86_LDADD=$(TEST_LDADD) touch_LDADD=$(TEST_LDADD) +hashtabletest_LDADD=$(TEST_LDADD) ../Xext/hashtable.c libxservertest_la_LIBADD = $(XSERVER_LIBS) if XORG diff --git a/xorg-server/test/hashtabletest.c b/xorg-server/test/hashtabletest.c new file mode 100644 index 000000000..64c7091fc --- /dev/null +++ b/xorg-server/test/hashtabletest.c @@ -0,0 +1,162 @@ +#include <misc.h> +#include <stdlib.h> +#include <stdio.h> +#include "hashtable.h" +#include "resource.h" + +static void +print_xid(void* ptr, void* v) +{ + XID *x = v; + printf("%ld", *x); +} + +static void +print_int(void* ptr, void* v) +{ + int *x = v; + printf("%d", *x); +} + +static int +test1(void) +{ + HashTable h; + XID id; + int c; + int ok = 1; + const int numKeys = 420; + + printf("test1\n"); + h = ht_create(sizeof(XID), sizeof(int), ht_resourceid_hash, ht_resourceid_compare, NULL); + + for (c = 0; c < numKeys; ++c) { + int *dest; + id = c; + dest = ht_add(h, &id); + if (dest) { + *dest = 2 * c; + } + } + + printf("Distribution after insertion\n"); + ht_dump_distribution(h); + ht_dump_contents(h, print_xid, print_int, NULL); + + for (c = 0; c < numKeys; ++c) { + XID id = c; + int* v = ht_find(h, &id); + if (v) { + if (*v == 2 * c) { + // ok + } else { + printf("Key %d doesn't have expected value %d but has %d instead\n", + c, 2 * c, *v); + ok = 0; + } + } else { + ok = 0; + printf("Cannot find key %d\n", c); + } + } + + if (ok) { + printf("%d keys inserted and found\n", c); + + for (c = 0; c < numKeys; ++c) { + XID id = c; + ht_remove(h, &id); + } + + printf("Distribution after deletion\n"); + ht_dump_distribution(h); + } + + ht_destroy(h); + + return ok; +} + +static int +test2(void) +{ + HashTable h; + XID id; + int c; + int ok = 1; + const int numKeys = 420; + + printf("test2\n"); + h = ht_create(sizeof(XID), 0, ht_resourceid_hash, ht_resourceid_compare, NULL); + + for (c = 0; c < numKeys; ++c) { + id = c; + ht_add(h, &id); + } + + for (c = 0; c < numKeys; ++c) { + XID id = c; + if (!ht_find(h, &id)) { + ok = 0; + printf("Cannot find key %d\n", c); + } + } + + { + XID id = c + 1; + if (ht_find(h, &id)) { + ok = 0; + printf("Could find a key that shouldn't be there\n"); + } + } + + ht_destroy(h); + + if (ok) { + printf("Test with empty keys OK\n"); + } else { + printf("Test with empty keys FAILED\n"); + } + + return ok; +} + +static int +test3(void) +{ + int ok = 1; + HtGenericHashSetupRec hashSetup = { + .keySize = 4 + }; + HashTable h; + printf("test3\n"); + h = ht_create(4, 0, ht_generic_hash, ht_generic_compare, &hashSetup); + + if (!ht_add(h, "helo") || + !ht_add(h, "wrld")) { + printf("Could not insert keys\n"); + } + + if (!ht_find(h, "helo") || + !ht_find(h, "wrld")) { + ok = 0; + printf("Could not find inserted keys\n"); + } + + printf("Hash distribution with two strings\n"); + ht_dump_distribution(h); + + ht_destroy(h); + + return ok; +} + +int +main(void) +{ + int ok = test1(); + ok = ok && test2(); + ok = ok && test3(); + + return ok ? 0 : 1; +} diff --git a/xorg-server/xkeyboard-config/ABOUT-NLS b/xorg-server/xkeyboard-config/ABOUT-NLS deleted file mode 100644 index 2f50c6693..000000000 --- a/xorg-server/xkeyboard-config/ABOUT-NLS +++ /dev/null @@ -1,768 +0,0 @@ -Notes on the Free Translation Project -************************************* - -Free software is going international! The Free Translation Project is -a way to get maintainers of free software, translators, and users all -together, so that will gradually become able to speak many languages. -A few packages already provide translations for their messages. - - If you found this `ABOUT-NLS' file inside a distribution, you may -assume that the distributed package does use GNU `gettext' internally, -itself available at your nearest GNU archive site. But you do _not_ -need to install GNU `gettext' prior to configuring, installing or using -this package with messages translated. - - Installers will find here some useful hints. These notes also -explain how users should proceed for getting the programs to use the -available translations. They tell how people wanting to contribute and -work at translations should contact the appropriate team. - - When reporting bugs in the `intl/' directory or bugs which may be -related to internationalization, you should tell about the version of -`gettext' which is used. The information can be found in the -`intl/VERSION' file, in internationalized packages. - -Quick configuration advice -========================== - -If you want to exploit the full power of internationalization, you -should configure it using - - ./configure --with-included-gettext - -to force usage of internationalizing routines provided within this -package, despite the existence of internationalizing capabilities in the -operating system where this package is being installed. So far, only -the `gettext' implementation in the GNU C library version 2 provides as -many features (such as locale alias, message inheritance, automatic -charset conversion or plural form handling) as the implementation here. -It is also not possible to offer this additional functionality on top -of a `catgets' implementation. Future versions of GNU `gettext' will -very likely convey even more functionality. So it might be a good idea -to change to GNU `gettext' as soon as possible. - - So you need _not_ provide this option if you are using GNU libc 2 or -you have installed a recent copy of the GNU gettext package with the -included `libintl'. - -INSTALL Matters -=============== - -Some packages are "localizable" when properly installed; the programs -they contain can be made to speak your own native language. Most such -packages use GNU `gettext'. Other packages have their own ways to -internationalization, predating GNU `gettext'. - - By default, this package will be installed to allow translation of -messages. It will automatically detect whether the system already -provides the GNU `gettext' functions. If not, the GNU `gettext' own -library will be used. This library is wholly contained within this -package, usually in the `intl/' subdirectory, so prior installation of -the GNU `gettext' package is _not_ required. Installers may use -special options at configuration time for changing the default -behaviour. The commands: - - ./configure --with-included-gettext - ./configure --disable-nls - -will respectively bypass any pre-existing `gettext' to use the -internationalizing routines provided within this package, or else, -_totally_ disable translation of messages. - - When you already have GNU `gettext' installed on your system and run -configure without an option for your new package, `configure' will -probably detect the previously built and installed `libintl.a' file and -will decide to use this. This might be not what is desirable. You -should use the more recent version of the GNU `gettext' library. I.e. -if the file `intl/VERSION' shows that the library which comes with this -package is more recent, you should use - - ./configure --with-included-gettext - -to prevent auto-detection. - - The configuration process will not test for the `catgets' function -and therefore it will not be used. The reason is that even an -emulation of `gettext' on top of `catgets' could not provide all the -extensions of the GNU `gettext' library. - - Internationalized packages have usually many `po/LL.po' files, where -LL gives an ISO 639 two-letter code identifying the language. Unless -translations have been forbidden at `configure' time by using the -`--disable-nls' switch, all available translations are installed -together with the package. However, the environment variable `LINGUAS' -may be set, prior to configuration, to limit the installed set. -`LINGUAS' should then contain a space separated list of two-letter -codes, stating which languages are allowed. - -Using This Package -================== - -As a user, if your language has been installed for this package, you -only have to set the `LANG' environment variable to the appropriate -`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code, -and `CC' is an ISO 3166 two-letter country code. For example, let's -suppose that you speak German and live in Germany. At the shell -prompt, merely execute `setenv LANG de_DE' (in `csh'), -`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash'). -This can be done from your `.login' or `.profile' file, once and for -all. - - You might think that the country code specification is redundant. -But in fact, some languages have dialects in different countries. For -example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The -country code serves to distinguish the dialects. - - The locale naming convention of `LL_CC', with `LL' denoting the -language and `CC' denoting the country, is the one use on systems based -on GNU libc. On other systems, some variations of this scheme are -used, such as `LL' or `LL_CC.ENCODING'. You can get the list of -locales supported by your system for your country by running the command -`locale -a | grep '^LL''. - - Not all programs have translations for all languages. By default, an -English message is shown in place of a nonexistent translation. If you -understand other languages, you can set up a priority list of languages. -This is done through a different environment variable, called -`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG' -for the purpose of message handling, but you still need to have `LANG' -set to the primary language; this is required by other parts of the -system libraries. For example, some Swedish users who would rather -read translations in German than English for when Swedish is not -available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'. - - Special advice for Norwegian users: The language code for Norwegian -bokma*l changed from `no' to `nb' recently (in 2003). During the -transition period, while some message catalogs for this language are -installed under `nb' and some older ones under `no', it's recommended -for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and -older translations are used. - - In the `LANGUAGE' environment variable, but not in the `LANG' -environment variable, `LL_CC' combinations can be abbreviated as `LL' -to denote the language's main dialect. For example, `de' is equivalent -to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT' -(Portuguese as spoken in Portugal) in this context. - -Translating Teams -================= - -For the Free Translation Project to be a success, we need interested -people who like their own language and write it well, and who are also -able to synergize with other translators speaking the same language. -Each translation team has its own mailing list. The up-to-date list of -teams can be found at the Free Translation Project's homepage, -`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams" -area. - - If you'd like to volunteer to _work_ at translating messages, you -should become a member of the translating team for your own language. -The subscribing address is _not_ the same as the list itself, it has -`-request' appended. For example, speakers of Swedish can send a -message to `sv-request@li.org', having this message body: - - subscribe - - Keep in mind that team members are expected to participate -_actively_ in translations, or at solving translational difficulties, -rather than merely lurking around. If your team does not exist yet and -you want to start one, or if you are unsure about what to do or how to -get started, please write to `translation@iro.umontreal.ca' to reach the -coordinator for all translator teams. - - The English team is special. It works at improving and uniformizing -the terminology in use. Proven linguistic skill are praised more than -programming skill, here. - -Available Packages -================== - -Languages are not equally supported in all packages. The following -matrix shows the current state of internationalization, as of January -2004. The matrix shows, in regard of each package, for which languages -PO files have been submitted to translation coordination, with a -translation percentage of at least 50%. - - Ready PO files af am ar az be bg bs ca cs da de el en en_GB eo es - +----------------------------------------------------+ - a2ps | [] [] [] [] | - aegis | () | - ant-phone | () | - anubis | | - ap-utils | | - aspell | [] | - bash | [] [] [] [] | - batchelor | | - bfd | [] [] | - binutils | [] [] | - bison | [] [] [] | - bluez-pin | [] [] [] | - clisp | | - clisp | [] [] [] | - console-tools | [] [] | - coreutils | [] [] [] [] | - cpio | [] [] [] | - darkstat | [] () [] | - diffutils | [] [] [] [] [] [] [] | - e2fsprogs | [] [] [] | - enscript | [] [] [] [] | - error | [] [] [] [] [] | - fetchmail | [] () [] [] [] [] | - fileutils | [] [] [] | - findutils | [] [] [] [] [] [] [] | - flex | [] [] [] [] | - fslint | | - gas | [] | - gawk | [] [] [] [] | - gbiff | [] | - gcal | [] | - gcc | [] [] | - gettext | [] [] [] [] [] | - gettext-examples | [] [] [] [] | - gettext-runtime | [] [] [] [] [] | - gettext-tools | [] [] [] | - gimp-print | [] [] [] [] [] | - gliv | | - glunarclock | [] [] | - gnubiff | [] | - gnucash | [] () [] [] | - gnucash-glossary | [] () [] | - gnupg | [] () [] [] [] [] | - gpe-aerial | [] | - gpe-beam | [] [] | - gpe-calendar | [] [] | - gpe-clock | [] [] | - gpe-conf | [] [] | - gpe-contacts | [] [] | - gpe-edit | [] | - gpe-go | [] | - gpe-login | [] [] | - gpe-ownerinfo | [] [] | - gpe-sketchbook | [] [] | - gpe-su | [] [] | - gpe-taskmanager | [] [] | - gpe-timesheet | [] | - gpe-today | [] [] | - gpe-todo | [] [] | - gphoto2 | [] [] [] [] | - gprof | [] [] [] | - gpsdrive | () () () | - gramadoir | [] | - grep | [] [] [] [] [] [] | - gretl | [] | - gtick | [] () | - hello | [] [] [] [] [] [] | - id-utils | [] [] | - indent | [] [] [] [] | - iso_3166 | [] [] [] [] [] [] [] [] [] [] | - iso_3166_1 | [] [] [] [] [] [] | - iso_3166_2 | | - iso_3166_3 | [] | - iso_4217 | [] [] [] [] | - iso_639 | | - jpilot | [] [] [] | - jtag | | - jwhois | [] | - kbd | [] [] [] [] [] | - latrine | () | - ld | [] [] | - libc | [] [] [] [] [] [] | - libgpewidget | [] [] | - libiconv | [] [] [] [] [] | - lifelines | [] () | - lilypond | [] | - lingoteach | | - lingoteach_lessons | () () | - lynx | [] [] [] [] | - m4 | [] [] [] [] | - mailutils | [] [] | - make | [] [] [] | - man-db | [] () [] [] () | - minicom | [] [] [] | - mysecretdiary | [] [] [] | - nano | [] () [] [] [] | - nano_1_0 | [] () [] [] [] | - opcodes | [] | - parted | [] [] [] [] [] | - ptx | [] [] [] [] [] | - python | | - radius | [] | - recode | [] [] [] [] [] [] [] | - rpm | [] [] | - screem | | - scrollkeeper | [] [] [] [] [] [] | - sed | [] [] [] [] [] [] | - sh-utils | [] [] [] | - shared-mime-info | | - sharutils | [] [] [] [] [] [] | - silky | () | - skencil | [] () [] | - sketch | [] () [] | - soundtracker | [] [] [] | - sp | [] | - tar | [] [] [] [] | - texinfo | [] [] [] | - textutils | [] [] [] [] | - tin | () () | - tp-robot | | - tuxpaint | [] [] [] [] [] [] [] | - unicode-han-tra... | | - unicode-transla... | | - util-linux | [] [] [] [] [] | - vorbis-tools | [] [] [] [] | - wastesedge | () | - wdiff | [] [] [] [] | - wget | [] [] [] [] [] [] | - xchat | [] [] [] [] | - xfree86_xkb_xml | [] [] | - xpad | [] | - +----------------------------------------------------+ - af am ar az be bg bs ca cs da de el en en_GB eo es - 4 0 0 1 9 4 1 40 41 60 78 17 1 5 13 68 - - et eu fa fi fr ga gl he hr hu id is it ja ko lg - +-------------------------------------------------+ - a2ps | [] [] [] () () | - aegis | | - ant-phone | [] | - anubis | [] | - ap-utils | [] | - aspell | [] [] | - bash | [] [] | - batchelor | [] [] | - bfd | [] | - binutils | [] [] | - bison | [] [] [] [] | - bluez-pin | [] [] [] [] [] | - clisp | | - clisp | [] | - console-tools | | - coreutils | [] [] [] [] [] [] | - cpio | [] [] [] [] | - darkstat | () [] [] [] | - diffutils | [] [] [] [] [] [] [] | - e2fsprogs | | - enscript | [] [] | - error | [] [] [] [] | - fetchmail | [] | - fileutils | [] [] [] [] [] [] | - findutils | [] [] [] [] [] [] [] [] [] [] [] | - flex | [] [] [] | - fslint | [] | - gas | [] | - gawk | [] [] [] | - gbiff | [] | - gcal | [] | - gcc | [] | - gettext | [] [] [] | - gettext-examples | [] [] | - gettext-runtime | [] [] [] [] [] | - gettext-tools | [] [] [] | - gimp-print | [] [] | - gliv | () | - glunarclock | [] [] [] [] | - gnubiff | [] | - gnucash | () [] | - gnucash-glossary | [] | - gnupg | [] [] [] [] [] [] [] | - gpe-aerial | [] | - gpe-beam | [] | - gpe-calendar | [] [] [] | - gpe-clock | [] | - gpe-conf | [] | - gpe-contacts | [] [] | - gpe-edit | [] [] | - gpe-go | [] | - gpe-login | [] [] | - gpe-ownerinfo | [] [] [] | - gpe-sketchbook | [] | - gpe-su | [] | - gpe-taskmanager | [] | - gpe-timesheet | [] [] [] | - gpe-today | [] [] | - gpe-todo | [] [] | - gphoto2 | [] [] [] | - gprof | [] [] | - gpsdrive | () () () | - gramadoir | [] [] | - grep | [] [] [] [] [] [] [] [] [] [] [] | - gretl | [] [] | - gtick | [] [] [] | - hello | [] [] [] [] [] [] [] [] [] [] [] [] [] | - id-utils | [] [] [] [] | - indent | [] [] [] [] [] [] [] [] [] | - iso_3166 | [] [] [] [] [] [] [] | - iso_3166_1 | [] [] [] [] [] | - iso_3166_2 | | - iso_3166_3 | | - iso_4217 | [] [] [] [] [] [] | - iso_639 | | - jpilot | [] () | - jtag | [] | - jwhois | [] [] [] [] | - kbd | [] | - latrine | [] | - ld | [] | - libc | [] [] [] [] [] [] | - libgpewidget | [] [] [] [] | - libiconv | [] [] [] [] [] [] [] [] [] | - lifelines | () | - lilypond | [] | - lingoteach | [] [] | - lingoteach_lessons | | - lynx | [] [] [] [] | - m4 | [] [] [] [] | - mailutils | | - make | [] [] [] [] [] [] | - man-db | () () | - minicom | [] [] [] [] | - mysecretdiary | [] [] | - nano | [] [] [] [] | - nano_1_0 | [] [] [] [] | - opcodes | [] | - parted | [] [] [] | - ptx | [] [] [] [] [] [] [] | - python | | - radius | [] | - recode | [] [] [] [] [] [] | - rpm | [] [] | - screem | | - scrollkeeper | [] | - sed | [] [] [] [] [] [] [] [] [] | - sh-utils | [] [] [] [] [] [] [] | - shared-mime-info | [] [] [] | - sharutils | [] [] [] [] [] | - silky | () [] () () | - skencil | [] | - sketch | [] | - soundtracker | [] [] | - sp | [] () | - tar | [] [] [] [] [] [] [] [] [] | - texinfo | [] [] [] [] | - textutils | [] [] [] [] [] [] | - tin | [] () | - tp-robot | [] | - tuxpaint | [] [] [] [] [] [] [] [] [] | - unicode-han-tra... | | - unicode-transla... | [] [] | - util-linux | [] [] [] [] () [] | - vorbis-tools | [] | - wastesedge | () | - wdiff | [] [] [] [] [] [] | - wget | [] [] [] [] [] [] [] | - xchat | [] [] [] | - xfree86_xkb_xml | [] [] | - xpad | [] [] | - +-------------------------------------------------+ - et eu fa fi fr ga gl he hr hu id is it ja ko lg - 22 2 1 26 106 28 24 8 10 41 33 1 26 33 12 0 - - lt lv mk mn ms mt nb nl nn no nso pl pt pt_BR ro ru - +-----------------------------------------------------+ - a2ps | [] [] () () [] [] [] | - aegis | () () () | - ant-phone | [] [] | - anubis | [] [] [] [] [] [] | - ap-utils | [] () [] | - aspell | [] | - bash | [] [] [] | - batchelor | [] | - bfd | [] | - binutils | [] | - bison | [] [] [] [] [] | - bluez-pin | [] [] [] | - clisp | | - clisp | [] | - console-tools | [] | - coreutils | [] [] | - cpio | [] [] [] [] [] | - darkstat | [] [] [] [] | - diffutils | [] [] [] [] [] [] | - e2fsprogs | [] | - enscript | [] [] [] [] | - error | [] [] [] | - fetchmail | [] [] () [] | - fileutils | [] [] [] | - findutils | [] [] [] [] [] | - flex | [] [] [] [] | - fslint | [] [] | - gas | | - gawk | [] [] [] | - gbiff | [] [] | - gcal | | - gcc | | - gettext | [] [] [] | - gettext-examples | [] [] [] | - gettext-runtime | [] [] [] [] | - gettext-tools | [] [] | - gimp-print | [] | - gliv | [] [] [] | - glunarclock | [] [] [] [] | - gnubiff | [] | - gnucash | [] [] () [] | - gnucash-glossary | [] [] | - gnupg | [] | - gpe-aerial | [] [] [] [] | - gpe-beam | [] [] [] [] | - gpe-calendar | [] [] [] [] | - gpe-clock | [] [] [] [] | - gpe-conf | [] [] [] [] | - gpe-contacts | [] [] [] [] | - gpe-edit | [] [] [] [] | - gpe-go | [] [] [] | - gpe-login | [] [] [] [] | - gpe-ownerinfo | [] [] [] [] | - gpe-sketchbook | [] [] [] [] | - gpe-su | [] [] [] [] | - gpe-taskmanager | [] [] [] [] | - gpe-timesheet | [] [] [] [] | - gpe-today | [] [] [] [] | - gpe-todo | [] [] [] [] | - gphoto2 | [] | - gprof | [] [] | - gpsdrive | () () [] | - gramadoir | () [] | - grep | [] [] [] [] [] | - gretl | | - gtick | [] [] [] | - hello | [] [] [] [] [] [] [] [] [] [] | - id-utils | [] [] [] [] | - indent | [] [] [] [] | - iso_3166 | [] [] [] | - iso_3166_1 | [] [] | - iso_3166_2 | | - iso_3166_3 | [] | - iso_4217 | [] [] [] [] [] [] [] [] | - iso_639 | [] | - jpilot | () () | - jtag | | - jwhois | [] [] [] [] () | - kbd | [] [] [] | - latrine | [] | - ld | | - libc | [] [] [] [] | - libgpewidget | [] [] [] | - libiconv | [] [] [] [] [] | - lifelines | | - lilypond | | - lingoteach | | - lingoteach_lessons | | - lynx | [] [] [] | - m4 | [] [] [] [] [] | - mailutils | [] [] [] | - make | [] [] [] [] | - man-db | [] | - minicom | [] [] [] [] | - mysecretdiary | [] [] [] | - nano | [] [] [] [] [] | - nano_1_0 | [] [] [] [] [] [] | - opcodes | [] [] | - parted | [] [] [] [] | - ptx | [] [] [] [] [] [] [] [] | - python | | - radius | [] [] | - recode | [] [] [] [] | - rpm | [] [] [] | - screem | | - scrollkeeper | [] [] [] [] [] | - sed | [] [] [] | - sh-utils | [] [] | - shared-mime-info | [] [] | - sharutils | [] [] | - silky | () | - skencil | [] [] | - sketch | [] [] | - soundtracker | | - sp | | - tar | [] [] [] [] [] [] | - texinfo | [] [] [] [] | - textutils | [] [] | - tin | | - tp-robot | [] | - tuxpaint | [] [] [] [] [] [] [] [] | - unicode-han-tra... | | - unicode-transla... | | - util-linux | [] [] [] | - vorbis-tools | [] [] [] | - wastesedge | | - wdiff | [] [] [] [] [] | - wget | [] [] [] | - xchat | [] [] [] | - xfree86_xkb_xml | [] [] | - xpad | [] [] | - +-----------------------------------------------------+ - lt lv mk mn ms mt nb nl nn no nso pl pt pt_BR ro ru - 1 2 0 3 12 0 10 69 6 7 1 40 26 36 76 63 - - sk sl sr sv ta th tr uk ven vi wa xh zh_CN zh_TW zu - +-----------------------------------------------------+ - a2ps | [] [] [] [] | 16 - aegis | | 0 - ant-phone | | 3 - anubis | [] [] | 9 - ap-utils | () | 3 - aspell | | 4 - bash | | 9 - batchelor | | 3 - bfd | [] [] | 6 - binutils | [] [] [] | 8 - bison | [] [] | 14 - bluez-pin | [] [] [] | 14 - clisp | | 0 - clisp | | 5 - console-tools | | 3 - coreutils | [] [] [] [] | 16 - cpio | [] [] | 14 - darkstat | [] [] [] () () | 12 - diffutils | [] [] [] | 23 - e2fsprogs | [] [] | 6 - enscript | [] [] | 12 - error | [] [] [] | 15 - fetchmail | [] [] | 11 - fileutils | [] [] [] [] [] | 17 - findutils | [] [] [] [] [] [] | 29 - flex | [] [] | 13 - fslint | | 3 - gas | [] | 3 - gawk | [] [] | 12 - gbiff | | 4 - gcal | [] [] | 4 - gcc | [] | 4 - gettext | [] [] [] [] [] | 16 - gettext-examples | [] [] [] [] [] | 14 - gettext-runtime | [] [] [] [] [] [] [] [] | 22 - gettext-tools | [] [] [] [] [] [] | 14 - gimp-print | [] [] | 10 - gliv | | 3 - glunarclock | [] [] [] | 13 - gnubiff | | 3 - gnucash | [] [] | 9 - gnucash-glossary | [] [] [] | 8 - gnupg | [] [] [] [] | 17 - gpe-aerial | [] | 7 - gpe-beam | [] | 8 - gpe-calendar | [] [] [] [] | 13 - gpe-clock | [] [] [] | 10 - gpe-conf | [] [] | 9 - gpe-contacts | [] [] [] | 11 - gpe-edit | [] [] [] [] [] | 12 - gpe-go | | 5 - gpe-login | [] [] [] [] [] | 13 - gpe-ownerinfo | [] [] [] [] | 13 - gpe-sketchbook | [] [] | 9 - gpe-su | [] [] [] | 10 - gpe-taskmanager | [] [] [] | 10 - gpe-timesheet | [] [] [] [] | 12 - gpe-today | [] [] [] [] [] | 13 - gpe-todo | [] [] [] [] | 12 - gphoto2 | [] [] [] | 11 - gprof | [] [] | 9 - gpsdrive | [] [] | 3 - gramadoir | [] | 5 - grep | [] [] [] [] | 26 - gretl | | 3 - gtick | | 7 - hello | [] [] [] [] [] | 34 - id-utils | [] [] | 12 - indent | [] [] [] [] | 21 - iso_3166 | [] [] [] [] [] [] [] | 27 - iso_3166_1 | [] [] [] | 16 - iso_3166_2 | | 0 - iso_3166_3 | | 2 - iso_4217 | [] [] [] [] [] [] | 24 - iso_639 | | 1 - jpilot | [] [] [] [] [] | 9 - jtag | [] | 2 - jwhois | () [] [] | 11 - kbd | [] [] | 11 - latrine | | 2 - ld | [] [] | 5 - libc | [] [] [] [] | 20 - libgpewidget | [] [] [] [] | 13 - libiconv | [] [] [] [] [] [] [] [] | 27 - lifelines | [] | 2 - lilypond | [] | 3 - lingoteach | | 2 - lingoteach_lessons | () | 0 - lynx | [] [] [] | 14 - m4 | [] [] | 15 - mailutils | | 5 - make | [] [] [] | 16 - man-db | [] | 5 - minicom | | 11 - mysecretdiary | [] [] | 10 - nano | [] [] [] [] | 17 - nano_1_0 | [] [] [] | 17 - opcodes | [] [] | 6 - parted | [] [] [] | 15 - ptx | [] [] | 22 - python | | 0 - radius | | 4 - recode | [] [] [] | 20 - rpm | [] [] | 9 - screem | [] [] | 2 - scrollkeeper | [] [] [] | 15 - sed | [] [] [] [] [] [] | 24 - sh-utils | [] [] | 14 - shared-mime-info | [] [] | 7 - sharutils | [] [] [] [] | 17 - silky | () | 3 - skencil | [] | 6 - sketch | [] | 6 - soundtracker | [] [] | 7 - sp | [] | 3 - tar | [] [] [] [] [] | 24 - texinfo | [] [] [] | 14 - textutils | [] [] [] [] | 16 - tin | | 1 - tp-robot | | 2 - tuxpaint | [] [] [] [] [] | 29 - unicode-han-tra... | | 0 - unicode-transla... | | 2 - util-linux | [] [] | 15 - vorbis-tools | | 8 - wastesedge | | 0 - wdiff | [] [] [] | 18 - wget | [] [] [] [] [] [] [] [] | 24 - xchat | [] [] [] [] [] | 15 - xfree86_xkb_xml | [] [] [] [] [] | 11 - xpad | | 5 - +-----------------------------------------------------+ - 63 teams sk sl sr sv ta th tr uk ven vi wa xh zh_CN zh_TW zu - 131 domains 47 19 28 83 0 0 59 13 1 1 11 0 22 22 0 1373 - - Some counters in the preceding matrix are higher than the number of -visible blocks let us expect. This is because a few extra PO files are -used for implementing regional variants of languages, or language -dialects. - - For a PO file in the matrix above to be effective, the package to -which it applies should also have been internationalized and -distributed as such by its maintainer. There might be an observable -lag between the mere existence a PO file and its wide availability in a -distribution. - - If January 2004 seems to be old, you may fetch a more recent copy of -this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date -matrix with full percentage details can be found at -`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'. - -Using `gettext' in new packages -=============================== - -If you are writing a freely available program and want to -internationalize it you are welcome to use GNU `gettext' in your -package. Of course you have to respect the GNU Library General Public -License which covers the use of the GNU `gettext' library. This means -in particular that even non-free programs can use `libintl' as a shared -library, whereas only free software can use `libintl' as a static -library or use modified versions of `libintl'. - - Once the sources are changed appropriately and the setup can handle -the use of `gettext' the only thing missing are the translations. The -Free Translation Project is also available for packages which are not -developed inside the GNU project. Therefore the information given above -applies also for every other Free Software Project. Contact -`translation@iro.umontreal.ca' to make the `.pot' files available to -the translation teams. - diff --git a/xorg-server/xkeyboard-config/autogen.sh b/xorg-server/xkeyboard-config/autogen.sh index f9cd42b58..f9c238482 100644 --- a/xorg-server/xkeyboard-config/autogen.sh +++ b/xorg-server/xkeyboard-config/autogen.sh @@ -6,9 +6,8 @@ test -z "$srcdir" && srcdir=. ORIGDIR=`pwd` cd $srcdir -intltoolize +autopoint --force +AUTOPOINT='intltoolize --automake --copy' autoreconf -v --install --force || exit 1 -autoreconf -v --install || exit 1 cd $ORIGDIR || exit $? - $srcdir/configure --enable-maintainer-mode "$@" diff --git a/xorg-server/xkeyboard-config/config.rpath b/xorg-server/xkeyboard-config/config.rpath deleted file mode 100644 index e69de29bb..000000000 --- a/xorg-server/xkeyboard-config/config.rpath +++ /dev/null diff --git a/xorg-server/xkeyboard-config/configure.in b/xorg-server/xkeyboard-config/configure.in index 3b9fac2e0..6748cad68 100644 --- a/xorg-server/xkeyboard-config/configure.in +++ b/xorg-server/xkeyboard-config/configure.in @@ -70,12 +70,13 @@ AM_CONDITIONAL(USE_COMPAT_RULES, test "x$enable_compat_rules" = "xyes") # **** AC_PROG_INTLTOOL(0.30) +AM_GNU_GETTEXT_VERSION([0.18.1]) +AM_GNU_GETTEXT([external]) + GETTEXT_PACKAGE=xkeyboard-config AC_SUBST(GETTEXT_PACKAGE) AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [Gettext package]) -AM_GLIB_GNU_GETTEXT - ALL_LINGUAS="af az bg ca crh cs da de el en_GB eo es fi fr gl hu id it ja ka ko ky lt nb nl pl ro ru rw sk sl sq sr sv tr uk vi zh_CN zh_TW" AC_SUBST(xkb_base) diff --git a/xorg-server/xorg-server.pc.in b/xorg-server/xorg-server.pc.in index a98eca8f9..1de1c6c50 100644 --- a/xorg-server/xorg-server.pc.in +++ b/xorg-server/xorg-server.pc.in @@ -17,4 +17,4 @@ Description: Modular X.Org X Server Version: @PACKAGE_VERSION@ Requires.private: @SDK_REQUIRED_MODULES@ Cflags: -I${sdkdir} @symbol_visibility@ -Libs: -L${libdir} +Libs: -L${libdir} @XORG_DRIVER_LIBS@ |