aboutsummaryrefslogtreecommitdiff
path: root/libX11
diff options
context:
space:
mode:
Diffstat (limited to 'libX11')
-rw-r--r--libX11/src/XlibInt.c4300
-rw-r--r--libX11/src/xkb/XKB.c1544
-rw-r--r--libX11/src/xkb/XKBList.c496
-rw-r--r--libX11/src/xkb/XKBMisc.c1958
4 files changed, 4150 insertions, 4148 deletions
diff --git a/libX11/src/XlibInt.c b/libX11/src/XlibInt.c
index c0442afd4..498cf16be 100644
--- a/libX11/src/XlibInt.c
+++ b/libX11/src/XlibInt.c
@@ -1,2150 +1,2150 @@
-/*
-
-Copyright 1985, 1986, 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-/*
- * XlibInt.c - Internal support routines for the C subroutine
- * interface library (Xlib) to the X Window System Protocol V11.0.
- */
-
-#ifdef WIN32
-#define _XLIBINT_
-#include <X11\Xw32defs.h>
-#endif
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "Xlibint.h"
-#include "Xprivate.h"
-#include <X11/Xpoll.h>
-#include <assert.h>
-#include <stdio.h>
-#ifdef WIN32
-#include <direct.h>
-#endif
-
-#ifdef XTHREADS
-#include "locking.h"
-
-/* these pointers get initialized by XInitThreads */
-LockInfoPtr _Xglobal_lock = NULL;
-void (*_XCreateMutex_fn)(LockInfoPtr) = NULL;
-/* struct _XCVList *(*_XCreateCVL_fn)() = NULL; */
-void (*_XFreeMutex_fn)(LockInfoPtr) = NULL;
-void (*_XLockMutex_fn)(
- LockInfoPtr /* lock */
-#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
- , char * /* file */
- , int /* line */
-#endif
- ) = NULL;
-void (*_XUnlockMutex_fn)(
- LockInfoPtr /* lock */
-#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
- , char * /* file */
- , int /* line */
-#endif
- ) = NULL;
-xthread_t (*_Xthread_self_fn)(void) = NULL;
-
-#define XThread_Self() ((*_Xthread_self_fn)())
-
-#endif /* XTHREADS */
-
-/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
- * systems are broken and return EWOULDBLOCK when they should return EAGAIN
- */
-#ifdef WIN32
-#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK)
-#else
-#ifdef __CYGWIN__ /* Cygwin uses ENOBUFS to signal socket is full */
-#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
-#else
-#if defined(EAGAIN) && defined(EWOULDBLOCK)
-#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK)
-#else
-#ifdef EAGAIN
-#define ETEST() (errno == EAGAIN)
-#else
-#define ETEST() (errno == EWOULDBLOCK)
-#endif /* EAGAIN */
-#endif /* EAGAIN && EWOULDBLOCK */
-#endif /* __CYGWIN__ */
-#endif /* WIN32 */
-
-#ifdef WIN32
-#define ECHECK(err) (WSAGetLastError() == err)
-#define ESET(val) WSASetLastError(val)
-#else
-#ifdef __UNIXOS2__
-#define ECHECK(err) (errno == err)
-#define ESET(val)
-#else
-#define ECHECK(err) (errno == err)
-#define ESET(val) errno = val
-#endif
-#endif
-
-#if defined(LOCALCONN) || defined(LACHMAN)
-#ifdef EMSGSIZE
-#define ESZTEST() (ECHECK(EMSGSIZE) || ECHECK(ERANGE))
-#else
-#define ESZTEST() ECHECK(ERANGE)
-#endif
-#else
-#ifdef EMSGSIZE
-#define ESZTEST() ECHECK(EMSGSIZE)
-#endif
-#endif
-
-#ifdef __UNIXOS2__
-#include <limits.h>
-#define MAX_PATH _POSIX_PATH_MAX
-#endif
-
-/*
- * The following routines are internal routines used by Xlib for protocol
- * packet transmission and reception.
- *
- * _XIOError(Display *) will be called if any sort of system call error occurs.
- * This is assumed to be a fatal condition, i.e., XIOError should not return.
- *
- * _XError(Display *, xError *) will be called whenever an X_Error event is
- * received. This is not assumed to be a fatal condition, i.e., it is
- * acceptable for this procedure to return. However, XError should NOT
- * perform any operations (directly or indirectly) on the DISPLAY.
- *
- * Routines declared with a return type of 'Status' return 0 on failure,
- * and non 0 on success. Routines with no declared return type don't
- * return anything. Whenever possible routines that create objects return
- * the object they have created.
- */
-
-#define POLLFD_CACHE_SIZE 5
-
-/* initialize the struct array passed to poll() below */
-Bool _XPollfdCacheInit(
- Display *dpy)
-{
-#ifdef USE_POLL
- struct pollfd *pfp;
-
- pfp = (struct pollfd *)Xmalloc(POLLFD_CACHE_SIZE * sizeof(struct pollfd));
- if (!pfp)
- return False;
- pfp[0].fd = dpy->fd;
- pfp[0].events = POLLIN;
-
- dpy->filedes = (XPointer)pfp;
-#endif
- return True;
-}
-
-void _XPollfdCacheAdd(
- Display *dpy,
- int fd)
-{
-#ifdef USE_POLL
- struct pollfd *pfp = (struct pollfd *)dpy->filedes;
-
- if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) {
- pfp[dpy->im_fd_length].fd = fd;
- pfp[dpy->im_fd_length].events = POLLIN;
- }
-#endif
-}
-
-/* ARGSUSED */
-void _XPollfdCacheDel(
- Display *dpy,
- int fd) /* not used */
-{
-#ifdef USE_POLL
- struct pollfd *pfp = (struct pollfd *)dpy->filedes;
- struct _XConnectionInfo *conni;
-
- /* just recalculate whole list */
- if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) {
- int loc = 1;
- for (conni = dpy->im_fd_info; conni; conni=conni->next) {
- pfp[loc].fd = conni->fd;
- pfp[loc].events = POLLIN;
- loc++;
- }
- }
-#endif
-}
-
-#ifdef _MSC_VER
-#undef min
-#define min __min
-#endif
-
-static int sync_hazard(Display *dpy)
-{
- unsigned long span = dpy->request - dpy->last_request_read;
- unsigned long hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10);
- return span >= 65535 - hazard - 10;
-}
-
-static
-void sync_while_locked(Display *dpy)
-{
-#ifdef XTHREADS
- if (dpy->lock)
- (*dpy->lock->user_lock_display)(dpy);
-#endif
- UnlockDisplay(dpy);
- SyncHandle();
- InternalLockDisplay(dpy, /* don't skip user locks */ 0);
-#ifdef XTHREADS
- if (dpy->lock)
- (*dpy->lock->user_unlock_display)(dpy);
-#endif
-}
-
-void _XSeqSyncFunction(
- register Display *dpy)
-{
- xGetInputFocusReply rep;
- register xReq *req;
-
- if ((dpy->request - dpy->last_request_read) >= (65535 - BUFSIZE/SIZEOF(xReq))) {
- GetEmptyReq(GetInputFocus, req);
- (void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
- sync_while_locked(dpy);
- } else if (sync_hazard(dpy))
- _XSetPrivSyncFunction(dpy);
-}
-
-/* NOTE: only called if !XTHREADS, or when XInitThreads wasn't called. */
-static int
-_XPrivSyncFunction (Display *dpy)
-{
-#ifdef XTHREADS
- assert(!dpy->lock_fns);
-#endif
- assert(dpy->synchandler == _XPrivSyncFunction);
- assert((dpy->flags & XlibDisplayPrivSync) != 0);
- dpy->synchandler = dpy->savedsynchandler;
- dpy->savedsynchandler = NULL;
- dpy->flags &= ~XlibDisplayPrivSync;
- if(dpy->synchandler)
- dpy->synchandler(dpy);
- _XIDHandler(dpy);
- _XSeqSyncFunction(dpy);
- return 0;
-}
-
-void _XSetPrivSyncFunction(Display *dpy)
-{
-#ifdef XTHREADS
- if (dpy->lock_fns)
- return;
-#endif
- if (!(dpy->flags & XlibDisplayPrivSync)) {
- dpy->savedsynchandler = dpy->synchandler;
- dpy->synchandler = _XPrivSyncFunction;
- dpy->flags |= XlibDisplayPrivSync;
- }
-}
-
-void _XSetSeqSyncFunction(Display *dpy)
-{
- if (sync_hazard(dpy))
- _XSetPrivSyncFunction (dpy);
-}
-
-#ifdef LONG64
-void _XRead32(
- Display *dpy,
- register long *data,
- long len)
-{
- register int *buf;
- register long i;
-
- if (len) {
- (void) _XRead(dpy, (char *)data, len);
- i = len >> 2;
- buf = (int *)data + i;
- data += i;
- while (--i >= 0)
- *--data = *--buf;
- }
-}
-#endif /* LONG64 */
-
-#ifdef WORD64
-
-/*
- * XXX This is a *really* stupid way of doing this....
- * PACKBUFFERSIZE must be a multiple of 4.
- */
-
-#define PACKBUFFERSIZE 4096
-
-
-/*
- * _XRead32 - Read bytes from the socket unpacking each 32 bits
- * into a long (64 bits on a CRAY computer).
- *
- */
-static void _doXRead32(
- register Display *dpy,
- register long *data
- register long size,
- register char *packbuffer)
-{
- long *lpack,*lp;
- long mask32 = 0x00000000ffffffff;
- long maskw, nwords, i, bits;
-
- _XReadPad (dpy, packbuffer, size);
-
- lp = data;
- lpack = (long *) packbuffer;
- nwords = size >> 2;
- bits = 32;
-
- for(i=0;i<nwords;i++){
- maskw = mask32 << bits;
- *lp++ = ( *lpack & maskw ) >> bits;
- bits = bits ^32;
- if(bits){
- lpack++;
- }
- }
-}
-
-void _XRead32(
- Display *dpy,
- long *data,
- long len)
-{
- char packbuffer[PACKBUFFERSIZE];
- unsigned nunits = PACKBUFFERSIZE >> 2;
-
- for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
- _doXRead32 (dpy, data, PACKBUFFERSIZE, packbuffer);
- }
- if (len) _doXRead32 (dpy, data, len, packbuffer);
-}
-
-
-
-/*
- * _XRead16 - Read bytes from the socket unpacking each 16 bits
- * into a long (64 bits on a CRAY computer).
- *
- */
-static _doXRead16(
- register Display *dpy,
- register short *data,
- register long size,
- char *packbuffer)
-{
- long *lpack,*lp;
- long mask16 = 0x000000000000ffff;
- long maskw, nwords, i, bits;
-
- (void) _XRead(dpy,packbuffer,size); /* don't do a padded read... */
-
- lp = (long *) data;
- lpack = (long *) packbuffer;
- nwords = size >> 1; /* number of 16 bit words to be unpacked */
- bits = 48;
- for(i=0;i<nwords;i++){
- maskw = mask16 << bits;
- *lp++ = ( *lpack & maskw ) >> bits;
- bits -= 16;
- if(bits < 0){
- lpack++;
- bits = 48;
- }
- }
-}
-
-void _XRead16(
- Display *dpy,
- short *data,
- long len)
-{
- char packbuffer[PACKBUFFERSIZE];
- unsigned nunits = PACKBUFFERSIZE >> 1;
-
- for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
- _doXRead16 (dpy, data, PACKBUFFERSIZE, packbuffer);
- }
- if (len) _doXRead16 (dpy, data, len, packbuffer);
-}
-
-void _XRead16Pad(
- Display *dpy,
- short *data,
- long size)
-{
- int slop = (size & 3);
- short slopbuf[3];
-
- _XRead16 (dpy, data, size);
- if (slop > 0) {
- _XRead16 (dpy, slopbuf, 4 - slop);
- }
-}
-#endif /* WORD64 */
-
-/*
- * The hard part about this is that we only get 16 bits from a reply.
- * We have three values that will march along, with the following invariant:
- * dpy->last_request_read <= rep->sequenceNumber <= dpy->request
- * We have to keep
- * dpy->request - dpy->last_request_read < 2^16
- * or else we won't know for sure what value to use in events. We do this
- * by forcing syncs when we get close.
- */
-
-unsigned long
-_XSetLastRequestRead(
- register Display *dpy,
- register xGenericReply *rep)
-{
- register unsigned long newseq, lastseq;
-
- lastseq = dpy->last_request_read;
- /*
- * KeymapNotify has no sequence number, but is always guaranteed
- * to immediately follow another event, except when generated via
- * SendEvent (hmmm).
- */
- if ((rep->type & 0x7f) == KeymapNotify)
- return(lastseq);
-
- newseq = (lastseq & ~((unsigned long)0xffff)) | rep->sequenceNumber;
-
- if (newseq < lastseq) {
- newseq += 0x10000;
- if (newseq > dpy->request) {
- (void) fprintf (stderr,
- "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n",
- newseq, dpy->request,
- (unsigned int) rep->type);
- newseq -= 0x10000;
- }
- }
-
- dpy->last_request_read = newseq;
- return(newseq);
-}
-
-/*
- * Support for internal connections, such as an IM might use.
- * By Stephen Gildea, X Consortium, September 1993
- */
-
-/* _XRegisterInternalConnection
- * Each IM (or Xlib extension) that opens a file descriptor that Xlib should
- * include in its select/poll mask must call this function to register the
- * fd with Xlib. Any XConnectionWatchProc registered by XAddConnectionWatch
- * will also be called.
- *
- * Whenever Xlib detects input available on fd, it will call callback
- * with call_data to process it. If non-Xlib code calls select/poll
- * and detects input available, it must call XProcessInternalConnection,
- * which will call the associated callback.
- *
- * Non-Xlib code can learn about these additional fds by calling
- * XInternalConnectionNumbers or, more typically, by registering
- * a XConnectionWatchProc with XAddConnectionWatch
- * to be called when fds are registered or unregistered.
- *
- * Returns True if registration succeeded, False if not, typically
- * because could not allocate memory.
- * Assumes Display locked when called.
- */
-Status
-_XRegisterInternalConnection(
- Display* dpy,
- int fd,
- _XInternalConnectionProc callback,
- XPointer call_data
-)
-{
- struct _XConnectionInfo *new_conni, **iptr;
- struct _XConnWatchInfo *watchers;
- XPointer *wd;
-
- new_conni = (struct _XConnectionInfo*)Xmalloc(sizeof(struct _XConnectionInfo));
- if (!new_conni)
- return 0;
- new_conni->watch_data = (XPointer *)Xmalloc(dpy->watcher_count * sizeof(XPointer));
- if (!new_conni->watch_data) {
- Xfree(new_conni);
- return 0;
- }
- new_conni->fd = fd;
- new_conni->read_callback = callback;
- new_conni->call_data = call_data;
- new_conni->next = NULL;
- /* link new structure onto end of list */
- for (iptr = &dpy->im_fd_info; *iptr; iptr = &(*iptr)->next)
- ;
- *iptr = new_conni;
- dpy->im_fd_length++;
- _XPollfdCacheAdd(dpy, fd);
-
- for (watchers=dpy->conn_watchers, wd=new_conni->watch_data;
- watchers;
- watchers=watchers->next, wd++) {
- *wd = NULL; /* for cleanliness */
- (*watchers->fn) (dpy, watchers->client_data, fd, True, wd);
- }
-
- return 1;
-}
-
-/* _XUnregisterInternalConnection
- * Each IM (or Xlib extension) that closes a file descriptor previously
- * registered with _XRegisterInternalConnection must call this function.
- * Any XConnectionWatchProc registered by XAddConnectionWatch
- * will also be called.
- *
- * Assumes Display locked when called.
- */
-void
-_XUnregisterInternalConnection(
- Display* dpy,
- int fd
-)
-{
- struct _XConnectionInfo *info_list, **prev;
- struct _XConnWatchInfo *watch;
- XPointer *wd;
-
- for (prev = &dpy->im_fd_info; (info_list = *prev);
- prev = &info_list->next) {
- if (info_list->fd == fd) {
- *prev = info_list->next;
- dpy->im_fd_length--;
- for (watch=dpy->conn_watchers, wd=info_list->watch_data;
- watch;
- watch=watch->next, wd++) {
- (*watch->fn) (dpy, watch->client_data, fd, False, wd);
- }
- if (info_list->watch_data)
- Xfree (info_list->watch_data);
- Xfree (info_list);
- break;
- }
- }
- _XPollfdCacheDel(dpy, fd);
-}
-
-/* XInternalConnectionNumbers
- * Returns an array of fds and an array of corresponding call data.
- * Typically a XConnectionWatchProc registered with XAddConnectionWatch
- * will be used instead of this function to discover
- * additional fds to include in the select/poll mask.
- *
- * The list is allocated with Xmalloc and should be freed by the caller
- * with Xfree;
- */
-Status
-XInternalConnectionNumbers(
- Display *dpy,
- int **fd_return,
- int *count_return
-)
-{
- int count;
- struct _XConnectionInfo *info_list;
- int *fd_list;
-
- LockDisplay(dpy);
- count = 0;
- for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next)
- count++;
- fd_list = (int*) Xmalloc (count * sizeof(int));
- if (!fd_list) {
- UnlockDisplay(dpy);
- return 0;
- }
- count = 0;
- for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
- fd_list[count] = info_list->fd;
- count++;
- }
- UnlockDisplay(dpy);
-
- *fd_return = fd_list;
- *count_return = count;
- return 1;
-}
-
-void _XProcessInternalConnection(
- Display *dpy,
- struct _XConnectionInfo *conn_info)
-{
- dpy->flags |= XlibDisplayProcConni;
- UnlockDisplay(dpy);
- (*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data);
- LockDisplay(dpy);
- dpy->flags &= ~XlibDisplayProcConni;
-}
-
-/* XProcessInternalConnection
- * Call the _XInternalConnectionProc registered by _XRegisterInternalConnection
- * for this fd.
- * The Display is NOT locked during the call.
- */
-void
-XProcessInternalConnection(
- Display* dpy,
- int fd
-)
-{
- struct _XConnectionInfo *info_list;
-
- LockDisplay(dpy);
- for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
- if (info_list->fd == fd) {
- _XProcessInternalConnection(dpy, info_list);
- break;
- }
- }
- UnlockDisplay(dpy);
-}
-
-/* XAddConnectionWatch
- * Register a callback to be called whenever _XRegisterInternalConnection
- * or _XUnregisterInternalConnection is called.
- * Callbacks are called with the Display locked.
- * If any connections are already registered, the callback is immediately
- * called for each of them.
- */
-Status
-XAddConnectionWatch(
- Display* dpy,
- XConnectionWatchProc callback,
- XPointer client_data
-)
-{
- struct _XConnWatchInfo *new_watcher, **wptr;
- struct _XConnectionInfo *info_list;
- XPointer *wd_array;
-
- LockDisplay(dpy);
-
- /* allocate new watch data */
- for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
- wd_array = (XPointer *)Xrealloc((char *)info_list->watch_data,
- (dpy->watcher_count + 1) *
- sizeof(XPointer));
- if (!wd_array) {
- UnlockDisplay(dpy);
- return 0;
- }
- wd_array[dpy->watcher_count] = NULL; /* for cleanliness */
- }
-
- new_watcher = (struct _XConnWatchInfo*)Xmalloc(sizeof(struct _XConnWatchInfo));
- if (!new_watcher) {
- UnlockDisplay(dpy);
- return 0;
- }
- new_watcher->fn = callback;
- new_watcher->client_data = client_data;
- new_watcher->next = NULL;
-
- /* link new structure onto end of list */
- for (wptr = &dpy->conn_watchers; *wptr; wptr = &(*wptr)->next)
- ;
- *wptr = new_watcher;
- dpy->watcher_count++;
-
- /* call new watcher on all currently registered fds */
- for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
- (*callback) (dpy, client_data, info_list->fd, True,
- info_list->watch_data + dpy->watcher_count - 1);
- }
-
- UnlockDisplay(dpy);
- return 1;
-}
-
-/* XRemoveConnectionWatch
- * Unregister a callback registered by XAddConnectionWatch.
- * Both callback and client_data must match what was passed to
- * XAddConnectionWatch.
- */
-void
-XRemoveConnectionWatch(
- Display* dpy,
- XConnectionWatchProc callback,
- XPointer client_data
-)
-{
- struct _XConnWatchInfo *watch;
- struct _XConnWatchInfo *previous = NULL;
- struct _XConnectionInfo *conni;
- int counter = 0;
-
- LockDisplay(dpy);
- for (watch=dpy->conn_watchers; watch; watch=watch->next) {
- if (watch->fn == callback && watch->client_data == client_data) {
- if (previous)
- previous->next = watch->next;
- else
- dpy->conn_watchers = watch->next;
- Xfree (watch);
- dpy->watcher_count--;
- /* remove our watch_data for each connection */
- for (conni=dpy->im_fd_info; conni; conni=conni->next) {
- /* don't bother realloc'ing; these arrays are small anyway */
- /* overlapping */
- memmove(conni->watch_data+counter,
- conni->watch_data+counter+1,
- dpy->watcher_count - counter);
- }
- break;
- }
- previous = watch;
- counter++;
- }
- UnlockDisplay(dpy);
-}
-
-/* end of internal connections support */
-
-/* Cookie jar implementation
- dpy->cookiejar is a linked list. _XEnq receives the events but leaves
- them in the normal EQ. _XStoreEvent returns the cookie event (minus
- data pointer) and adds it to the cookiejar. _XDeq just removes
- the entry like any other event but resets the data pointer for
- cookie events (to avoid double-free, the memory is re-used by Xlib).
-
- _XFetchEventCookie (called from XGetEventData) removes a cookie from the
- jar. _XFreeEventCookies removes all unclaimed cookies from the jar
- (called by XNextEvent).
-
- _XFreeDisplayStructure calls _XFreeEventCookies for each cookie in the
- normal EQ.
- */
-
-#include "utlist.h"
-struct stored_event {
- XGenericEventCookie ev;
- struct stored_event *prev;
- struct stored_event *next;
-};
-
-Bool
-_XIsEventCookie(Display *dpy, XEvent *ev)
-{
- return (ev->xcookie.type == GenericEvent &&
- dpy->generic_event_vec[ev->xcookie.extension & 0x7F] != NULL);
-}
-
-/**
- * Free all events in the event list.
- */
-void
-_XFreeEventCookies(Display *dpy)
-{
- struct stored_event **head, *e, *tmp;
-
- if (!dpy->cookiejar)
- return;
-
- head = (struct stored_event**)&dpy->cookiejar;
-
- DL_FOREACH_SAFE(*head, e, tmp) {
- XFree(e->ev.data);
- XFree(e);
- if (dpy->cookiejar == e)
- dpy->cookiejar = NULL;
- }
-}
-
-/**
- * Add an event to the display's event list. This event must be freed on the
- * next call to XNextEvent().
- */
-void
-_XStoreEventCookie(Display *dpy, XEvent *event)
-{
- XGenericEventCookie* cookie = &event->xcookie;
- struct stored_event **head, *add;
-
- if (!_XIsEventCookie(dpy, event))
- return;
-
- head = (struct stored_event**)(&dpy->cookiejar);
-
- add = Xmalloc(sizeof(struct stored_event));
- if (!add) {
- ESET(ENOMEM);
- _XIOError(dpy);
- }
- add->ev = *cookie;
- DL_APPEND(*head, add);
- cookie->data = NULL; /* don't return data yet, must be claimed */
-}
-
-/**
- * Return the event with the given cookie and remove it from the list.
- */
-Bool
-_XFetchEventCookie(Display *dpy, XGenericEventCookie* ev)
-{
- Bool ret = False;
- struct stored_event **head, *event;
- head = (struct stored_event**)&dpy->cookiejar;
-
- if (!_XIsEventCookie(dpy, (XEvent*)ev))
- return ret;
-
- DL_FOREACH(*head, event) {
- if (event->ev.cookie == ev->cookie &&
- event->ev.extension == ev->extension &&
- event->ev.evtype == ev->evtype) {
- *ev = event->ev;
- DL_DELETE(*head, event);
- Xfree(event);
- ret = True;
- break;
- }
- }
-
- return ret;
-}
-
-Bool
-_XCopyEventCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out)
-{
- Bool ret = False;
- int extension;
-
- if (!_XIsEventCookie(dpy, (XEvent*)in) || !out)
- return ret;
-
- extension = in->extension & 0x7F;
-
- if (!dpy->generic_event_copy_vec[extension])
- return ret;
-
- ret = ((*dpy->generic_event_copy_vec[extension])(dpy, in, out));
- out->cookie = ret ? ++dpy->next_cookie : 0;
- return ret;
-}
-
-
-/*
- * _XEnq - Place event packets on the display's queue.
- * note that no squishing of move events in V11, since there
- * is pointer motion hints....
- */
-void _XEnq(
- register Display *dpy,
- register xEvent *event)
-{
- register _XQEvent *qelt;
- int type, extension;
-
- if ((qelt = dpy->qfree)) {
- /* If dpy->qfree is non-NULL do this, else malloc a new one. */
- dpy->qfree = qelt->next;
- }
- else if ((qelt =
- (_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) {
- /* Malloc call failed! */
- ESET(ENOMEM);
- _XIOError(dpy);
- }
- qelt->next = NULL;
-
- type = event->u.u.type & 0177;
- extension = ((xGenericEvent*)event)->extension;
-
- qelt->event.type = type;
- /* If an extension has registerd a generic_event_vec handler, then
- * it can handle event cookies. Otherwise, proceed with the normal
- * event handlers.
- *
- * If the generic_event_vec is called, qelt->event is a event cookie
- * with the data pointer and the "free" pointer set. Data pointer is
- * some memory allocated by the extension.
- */
- if (type == GenericEvent && dpy->generic_event_vec[extension & 0x7F]) {
- XGenericEventCookie *cookie = &qelt->event.xcookie;
- (*dpy->generic_event_vec[extension & 0x7F])(dpy, cookie, event);
- cookie->cookie = ++dpy->next_cookie;
-
- qelt->qserial_num = dpy->next_event_serial_num++;
- if (dpy->tail) dpy->tail->next = qelt;
- else dpy->head = qelt;
-
- dpy->tail = qelt;
- dpy->qlen++;
- } else if ((*dpy->event_vec[type])(dpy, &qelt->event, event)) {
- qelt->qserial_num = dpy->next_event_serial_num++;
- if (dpy->tail) dpy->tail->next = qelt;
- else dpy->head = qelt;
-
- dpy->tail = qelt;
- dpy->qlen++;
- } else {
- /* ignored, or stashed away for many-to-one compression */
- qelt->next = dpy->qfree;
- dpy->qfree = qelt;
- }
-}
-
-/*
- * _XDeq - Remove event packet from the display's queue.
- */
-void _XDeq(
- register Display *dpy,
- register _XQEvent *prev, /* element before qelt */
- register _XQEvent *qelt) /* element to be unlinked */
-{
- if (prev) {
- if ((prev->next = qelt->next) == NULL)
- dpy->tail = prev;
- } else {
- /* no prev, so removing first elt */
- if ((dpy->head = qelt->next) == NULL)
- dpy->tail = NULL;
- }
- qelt->qserial_num = 0;
- qelt->next = dpy->qfree;
- dpy->qfree = qelt;
- dpy->qlen--;
-
- if (_XIsEventCookie(dpy, &qelt->event)) {
- XGenericEventCookie* cookie = &qelt->event.xcookie;
- /* dpy->qfree is re-used, reset memory to avoid double free on
- * _XFreeDisplayStructure */
- cookie->data = NULL;
- }
-}
-
-/*
- * EventToWire in separate file in that often not needed.
- */
-
-/*ARGSUSED*/
-Bool
-_XUnknownWireEvent(
- register Display *dpy, /* pointer to display structure */
- register XEvent *re, /* pointer to where event should be reformatted */
- register xEvent *event) /* wire protocol event */
-{
-#ifdef notdef
- (void) fprintf(stderr,
- "Xlib: unhandled wire event! event number = %d, display = %x\n.",
- event->u.u.type, dpy);
-#endif
- return(False);
-}
-
-Bool
-_XUnknownWireEventCookie(
- Display *dpy, /* pointer to display structure */
- XGenericEventCookie *re, /* pointer to where event should be reformatted */
- xEvent *event) /* wire protocol event */
-{
-#ifdef notdef
- fprintf(stderr,
- "Xlib: unhandled wire cookie event! extension number = %d, display = %x\n.",
- ((xGenericEvent*)event)->extension, dpy);
-#endif
- return(False);
-}
-
-Bool
-_XUnknownCopyEventCookie(
- Display *dpy, /* pointer to display structure */
- XGenericEventCookie *in, /* source */
- XGenericEventCookie *out) /* destination */
-{
-#ifdef notdef
- fprintf(stderr,
- "Xlib: unhandled cookie event copy! extension number = %d, display = %x\n.",
- in->extension, dpy);
-#endif
- return(False);
-}
-
-/*ARGSUSED*/
-Status
-_XUnknownNativeEvent(
- register Display *dpy, /* pointer to display structure */
- register XEvent *re, /* pointer to where event should be reformatted */
- register xEvent *event) /* wire protocol event */
-{
-#ifdef notdef
- (void) fprintf(stderr,
- "Xlib: unhandled native event! event number = %d, display = %x\n.",
- re->type, dpy);
-#endif
- return(0);
-}
-/*
- * reformat a wire event into an XEvent structure of the right type.
- */
-Bool
-_XWireToEvent(
- register Display *dpy, /* pointer to display structure */
- register XEvent *re, /* pointer to where event should be reformatted */
- register xEvent *event) /* wire protocol event */
-{
-
- re->type = event->u.u.type & 0x7f;
- ((XAnyEvent *)re)->serial = _XSetLastRequestRead(dpy,
- (xGenericReply *)event);
- ((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0);
- ((XAnyEvent *)re)->display = dpy;
-
- /* Ignore the leading bit of the event type since it is set when a
- client sends an event rather than the server. */
-
- switch (event-> u.u.type & 0177) {
- case KeyPress:
- case KeyRelease:
- {
- register XKeyEvent *ev = (XKeyEvent*) re;
- ev->root = event->u.keyButtonPointer.root;
- ev->window = event->u.keyButtonPointer.event;
- ev->subwindow = event->u.keyButtonPointer.child;
- ev->time = event->u.keyButtonPointer.time;
- ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX);
- ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY);
- ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX);
- ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY);
- ev->state = event->u.keyButtonPointer.state;
- ev->same_screen = event->u.keyButtonPointer.sameScreen;
- ev->keycode = event->u.u.detail;
- }
- break;
- case ButtonPress:
- case ButtonRelease:
- {
- register XButtonEvent *ev = (XButtonEvent *) re;
- ev->root = event->u.keyButtonPointer.root;
- ev->window = event->u.keyButtonPointer.event;
- ev->subwindow = event->u.keyButtonPointer.child;
- ev->time = event->u.keyButtonPointer.time;
- ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX);
- ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY);
- ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX);
- ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY);
- ev->state = event->u.keyButtonPointer.state;
- ev->same_screen = event->u.keyButtonPointer.sameScreen;
- ev->button = event->u.u.detail;
- }
- break;
- case MotionNotify:
- {
- register XMotionEvent *ev = (XMotionEvent *)re;
- ev->root = event->u.keyButtonPointer.root;
- ev->window = event->u.keyButtonPointer.event;
- ev->subwindow = event->u.keyButtonPointer.child;
- ev->time = event->u.keyButtonPointer.time;
- ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX);
- ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY);
- ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX);
- ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY);
- ev->state = event->u.keyButtonPointer.state;
- ev->same_screen = event->u.keyButtonPointer.sameScreen;
- ev->is_hint = event->u.u.detail;
- }
- break;
- case EnterNotify:
- case LeaveNotify:
- {
- register XCrossingEvent *ev = (XCrossingEvent *) re;
- ev->root = event->u.enterLeave.root;
- ev->window = event->u.enterLeave.event;
- ev->subwindow = event->u.enterLeave.child;
- ev->time = event->u.enterLeave.time;
- ev->x = cvtINT16toInt(event->u.enterLeave.eventX);
- ev->y = cvtINT16toInt(event->u.enterLeave.eventY);
- ev->x_root = cvtINT16toInt(event->u.enterLeave.rootX);
- ev->y_root = cvtINT16toInt(event->u.enterLeave.rootY);
- ev->state = event->u.enterLeave.state;
- ev->mode = event->u.enterLeave.mode;
- ev->same_screen = (event->u.enterLeave.flags &
- ELFlagSameScreen) && True;
- ev->focus = (event->u.enterLeave.flags &
- ELFlagFocus) && True;
- ev->detail = event->u.u.detail;
- }
- break;
- case FocusIn:
- case FocusOut:
- {
- register XFocusChangeEvent *ev = (XFocusChangeEvent *) re;
- ev->window = event->u.focus.window;
- ev->mode = event->u.focus.mode;
- ev->detail = event->u.u.detail;
- }
- break;
- case KeymapNotify:
- {
- register XKeymapEvent *ev = (XKeymapEvent *) re;
- ev->window = None;
- memcpy(&ev->key_vector[1],
- (char *)((xKeymapEvent *) event)->map,
- sizeof (((xKeymapEvent *) event)->map));
- }
- break;
- case Expose:
- {
- register XExposeEvent *ev = (XExposeEvent *) re;
- ev->window = event->u.expose.window;
- ev->x = event->u.expose.x;
- ev->y = event->u.expose.y;
- ev->width = event->u.expose.width;
- ev->height = event->u.expose.height;
- ev->count = event->u.expose.count;
- }
- break;
- case GraphicsExpose:
- {
- register XGraphicsExposeEvent *ev =
- (XGraphicsExposeEvent *) re;
- ev->drawable = event->u.graphicsExposure.drawable;
- ev->x = event->u.graphicsExposure.x;
- ev->y = event->u.graphicsExposure.y;
- ev->width = event->u.graphicsExposure.width;
- ev->height = event->u.graphicsExposure.height;
- ev->count = event->u.graphicsExposure.count;
- ev->major_code = event->u.graphicsExposure.majorEvent;
- ev->minor_code = event->u.graphicsExposure.minorEvent;
- }
- break;
- case NoExpose:
- {
- register XNoExposeEvent *ev = (XNoExposeEvent *) re;
- ev->drawable = event->u.noExposure.drawable;
- ev->major_code = event->u.noExposure.majorEvent;
- ev->minor_code = event->u.noExposure.minorEvent;
- }
- break;
- case VisibilityNotify:
- {
- register XVisibilityEvent *ev = (XVisibilityEvent *) re;
- ev->window = event->u.visibility.window;
- ev->state = event->u.visibility.state;
- }
- break;
- case CreateNotify:
- {
- register XCreateWindowEvent *ev =
- (XCreateWindowEvent *) re;
- ev->window = event->u.createNotify.window;
- ev->parent = event->u.createNotify.parent;
- ev->x = cvtINT16toInt(event->u.createNotify.x);
- ev->y = cvtINT16toInt(event->u.createNotify.y);
- ev->width = event->u.createNotify.width;
- ev->height = event->u.createNotify.height;
- ev->border_width = event->u.createNotify.borderWidth;
- ev->override_redirect = event->u.createNotify.override;
- }
- break;
- case DestroyNotify:
- {
- register XDestroyWindowEvent *ev =
- (XDestroyWindowEvent *) re;
- ev->window = event->u.destroyNotify.window;
- ev->event = event->u.destroyNotify.event;
- }
- break;
- case UnmapNotify:
- {
- register XUnmapEvent *ev = (XUnmapEvent *) re;
- ev->window = event->u.unmapNotify.window;
- ev->event = event->u.unmapNotify.event;
- ev->from_configure = event->u.unmapNotify.fromConfigure;
- }
- break;
- case MapNotify:
- {
- register XMapEvent *ev = (XMapEvent *) re;
- ev->window = event->u.mapNotify.window;
- ev->event = event->u.mapNotify.event;
- ev->override_redirect = event->u.mapNotify.override;
- }
- break;
- case MapRequest:
- {
- register XMapRequestEvent *ev = (XMapRequestEvent *) re;
- ev->window = event->u.mapRequest.window;
- ev->parent = event->u.mapRequest.parent;
- }
- break;
- case ReparentNotify:
- {
- register XReparentEvent *ev = (XReparentEvent *) re;
- ev->event = event->u.reparent.event;
- ev->window = event->u.reparent.window;
- ev->parent = event->u.reparent.parent;
- ev->x = cvtINT16toInt(event->u.reparent.x);
- ev->y = cvtINT16toInt(event->u.reparent.y);
- ev->override_redirect = event->u.reparent.override;
- }
- break;
- case ConfigureNotify:
- {
- register XConfigureEvent *ev = (XConfigureEvent *) re;
- ev->event = event->u.configureNotify.event;
- ev->window = event->u.configureNotify.window;
- ev->above = event->u.configureNotify.aboveSibling;
- ev->x = cvtINT16toInt(event->u.configureNotify.x);
- ev->y = cvtINT16toInt(event->u.configureNotify.y);
- ev->width = event->u.configureNotify.width;
- ev->height = event->u.configureNotify.height;
- ev->border_width = event->u.configureNotify.borderWidth;
- ev->override_redirect = event->u.configureNotify.override;
- }
- break;
- case ConfigureRequest:
- {
- register XConfigureRequestEvent *ev =
- (XConfigureRequestEvent *) re;
- ev->window = event->u.configureRequest.window;
- ev->parent = event->u.configureRequest.parent;
- ev->above = event->u.configureRequest.sibling;
- ev->x = cvtINT16toInt(event->u.configureRequest.x);
- ev->y = cvtINT16toInt(event->u.configureRequest.y);
- ev->width = event->u.configureRequest.width;
- ev->height = event->u.configureRequest.height;
- ev->border_width = event->u.configureRequest.borderWidth;
- ev->value_mask = event->u.configureRequest.valueMask;
- ev->detail = event->u.u.detail;
- }
- break;
- case GravityNotify:
- {
- register XGravityEvent *ev = (XGravityEvent *) re;
- ev->window = event->u.gravity.window;
- ev->event = event->u.gravity.event;
- ev->x = cvtINT16toInt(event->u.gravity.x);
- ev->y = cvtINT16toInt(event->u.gravity.y);
- }
- break;
- case ResizeRequest:
- {
- register XResizeRequestEvent *ev =
- (XResizeRequestEvent *) re;
- ev->window = event->u.resizeRequest.window;
- ev->width = event->u.resizeRequest.width;
- ev->height = event->u.resizeRequest.height;
- }
- break;
- case CirculateNotify:
- {
- register XCirculateEvent *ev = (XCirculateEvent *) re;
- ev->window = event->u.circulate.window;
- ev->event = event->u.circulate.event;
- ev->place = event->u.circulate.place;
- }
- break;
- case CirculateRequest:
- {
- register XCirculateRequestEvent *ev =
- (XCirculateRequestEvent *) re;
- ev->window = event->u.circulate.window;
- ev->parent = event->u.circulate.event;
- ev->place = event->u.circulate.place;
- }
- break;
- case PropertyNotify:
- {
- register XPropertyEvent *ev = (XPropertyEvent *) re;
- ev->window = event->u.property.window;
- ev->atom = event->u.property.atom;
- ev->time = event->u.property.time;
- ev->state = event->u.property.state;
- }
- break;
- case SelectionClear:
- {
- register XSelectionClearEvent *ev =
- (XSelectionClearEvent *) re;
- ev->window = event->u.selectionClear.window;
- ev->selection = event->u.selectionClear.atom;
- ev->time = event->u.selectionClear.time;
- }
- break;
- case SelectionRequest:
- {
- register XSelectionRequestEvent *ev =
- (XSelectionRequestEvent *) re;
- ev->owner = event->u.selectionRequest.owner;
- ev->requestor = event->u.selectionRequest.requestor;
- ev->selection = event->u.selectionRequest.selection;
- ev->target = event->u.selectionRequest.target;
- ev->property = event->u.selectionRequest.property;
- ev->time = event->u.selectionRequest.time;
- }
- break;
- case SelectionNotify:
- {
- register XSelectionEvent *ev = (XSelectionEvent *) re;
- ev->requestor = event->u.selectionNotify.requestor;
- ev->selection = event->u.selectionNotify.selection;
- ev->target = event->u.selectionNotify.target;
- ev->property = event->u.selectionNotify.property;
- ev->time = event->u.selectionNotify.time;
- }
- break;
- case ColormapNotify:
- {
- register XColormapEvent *ev = (XColormapEvent *) re;
- ev->window = event->u.colormap.window;
- ev->colormap = event->u.colormap.colormap;
- ev->new = event->u.colormap.new;
- ev->state = event->u.colormap.state;
- }
- break;
- case ClientMessage:
- {
- register int i;
- register XClientMessageEvent *ev
- = (XClientMessageEvent *) re;
- ev->window = event->u.clientMessage.window;
- ev->format = event->u.u.detail;
- switch (ev->format) {
- case 8:
- ev->message_type = event->u.clientMessage.u.b.type;
- for (i = 0; i < 20; i++)
- ev->data.b[i] = event->u.clientMessage.u.b.bytes[i];
- break;
- case 16:
- ev->message_type = event->u.clientMessage.u.s.type;
- ev->data.s[0] = cvtINT16toShort(event->u.clientMessage.u.s.shorts0);
- ev->data.s[1] = cvtINT16toShort(event->u.clientMessage.u.s.shorts1);
- ev->data.s[2] = cvtINT16toShort(event->u.clientMessage.u.s.shorts2);
- ev->data.s[3] = cvtINT16toShort(event->u.clientMessage.u.s.shorts3);
- ev->data.s[4] = cvtINT16toShort(event->u.clientMessage.u.s.shorts4);
- ev->data.s[5] = cvtINT16toShort(event->u.clientMessage.u.s.shorts5);
- ev->data.s[6] = cvtINT16toShort(event->u.clientMessage.u.s.shorts6);
- ev->data.s[7] = cvtINT16toShort(event->u.clientMessage.u.s.shorts7);
- ev->data.s[8] = cvtINT16toShort(event->u.clientMessage.u.s.shorts8);
- ev->data.s[9] = cvtINT16toShort(event->u.clientMessage.u.s.shorts9);
- break;
- case 32:
- ev->message_type = event->u.clientMessage.u.l.type;
- ev->data.l[0] = cvtINT32toLong(event->u.clientMessage.u.l.longs0);
- ev->data.l[1] = cvtINT32toLong(event->u.clientMessage.u.l.longs1);
- ev->data.l[2] = cvtINT32toLong(event->u.clientMessage.u.l.longs2);
- ev->data.l[3] = cvtINT32toLong(event->u.clientMessage.u.l.longs3);
- ev->data.l[4] = cvtINT32toLong(event->u.clientMessage.u.l.longs4);
- break;
- default: /* XXX should never occur */
- break;
- }
- }
- break;
- case MappingNotify:
- {
- register XMappingEvent *ev = (XMappingEvent *)re;
- ev->window = 0;
- ev->first_keycode = event->u.mappingNotify.firstKeyCode;
- ev->request = event->u.mappingNotify.request;
- ev->count = event->u.mappingNotify.count;
- }
- break;
- default:
- return(_XUnknownWireEvent(dpy, re, event));
- }
- return(True);
-}
-
-
-/*
- * _XDefaultIOError - Default fatal system error reporting routine. Called
- * when an X internal system error is encountered.
- */
-int _XDefaultIOError(
- Display *dpy)
-{
- if (ECHECK(EPIPE)) {
- (void) fprintf (stderr,
- "X connection to %s broken (explicit kill or server shutdown).\r\n",
- DisplayString (dpy));
- } else {
- (void) fprintf (stderr,
- "XIO: fatal IO error %d (%s) on X server \"%s\"\r\n",
-#ifdef WIN32
- WSAGetLastError(), strerror(WSAGetLastError()),
-#else
- errno, strerror (errno),
-#endif
- DisplayString (dpy));
- (void) fprintf (stderr,
- " after %lu requests (%lu known processed) with %d events remaining.\r\n",
- NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy),
- QLength(dpy));
-
- }
- exit(1);
- return(0); /* dummy - function should never return */
-}
-
-
-static int _XPrintDefaultError(
- Display *dpy,
- XErrorEvent *event,
- FILE *fp)
-{
- char buffer[BUFSIZ];
- char mesg[BUFSIZ];
- char number[32];
- const char *mtype = "XlibMessage";
- register _XExtension *ext = (_XExtension *)NULL;
- _XExtension *bext = (_XExtension *)NULL;
- XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
- XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
- (void) fprintf(fp, "%s: %s\n ", mesg, buffer);
- XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
- mesg, BUFSIZ);
- (void) fprintf(fp, mesg, event->request_code);
- if (event->request_code < 128) {
- sprintf(number, "%d", event->request_code);
- XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
- } else {
- for (ext = dpy->ext_procs;
- ext && (ext->codes.major_opcode != event->request_code);
- ext = ext->next)
- ;
- if (ext)
- strcpy(buffer, ext->name);
- else
- buffer[0] = '\0';
- }
- (void) fprintf(fp, " (%s)\n", buffer);
- if (event->request_code >= 128) {
- XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
- mesg, BUFSIZ);
- fputs(" ", fp);
- (void) fprintf(fp, mesg, event->minor_code);
- if (ext) {
- sprintf(mesg, "%s.%d", ext->name, event->minor_code);
- XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
- (void) fprintf(fp, " (%s)", buffer);
- }
- fputs("\n", fp);
- }
- if (event->error_code >= 128) {
- /* kludge, try to find the extension that caused it */
- buffer[0] = '\0';
- for (ext = dpy->ext_procs; ext; ext = ext->next) {
- if (ext->error_string)
- (*ext->error_string)(dpy, event->error_code, &ext->codes,
- buffer, BUFSIZ);
- if (buffer[0]) {
- bext = ext;
- break;
- }
- if (ext->codes.first_error &&
- ext->codes.first_error < (int)event->error_code &&
- (!bext || ext->codes.first_error > bext->codes.first_error))
- bext = ext;
- }
- if (bext)
- sprintf(buffer, "%s.%d", bext->name,
- event->error_code - bext->codes.first_error);
- else
- strcpy(buffer, "Value");
- XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
- if (mesg[0]) {
- fputs(" ", fp);
- (void) fprintf(fp, mesg, event->resourceid);
- fputs("\n", fp);
- }
- /* let extensions try to print the values */
- for (ext = dpy->ext_procs; ext; ext = ext->next) {
- if (ext->error_values)
- (*ext->error_values)(dpy, event, fp);
- }
- } else if ((event->error_code == BadWindow) ||
- (event->error_code == BadPixmap) ||
- (event->error_code == BadCursor) ||
- (event->error_code == BadFont) ||
- (event->error_code == BadDrawable) ||
- (event->error_code == BadColor) ||
- (event->error_code == BadGC) ||
- (event->error_code == BadIDChoice) ||
- (event->error_code == BadValue) ||
- (event->error_code == BadAtom)) {
- if (event->error_code == BadValue)
- XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
- mesg, BUFSIZ);
- else if (event->error_code == BadAtom)
- XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
- mesg, BUFSIZ);
- else
- XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
- mesg, BUFSIZ);
- fputs(" ", fp);
- (void) fprintf(fp, mesg, event->resourceid);
- fputs("\n", fp);
- }
- XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
- mesg, BUFSIZ);
- fputs(" ", fp);
- (void) fprintf(fp, mesg, event->serial);
- XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
- mesg, BUFSIZ);
- fputs("\n ", fp);
- (void) fprintf(fp, mesg, dpy->request);
- fputs("\n", fp);
- if (event->error_code == BadImplementation) return 0;
- return 1;
-}
-
-int _XDefaultError(
- Display *dpy,
- XErrorEvent *event)
-{
- if (_XPrintDefaultError (dpy, event, stderr) == 0) return 0;
- exit(1);
- /*NOTREACHED*/
-}
-
-/*ARGSUSED*/
-Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we)
-{
- return True;
-}
-
-/*
- * _XError - upcall internal or user protocol error handler
- */
-int _XError (
- Display *dpy,
- register xError *rep)
-{
- /*
- * X_Error packet encountered! We need to unpack the error before
- * giving it to the user.
- */
- XEvent event; /* make it a large event */
- register _XAsyncHandler *async, *next;
-
- event.xerror.serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep);
-
- for (async = dpy->async_handlers; async; async = next) {
- next = async->next;
- if ((*async->handler)(dpy, (xReply *)rep,
- (char *)rep, SIZEOF(xError), async->data))
- return 0;
- }
-
- event.xerror.display = dpy;
- event.xerror.type = X_Error;
- event.xerror.resourceid = rep->resourceID;
- event.xerror.error_code = rep->errorCode;
- event.xerror.request_code = rep->majorCode;
- event.xerror.minor_code = rep->minorCode;
- if (dpy->error_vec &&
- !(*dpy->error_vec[rep->errorCode])(dpy, &event.xerror, rep))
- return 0;
- if (_XErrorFunction != NULL) {
- return (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */
- } else {
- return _XDefaultError(dpy, (XErrorEvent *)&event);
- }
-}
-
-/*
- * _XIOError - call user connection error handler and exit
- */
-int
-_XIOError (
- Display *dpy)
-{
- dpy->flags |= XlibDisplayIOError;
-#ifdef WIN32
- errno = WSAGetLastError();
-#endif
-
- /* This assumes that the thread calling exit will call any atexit handlers.
- * If this does not hold, then an alternate solution would involve
- * registering an atexit handler to take over the lock, which would only
- * assume that the same thread calls all the atexit handlers. */
-#ifdef XTHREADS
- if (dpy->lock)
- (*dpy->lock->user_lock_display)(dpy);
-#endif
- UnlockDisplay(dpy);
-
- if (_XIOErrorFunction != NULL)
- (*_XIOErrorFunction)(dpy);
- else
- _XDefaultIOError(dpy);
- exit (1);
- return 0;
-}
-
-
-/*
- * This routine can be used to (cheaply) get some memory within a single
- * Xlib routine for scratch space. A single buffer is reused each time
- * if possible. To be MT safe, you can only call this between a call to
- * GetReq* and a call to Data* or _XSend*, or in a context when the thread
- * is guaranteed to not unlock the display.
- */
-char *_XAllocScratch(
- register Display *dpy,
- unsigned long nbytes)
-{
- if (nbytes > dpy->scratch_length) {
- if (dpy->scratch_buffer) Xfree (dpy->scratch_buffer);
- if ((dpy->scratch_buffer = Xmalloc((unsigned) nbytes)))
- dpy->scratch_length = nbytes;
- else dpy->scratch_length = 0;
- }
- return (dpy->scratch_buffer);
-}
-
-/*
- * Scratch space allocator you can call any time, multiple times, and be
- * MT safe, but you must hand the buffer back with _XFreeTemp.
- */
-char *_XAllocTemp(
- register Display *dpy,
- unsigned long nbytes)
-{
- char *buf;
-
- buf = _XAllocScratch(dpy, nbytes);
- dpy->scratch_buffer = NULL;
- dpy->scratch_length = 0;
- return buf;
-}
-
-void _XFreeTemp(
- register Display *dpy,
- char *buf,
- unsigned long nbytes)
-{
- if (dpy->scratch_buffer)
- Xfree(dpy->scratch_buffer);
- dpy->scratch_buffer = buf;
- dpy->scratch_length = nbytes;
-}
-
-/*
- * Given a visual id, find the visual structure for this id on this display.
- */
-Visual *_XVIDtoVisual(
- Display *dpy,
- VisualID id)
-{
- register int i, j, k;
- register Screen *sp;
- register Depth *dp;
- register Visual *vp;
- for (i = 0; i < dpy->nscreens; i++) {
- sp = &dpy->screens[i];
- for (j = 0; j < sp->ndepths; j++) {
- dp = &sp->depths[j];
- /* if nvisuals == 0 then visuals will be NULL */
- for (k = 0; k < dp->nvisuals; k++) {
- vp = &dp->visuals[k];
- if (vp->visualid == id) return (vp);
- }
- }
- }
- return (NULL);
-}
-
-int
-XFree (void *data)
-{
- Xfree (data);
- return 1;
-}
-
-#ifdef _XNEEDBCOPYFUNC
-void _Xbcopy(b1, b2, length)
- register char *b1, *b2;
- register length;
-{
- if (b1 < b2) {
- b2 += length;
- b1 += length;
- while (length--)
- *--b2 = *--b1;
- } else {
- while (length--)
- *b2++ = *b1++;
- }
-}
-#endif
-
-#ifdef DataRoutineIsProcedure
-void Data(
- Display *dpy,
- char *data,
- long len)
-{
- if (dpy->bufptr + (len) <= dpy->bufmax) {
- memcpy(dpy->bufptr, data, (int)len);
- dpy->bufptr += ((len) + 3) & ~3;
- } else {
- _XSend(dpy, data, len);
- }
-}
-#endif /* DataRoutineIsProcedure */
-
-
-#ifdef LONG64
-int
-_XData32(
- Display *dpy,
- register long *data,
- unsigned len)
-{
- register int *buf;
- register long i;
-
- while (len) {
- buf = (int *)dpy->bufptr;
- i = dpy->bufmax - (char *)buf;
- if (!i) {
- _XFlush(dpy);
- continue;
- }
- if (len < i)
- i = len;
- dpy->bufptr = (char *)buf + i;
- len -= i;
- i >>= 2;
- while (--i >= 0)
- *buf++ = *data++;
- }
- return 0;
-}
-#endif /* LONG64 */
-
-#ifdef WORD64
-
-/*
- * XXX This is a *really* stupid way of doing this. It should just use
- * dpy->bufptr directly, taking into account where in the word it is.
- */
-
-/*
- * Data16 - Place 16 bit data in the buffer.
- *
- * "dpy" is a pointer to a Display.
- * "data" is a pointer to the data.
- * "len" is the length in bytes of the data.
- */
-
-static doData16(
- register Display *dpy,
- short *data,
- unsigned len,
- char *packbuffer)
-{
- long *lp,*lpack;
- long i, nwords,bits;
- long mask16 = 0x000000000000ffff;
-
- lp = (long *)data;
- lpack = (long *)packbuffer;
-
-/* nwords is the number of 16 bit values to be packed,
- * the low order 16 bits of each word will be packed
- * into 64 bit words
- */
- nwords = len >> 1;
- bits = 48;
-
- for(i=0;i<nwords;i++){
- if (bits == 48) *lpack = 0;
- *lpack ^= (*lp & mask16) << bits;
- bits -= 16 ;
- lp++;
- if(bits < 0){
- lpack++;
- bits = 48;
- }
- }
- Data(dpy, packbuffer, len);
-}
-
-_XData16 (
- Display *dpy,
- short *data,
- unsigned len)
-{
- char packbuffer[PACKBUFFERSIZE];
- unsigned nunits = PACKBUFFERSIZE >> 1;
-
- for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
- doData16 (dpy, data, PACKBUFFERSIZE, packbuffer);
- }
- if (len) doData16 (dpy, data, len, packbuffer);
-}
-
-/*
- * Data32 - Place 32 bit data in the buffer.
- *
- * "dpy" is a pointer to a Display.
- * "data" is a pointer to the data.
- * "len" is the length in bytes of the data.
- */
-
-static doData32(
- register Display *dpy
- long *data,
- unsigned len,
- char *packbuffer)
-{
- long *lp,*lpack;
- long i,bits,nwords;
- long mask32 = 0x00000000ffffffff;
-
- lpack = (long *) packbuffer;
- lp = data;
-
-/* nwords is the number of 32 bit values to be packed
- * the low order 32 bits of each word will be packed
- * into 64 bit words
- */
- nwords = len >> 2;
- bits = 32;
-
- for(i=0;i<nwords;i++){
- if (bits == 32) *lpack = 0;
- *lpack ^= (*lp & mask32) << bits;
- bits = bits ^32;
- lp++;
- if(bits)
- lpack++;
- }
- Data(dpy, packbuffer, len);
-}
-
-void _XData32(
- Display *dpy,
- long *data,
- unsigned len)
-{
- char packbuffer[PACKBUFFERSIZE];
- unsigned nunits = PACKBUFFERSIZE >> 2;
-
- for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
- doData32 (dpy, data, PACKBUFFERSIZE, packbuffer);
- }
- if (len) doData32 (dpy, data, len, packbuffer);
-}
-
-#endif /* WORD64 */
-
-
-/* Make sure this produces the same string as DefineLocal/DefineSelf in xdm.
- * Otherwise, Xau will not be able to find your cookies in the Xauthority file.
- *
- * Note: POSIX says that the ``nodename'' member of utsname does _not_ have
- * to have sufficient information for interfacing to the network,
- * and so, you may be better off using gethostname (if it exists).
- */
-
-#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(SVR4)
-#define NEED_UTSNAME
-#include <sys/utsname.h>
-#else
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#endif
-
-/*
- * _XGetHostname - similar to gethostname but allows special processing.
- */
-int _XGetHostname (
- char *buf,
- int maxlen)
-{
- int len;
-
-#ifdef NEED_UTSNAME
- struct utsname name;
-
- if (maxlen <= 0 || buf == NULL)
- return 0;
-
- uname (&name);
- len = strlen (name.nodename);
- if (len >= maxlen) len = maxlen - 1;
- strncpy (buf, name.nodename, len);
- buf[len] = '\0';
-#else
- if (maxlen <= 0 || buf == NULL)
- return 0;
-
- buf[0] = '\0';
- (void) gethostname (buf, maxlen);
- buf [maxlen - 1] = '\0';
- len = strlen(buf);
-#endif /* NEED_UTSNAME */
- return len;
-}
-
-
-/*
- * _XScreenOfWindow - get the Screen of a given window
- */
-
-Screen *_XScreenOfWindow(Display *dpy, Window w)
-{
- register int i;
- Window root;
- int x, y; /* dummy variables */
- unsigned int width, height, bw, depth; /* dummy variables */
-
- if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height,
- &bw, &depth) == False) {
- return NULL;
- }
- for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */
- if (root == RootWindow (dpy, i)) {
- return ScreenOfDisplay (dpy, i);
- }
- }
- return NULL;
-}
-
-
-#if defined(WIN32)
-
-/*
- * These functions are intended to be used internally to Xlib only.
- * These functions will always prefix the path with a DOS drive in the
- * form "<drive-letter>:". As such, these functions are only suitable
- * for use by Xlib function that supply a root-based path to some
- * particular file, e.g. <ProjectRoot>/lib/X11/locale/locale.dir will
- * be converted to "C:/usr/X11R6.3/lib/X11/locale/locale.dir".
- */
-
-static int access_file (path, pathbuf, len_pathbuf, pathret)
- char* path;
- char* pathbuf;
- int len_pathbuf;
- char** pathret;
-{
- if (access (path, F_OK) == 0) {
- if (strlen (path) < len_pathbuf)
- *pathret = pathbuf;
- else
- *pathret = Xmalloc (strlen (path) + 1);
- if (*pathret) {
- strcpy (*pathret, path);
- return 1;
- }
- }
- return 0;
-}
-
-static int AccessFile (path, pathbuf, len_pathbuf, pathret)
- char* path;
- char* pathbuf;
- int len_pathbuf;
- char** pathret;
-{
- unsigned long drives;
- int i, len;
- char* drive;
- char buf[MAX_PATH];
- char* bufp;
-
- /* just try the "raw" name first and see if it works */
- if (access_file (path, pathbuf, len_pathbuf, pathret))
- return 1;
-
- /* try the places set in the environment */
- drive = getenv ("_XBASEDRIVE");
-#ifdef __UNIXOS2__
- if (!drive)
- drive = getenv ("X11ROOT");
-#endif
- if (!drive)
- drive = "C:";
- len = strlen (drive) + strlen (path);
- if (len < MAX_PATH) bufp = buf;
- else bufp = Xmalloc (len + 1);
- strcpy (bufp, drive);
- strcat (bufp, path);
- if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
- if (bufp != buf) Xfree (bufp);
- return 1;
- }
-
-#ifndef __UNIXOS2__
- /* one last place to look */
- drive = getenv ("HOMEDRIVE");
- if (drive) {
- len = strlen (drive) + strlen (path);
- if (len < MAX_PATH) bufp = buf;
- else bufp = Xmalloc (len + 1);
- strcpy (bufp, drive);
- strcat (bufp, path);
- if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
- if (bufp != buf) Xfree (bufp);
- return 1;
- }
- }
-
- /* tried everywhere else, go fishing */
-#define C_DRIVE ('C' - 'A')
-#define Z_DRIVE ('Z' - 'A')
- /* does OS/2 (with or with gcc-emx) have getdrives? */
- drives = _getdrives ();
- for (i = C_DRIVE; i <= Z_DRIVE; i++) { /* don't check on A: or B: */
- if ((1 << i) & drives) {
- len = 2 + strlen (path);
- if (len < MAX_PATH) bufp = buf;
- else bufp = Xmalloc (len + 1);
- *bufp = 'A' + i;
- *(bufp + 1) = ':';
- *(bufp + 2) = '\0';
- strcat (bufp, path);
- if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
- if (bufp != buf) Xfree (bufp);
- return 1;
- }
- }
- }
-#endif
- return 0;
-}
-
-int _XOpenFile(path, flags)
- _Xconst char* path;
- int flags;
-{
- char buf[MAX_PATH];
- char* bufp = NULL;
- int ret = -1;
- UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
-
- if (AccessFile (path, buf, MAX_PATH, &bufp))
- ret = open (bufp, flags);
-
- (void) SetErrorMode (olderror);
-
- if (bufp != buf) Xfree (bufp);
-
- return ret;
-}
-
-int _XOpenFileMode(path, flags, mode)
- _Xconst char* path;
- int flags;
- mode_t mode;
-{
- char buf[MAX_PATH];
- char* bufp = NULL;
- int ret = -1;
- UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
-
- if (AccessFile (path, buf, MAX_PATH, &bufp))
- ret = open (bufp, flags, mode);
-
- (void) SetErrorMode (olderror);
-
- if (bufp != buf) Xfree (bufp);
-
- return ret;
-}
-
-void* _XFopenFile(path, mode)
- _Xconst char* path;
- _Xconst char* mode;
-{
- char buf[MAX_PATH];
- char* bufp = NULL;
- void* ret = NULL;
- UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
-
- if (AccessFile (path, buf, MAX_PATH, &bufp))
- ret = fopen (bufp, mode);
-
- (void) SetErrorMode (olderror);
-
- if (bufp != buf) Xfree (bufp);
-
- return ret;
-}
-
-int _XAccessFile(path)
- _Xconst char* path;
-{
- char buf[MAX_PATH];
- char* bufp;
- int ret = -1;
- UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
-
- ret = AccessFile (path, buf, MAX_PATH, &bufp);
-
- (void) SetErrorMode (olderror);
-
- if (bufp != buf) Xfree (bufp);
-
- return ret;
-}
-
-#endif
-
-#ifdef WIN32
-#undef _Xdebug
-int _Xdebug = 0;
-int *_Xdebug_p = &_Xdebug;
-void (**_XCreateMutex_fn_p)(LockInfoPtr) = &_XCreateMutex_fn;
-void (**_XFreeMutex_fn_p)(LockInfoPtr) = &_XFreeMutex_fn;
-void (**_XLockMutex_fn_p)(LockInfoPtr
-#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
- , char * /* file */
- , int /* line */
-#endif
- ) = &_XLockMutex_fn;
-void (**_XUnlockMutex_fn_p)(LockInfoPtr
-#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
- , char * /* file */
- , int /* line */
-#endif
- ) = &_XUnlockMutex_fn;
-LockInfoPtr *_Xglobal_lock_p = &_Xglobal_lock;
-#endif
+/*
+
+Copyright 1985, 1986, 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * XlibInt.c - Internal support routines for the C subroutine
+ * interface library (Xlib) to the X Window System Protocol V11.0.
+ */
+
+#ifdef WIN32
+#define _XLIBINT_
+#include <X11\Xw32defs.h>
+#endif
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "Xprivate.h"
+#include <X11/Xpoll.h>
+#include <assert.h>
+#include <stdio.h>
+#ifdef WIN32
+#include <direct.h>
+#endif
+
+#ifdef XTHREADS
+#include "locking.h"
+
+/* these pointers get initialized by XInitThreads */
+LockInfoPtr _Xglobal_lock = NULL;
+void (*_XCreateMutex_fn)(LockInfoPtr) = NULL;
+/* struct _XCVList *(*_XCreateCVL_fn)() = NULL; */
+void (*_XFreeMutex_fn)(LockInfoPtr) = NULL;
+void (*_XLockMutex_fn)(
+ LockInfoPtr /* lock */
+#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
+ , char * /* file */
+ , int /* line */
+#endif
+ ) = NULL;
+void (*_XUnlockMutex_fn)(
+ LockInfoPtr /* lock */
+#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
+ , char * /* file */
+ , int /* line */
+#endif
+ ) = NULL;
+xthread_t (*_Xthread_self_fn)(void) = NULL;
+
+#define XThread_Self() ((*_Xthread_self_fn)())
+
+#endif /* XTHREADS */
+
+/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
+ * systems are broken and return EWOULDBLOCK when they should return EAGAIN
+ */
+#ifdef WIN32
+#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK)
+#else
+#ifdef __CYGWIN__ /* Cygwin uses ENOBUFS to signal socket is full */
+#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
+#else
+#if defined(EAGAIN) && defined(EWOULDBLOCK)
+#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK)
+#else
+#ifdef EAGAIN
+#define ETEST() (errno == EAGAIN)
+#else
+#define ETEST() (errno == EWOULDBLOCK)
+#endif /* EAGAIN */
+#endif /* EAGAIN && EWOULDBLOCK */
+#endif /* __CYGWIN__ */
+#endif /* WIN32 */
+
+#ifdef WIN32
+#define ECHECK(err) (WSAGetLastError() == err)
+#define ESET(val) WSASetLastError(val)
+#else
+#ifdef __UNIXOS2__
+#define ECHECK(err) (errno == err)
+#define ESET(val)
+#else
+#define ECHECK(err) (errno == err)
+#define ESET(val) errno = val
+#endif
+#endif
+
+#if defined(LOCALCONN) || defined(LACHMAN)
+#ifdef EMSGSIZE
+#define ESZTEST() (ECHECK(EMSGSIZE) || ECHECK(ERANGE))
+#else
+#define ESZTEST() ECHECK(ERANGE)
+#endif
+#else
+#ifdef EMSGSIZE
+#define ESZTEST() ECHECK(EMSGSIZE)
+#endif
+#endif
+
+#ifdef __UNIXOS2__
+#include <limits.h>
+#define MAX_PATH _POSIX_PATH_MAX
+#endif
+
+/*
+ * The following routines are internal routines used by Xlib for protocol
+ * packet transmission and reception.
+ *
+ * _XIOError(Display *) will be called if any sort of system call error occurs.
+ * This is assumed to be a fatal condition, i.e., XIOError should not return.
+ *
+ * _XError(Display *, xError *) will be called whenever an X_Error event is
+ * received. This is not assumed to be a fatal condition, i.e., it is
+ * acceptable for this procedure to return. However, XError should NOT
+ * perform any operations (directly or indirectly) on the DISPLAY.
+ *
+ * Routines declared with a return type of 'Status' return 0 on failure,
+ * and non 0 on success. Routines with no declared return type don't
+ * return anything. Whenever possible routines that create objects return
+ * the object they have created.
+ */
+
+#define POLLFD_CACHE_SIZE 5
+
+/* initialize the struct array passed to poll() below */
+Bool _XPollfdCacheInit(
+ Display *dpy)
+{
+#ifdef USE_POLL
+ struct pollfd *pfp;
+
+ pfp = (struct pollfd *)Xmalloc(POLLFD_CACHE_SIZE * sizeof(struct pollfd));
+ if (!pfp)
+ return False;
+ pfp[0].fd = dpy->fd;
+ pfp[0].events = POLLIN;
+
+ dpy->filedes = (XPointer)pfp;
+#endif
+ return True;
+}
+
+void _XPollfdCacheAdd(
+ Display *dpy,
+ int fd)
+{
+#ifdef USE_POLL
+ struct pollfd *pfp = (struct pollfd *)dpy->filedes;
+
+ if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) {
+ pfp[dpy->im_fd_length].fd = fd;
+ pfp[dpy->im_fd_length].events = POLLIN;
+ }
+#endif
+}
+
+/* ARGSUSED */
+void _XPollfdCacheDel(
+ Display *dpy,
+ int fd) /* not used */
+{
+#ifdef USE_POLL
+ struct pollfd *pfp = (struct pollfd *)dpy->filedes;
+ struct _XConnectionInfo *conni;
+
+ /* just recalculate whole list */
+ if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) {
+ int loc = 1;
+ for (conni = dpy->im_fd_info; conni; conni=conni->next) {
+ pfp[loc].fd = conni->fd;
+ pfp[loc].events = POLLIN;
+ loc++;
+ }
+ }
+#endif
+}
+
+#ifdef _MSC_VER
+#undef min
+#define min __min
+#endif
+
+static int sync_hazard(Display *dpy)
+{
+ unsigned long span = dpy->request - dpy->last_request_read;
+ unsigned long hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10);
+ return span >= 65535 - hazard - 10;
+}
+
+static
+void sync_while_locked(Display *dpy)
+{
+#ifdef XTHREADS
+ if (dpy->lock)
+ (*dpy->lock->user_lock_display)(dpy);
+#endif
+ UnlockDisplay(dpy);
+ SyncHandle();
+ InternalLockDisplay(dpy, /* don't skip user locks */ 0);
+#ifdef XTHREADS
+ if (dpy->lock)
+ (*dpy->lock->user_unlock_display)(dpy);
+#endif
+}
+
+void _XSeqSyncFunction(
+ register Display *dpy)
+{
+ xGetInputFocusReply rep;
+ register xReq *req;
+
+ if ((dpy->request - dpy->last_request_read) >= (65535 - BUFSIZE/SIZEOF(xReq))) {
+ GetEmptyReq(GetInputFocus, req);
+ (void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
+ sync_while_locked(dpy);
+ } else if (sync_hazard(dpy))
+ _XSetPrivSyncFunction(dpy);
+}
+
+/* NOTE: only called if !XTHREADS, or when XInitThreads wasn't called. */
+static int
+_XPrivSyncFunction (Display *dpy)
+{
+#ifdef XTHREADS
+ assert(!dpy->lock_fns);
+#endif
+ assert(dpy->synchandler == _XPrivSyncFunction);
+ assert((dpy->flags & XlibDisplayPrivSync) != 0);
+ dpy->synchandler = dpy->savedsynchandler;
+ dpy->savedsynchandler = NULL;
+ dpy->flags &= ~XlibDisplayPrivSync;
+ if(dpy->synchandler)
+ dpy->synchandler(dpy);
+ _XIDHandler(dpy);
+ _XSeqSyncFunction(dpy);
+ return 0;
+}
+
+void _XSetPrivSyncFunction(Display *dpy)
+{
+#ifdef XTHREADS
+ if (dpy->lock_fns)
+ return;
+#endif
+ if (!(dpy->flags & XlibDisplayPrivSync)) {
+ dpy->savedsynchandler = dpy->synchandler;
+ dpy->synchandler = _XPrivSyncFunction;
+ dpy->flags |= XlibDisplayPrivSync;
+ }
+}
+
+void _XSetSeqSyncFunction(Display *dpy)
+{
+ if (sync_hazard(dpy))
+ _XSetPrivSyncFunction (dpy);
+}
+
+#ifdef LONG64
+void _XRead32(
+ Display *dpy,
+ register long *data,
+ long len)
+{
+ register int *buf;
+ register long i;
+
+ if (len) {
+ (void) _XRead(dpy, (char *)data, len);
+ i = len >> 2;
+ buf = (int *)data + i;
+ data += i;
+ while (--i >= 0)
+ *--data = *--buf;
+ }
+}
+#endif /* LONG64 */
+
+#ifdef WORD64
+
+/*
+ * XXX This is a *really* stupid way of doing this....
+ * PACKBUFFERSIZE must be a multiple of 4.
+ */
+
+#define PACKBUFFERSIZE 4096
+
+
+/*
+ * _XRead32 - Read bytes from the socket unpacking each 32 bits
+ * into a long (64 bits on a CRAY computer).
+ *
+ */
+static void _doXRead32(
+ register Display *dpy,
+ register long *data
+ register long size,
+ register char *packbuffer)
+{
+ long *lpack,*lp;
+ long mask32 = 0x00000000ffffffff;
+ long maskw, nwords, i, bits;
+
+ _XReadPad (dpy, packbuffer, size);
+
+ lp = data;
+ lpack = (long *) packbuffer;
+ nwords = size >> 2;
+ bits = 32;
+
+ for(i=0;i<nwords;i++){
+ maskw = mask32 << bits;
+ *lp++ = ( *lpack & maskw ) >> bits;
+ bits = bits ^32;
+ if(bits){
+ lpack++;
+ }
+ }
+}
+
+void _XRead32(
+ Display *dpy,
+ long *data,
+ long len)
+{
+ char packbuffer[PACKBUFFERSIZE];
+ unsigned nunits = PACKBUFFERSIZE >> 2;
+
+ for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
+ _doXRead32 (dpy, data, PACKBUFFERSIZE, packbuffer);
+ }
+ if (len) _doXRead32 (dpy, data, len, packbuffer);
+}
+
+
+
+/*
+ * _XRead16 - Read bytes from the socket unpacking each 16 bits
+ * into a long (64 bits on a CRAY computer).
+ *
+ */
+static _doXRead16(
+ register Display *dpy,
+ register short *data,
+ register long size,
+ char *packbuffer)
+{
+ long *lpack,*lp;
+ long mask16 = 0x000000000000ffff;
+ long maskw, nwords, i, bits;
+
+ (void) _XRead(dpy,packbuffer,size); /* don't do a padded read... */
+
+ lp = (long *) data;
+ lpack = (long *) packbuffer;
+ nwords = size >> 1; /* number of 16 bit words to be unpacked */
+ bits = 48;
+ for(i=0;i<nwords;i++){
+ maskw = mask16 << bits;
+ *lp++ = ( *lpack & maskw ) >> bits;
+ bits -= 16;
+ if(bits < 0){
+ lpack++;
+ bits = 48;
+ }
+ }
+}
+
+void _XRead16(
+ Display *dpy,
+ short *data,
+ long len)
+{
+ char packbuffer[PACKBUFFERSIZE];
+ unsigned nunits = PACKBUFFERSIZE >> 1;
+
+ for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
+ _doXRead16 (dpy, data, PACKBUFFERSIZE, packbuffer);
+ }
+ if (len) _doXRead16 (dpy, data, len, packbuffer);
+}
+
+void _XRead16Pad(
+ Display *dpy,
+ short *data,
+ long size)
+{
+ int slop = (size & 3);
+ short slopbuf[3];
+
+ _XRead16 (dpy, data, size);
+ if (slop > 0) {
+ _XRead16 (dpy, slopbuf, 4 - slop);
+ }
+}
+#endif /* WORD64 */
+
+/*
+ * The hard part about this is that we only get 16 bits from a reply.
+ * We have three values that will march along, with the following invariant:
+ * dpy->last_request_read <= rep->sequenceNumber <= dpy->request
+ * We have to keep
+ * dpy->request - dpy->last_request_read < 2^16
+ * or else we won't know for sure what value to use in events. We do this
+ * by forcing syncs when we get close.
+ */
+
+unsigned long
+_XSetLastRequestRead(
+ register Display *dpy,
+ register xGenericReply *rep)
+{
+ register unsigned long newseq, lastseq;
+
+ lastseq = dpy->last_request_read;
+ /*
+ * KeymapNotify has no sequence number, but is always guaranteed
+ * to immediately follow another event, except when generated via
+ * SendEvent (hmmm).
+ */
+ if ((rep->type & 0x7f) == KeymapNotify)
+ return(lastseq);
+
+ newseq = (lastseq & ~((unsigned long)0xffff)) | rep->sequenceNumber;
+
+ if (newseq < lastseq) {
+ newseq += 0x10000;
+ if (newseq > dpy->request) {
+ (void) fprintf (stderr,
+ "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n",
+ newseq, dpy->request,
+ (unsigned int) rep->type);
+ newseq -= 0x10000;
+ }
+ }
+
+ dpy->last_request_read = newseq;
+ return(newseq);
+}
+
+/*
+ * Support for internal connections, such as an IM might use.
+ * By Stephen Gildea, X Consortium, September 1993
+ */
+
+/* _XRegisterInternalConnection
+ * Each IM (or Xlib extension) that opens a file descriptor that Xlib should
+ * include in its select/poll mask must call this function to register the
+ * fd with Xlib. Any XConnectionWatchProc registered by XAddConnectionWatch
+ * will also be called.
+ *
+ * Whenever Xlib detects input available on fd, it will call callback
+ * with call_data to process it. If non-Xlib code calls select/poll
+ * and detects input available, it must call XProcessInternalConnection,
+ * which will call the associated callback.
+ *
+ * Non-Xlib code can learn about these additional fds by calling
+ * XInternalConnectionNumbers or, more typically, by registering
+ * a XConnectionWatchProc with XAddConnectionWatch
+ * to be called when fds are registered or unregistered.
+ *
+ * Returns True if registration succeeded, False if not, typically
+ * because could not allocate memory.
+ * Assumes Display locked when called.
+ */
+Status
+_XRegisterInternalConnection(
+ Display* dpy,
+ int fd,
+ _XInternalConnectionProc callback,
+ XPointer call_data
+)
+{
+ struct _XConnectionInfo *new_conni, **iptr;
+ struct _XConnWatchInfo *watchers;
+ XPointer *wd;
+
+ new_conni = (struct _XConnectionInfo*)Xmalloc(sizeof(struct _XConnectionInfo));
+ if (!new_conni)
+ return 0;
+ new_conni->watch_data = (XPointer *)Xmalloc(dpy->watcher_count * sizeof(XPointer));
+ if (!new_conni->watch_data) {
+ Xfree(new_conni);
+ return 0;
+ }
+ new_conni->fd = fd;
+ new_conni->read_callback = callback;
+ new_conni->call_data = call_data;
+ new_conni->next = NULL;
+ /* link new structure onto end of list */
+ for (iptr = &dpy->im_fd_info; *iptr; iptr = &(*iptr)->next)
+ ;
+ *iptr = new_conni;
+ dpy->im_fd_length++;
+ _XPollfdCacheAdd(dpy, fd);
+
+ for (watchers=dpy->conn_watchers, wd=new_conni->watch_data;
+ watchers;
+ watchers=watchers->next, wd++) {
+ *wd = NULL; /* for cleanliness */
+ (*watchers->fn) (dpy, watchers->client_data, fd, True, wd);
+ }
+
+ return 1;
+}
+
+/* _XUnregisterInternalConnection
+ * Each IM (or Xlib extension) that closes a file descriptor previously
+ * registered with _XRegisterInternalConnection must call this function.
+ * Any XConnectionWatchProc registered by XAddConnectionWatch
+ * will also be called.
+ *
+ * Assumes Display locked when called.
+ */
+void
+_XUnregisterInternalConnection(
+ Display* dpy,
+ int fd
+)
+{
+ struct _XConnectionInfo *info_list, **prev;
+ struct _XConnWatchInfo *watch;
+ XPointer *wd;
+
+ for (prev = &dpy->im_fd_info; (info_list = *prev);
+ prev = &info_list->next) {
+ if (info_list->fd == fd) {
+ *prev = info_list->next;
+ dpy->im_fd_length--;
+ for (watch=dpy->conn_watchers, wd=info_list->watch_data;
+ watch;
+ watch=watch->next, wd++) {
+ (*watch->fn) (dpy, watch->client_data, fd, False, wd);
+ }
+ if (info_list->watch_data)
+ Xfree (info_list->watch_data);
+ Xfree (info_list);
+ break;
+ }
+ }
+ _XPollfdCacheDel(dpy, fd);
+}
+
+/* XInternalConnectionNumbers
+ * Returns an array of fds and an array of corresponding call data.
+ * Typically a XConnectionWatchProc registered with XAddConnectionWatch
+ * will be used instead of this function to discover
+ * additional fds to include in the select/poll mask.
+ *
+ * The list is allocated with Xmalloc and should be freed by the caller
+ * with Xfree;
+ */
+Status
+XInternalConnectionNumbers(
+ Display *dpy,
+ int **fd_return,
+ int *count_return
+)
+{
+ int count;
+ struct _XConnectionInfo *info_list;
+ int *fd_list;
+
+ LockDisplay(dpy);
+ count = 0;
+ for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next)
+ count++;
+ fd_list = (int*) Xmalloc (count * sizeof(int));
+ if (!fd_list) {
+ UnlockDisplay(dpy);
+ return 0;
+ }
+ count = 0;
+ for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
+ fd_list[count] = info_list->fd;
+ count++;
+ }
+ UnlockDisplay(dpy);
+
+ *fd_return = fd_list;
+ *count_return = count;
+ return 1;
+}
+
+void _XProcessInternalConnection(
+ Display *dpy,
+ struct _XConnectionInfo *conn_info)
+{
+ dpy->flags |= XlibDisplayProcConni;
+ UnlockDisplay(dpy);
+ (*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data);
+ LockDisplay(dpy);
+ dpy->flags &= ~XlibDisplayProcConni;
+}
+
+/* XProcessInternalConnection
+ * Call the _XInternalConnectionProc registered by _XRegisterInternalConnection
+ * for this fd.
+ * The Display is NOT locked during the call.
+ */
+void
+XProcessInternalConnection(
+ Display* dpy,
+ int fd
+)
+{
+ struct _XConnectionInfo *info_list;
+
+ LockDisplay(dpy);
+ for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
+ if (info_list->fd == fd) {
+ _XProcessInternalConnection(dpy, info_list);
+ break;
+ }
+ }
+ UnlockDisplay(dpy);
+}
+
+/* XAddConnectionWatch
+ * Register a callback to be called whenever _XRegisterInternalConnection
+ * or _XUnregisterInternalConnection is called.
+ * Callbacks are called with the Display locked.
+ * If any connections are already registered, the callback is immediately
+ * called for each of them.
+ */
+Status
+XAddConnectionWatch(
+ Display* dpy,
+ XConnectionWatchProc callback,
+ XPointer client_data
+)
+{
+ struct _XConnWatchInfo *new_watcher, **wptr;
+ struct _XConnectionInfo *info_list;
+ XPointer *wd_array;
+
+ LockDisplay(dpy);
+
+ /* allocate new watch data */
+ for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
+ wd_array = (XPointer *)Xrealloc((char *)info_list->watch_data,
+ (dpy->watcher_count + 1) *
+ sizeof(XPointer));
+ if (!wd_array) {
+ UnlockDisplay(dpy);
+ return 0;
+ }
+ wd_array[dpy->watcher_count] = NULL; /* for cleanliness */
+ }
+
+ new_watcher = (struct _XConnWatchInfo*)Xmalloc(sizeof(struct _XConnWatchInfo));
+ if (!new_watcher) {
+ UnlockDisplay(dpy);
+ return 0;
+ }
+ new_watcher->fn = callback;
+ new_watcher->client_data = client_data;
+ new_watcher->next = NULL;
+
+ /* link new structure onto end of list */
+ for (wptr = &dpy->conn_watchers; *wptr; wptr = &(*wptr)->next)
+ ;
+ *wptr = new_watcher;
+ dpy->watcher_count++;
+
+ /* call new watcher on all currently registered fds */
+ for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
+ (*callback) (dpy, client_data, info_list->fd, True,
+ info_list->watch_data + dpy->watcher_count - 1);
+ }
+
+ UnlockDisplay(dpy);
+ return 1;
+}
+
+/* XRemoveConnectionWatch
+ * Unregister a callback registered by XAddConnectionWatch.
+ * Both callback and client_data must match what was passed to
+ * XAddConnectionWatch.
+ */
+void
+XRemoveConnectionWatch(
+ Display* dpy,
+ XConnectionWatchProc callback,
+ XPointer client_data
+)
+{
+ struct _XConnWatchInfo *watch;
+ struct _XConnWatchInfo *previous = NULL;
+ struct _XConnectionInfo *conni;
+ int counter = 0;
+
+ LockDisplay(dpy);
+ for (watch=dpy->conn_watchers; watch; watch=watch->next) {
+ if (watch->fn == callback && watch->client_data == client_data) {
+ if (previous)
+ previous->next = watch->next;
+ else
+ dpy->conn_watchers = watch->next;
+ Xfree (watch);
+ dpy->watcher_count--;
+ /* remove our watch_data for each connection */
+ for (conni=dpy->im_fd_info; conni; conni=conni->next) {
+ /* don't bother realloc'ing; these arrays are small anyway */
+ /* overlapping */
+ memmove(conni->watch_data+counter,
+ conni->watch_data+counter+1,
+ dpy->watcher_count - counter);
+ }
+ break;
+ }
+ previous = watch;
+ counter++;
+ }
+ UnlockDisplay(dpy);
+}
+
+/* end of internal connections support */
+
+/* Cookie jar implementation
+ dpy->cookiejar is a linked list. _XEnq receives the events but leaves
+ them in the normal EQ. _XStoreEvent returns the cookie event (minus
+ data pointer) and adds it to the cookiejar. _XDeq just removes
+ the entry like any other event but resets the data pointer for
+ cookie events (to avoid double-free, the memory is re-used by Xlib).
+
+ _XFetchEventCookie (called from XGetEventData) removes a cookie from the
+ jar. _XFreeEventCookies removes all unclaimed cookies from the jar
+ (called by XNextEvent).
+
+ _XFreeDisplayStructure calls _XFreeEventCookies for each cookie in the
+ normal EQ.
+ */
+
+#include "utlist.h"
+struct stored_event {
+ XGenericEventCookie ev;
+ struct stored_event *prev;
+ struct stored_event *next;
+};
+
+Bool
+_XIsEventCookie(Display *dpy, XEvent *ev)
+{
+ return (ev->xcookie.type == GenericEvent &&
+ dpy->generic_event_vec[ev->xcookie.extension & 0x7F] != NULL);
+}
+
+/**
+ * Free all events in the event list.
+ */
+void
+_XFreeEventCookies(Display *dpy)
+{
+ struct stored_event **head, *e, *tmp;
+
+ if (!dpy->cookiejar)
+ return;
+
+ head = (struct stored_event**)&dpy->cookiejar;
+
+ DL_FOREACH_SAFE(*head, e, tmp) {
+ if (dpy->cookiejar == e)
+ dpy->cookiejar = NULL;
+ XFree(e->ev.data);
+ XFree(e);
+ }
+}
+
+/**
+ * Add an event to the display's event list. This event must be freed on the
+ * next call to XNextEvent().
+ */
+void
+_XStoreEventCookie(Display *dpy, XEvent *event)
+{
+ XGenericEventCookie* cookie = &event->xcookie;
+ struct stored_event **head, *add;
+
+ if (!_XIsEventCookie(dpy, event))
+ return;
+
+ head = (struct stored_event**)(&dpy->cookiejar);
+
+ add = Xmalloc(sizeof(struct stored_event));
+ if (!add) {
+ ESET(ENOMEM);
+ _XIOError(dpy);
+ }
+ add->ev = *cookie;
+ DL_APPEND(*head, add);
+ cookie->data = NULL; /* don't return data yet, must be claimed */
+}
+
+/**
+ * Return the event with the given cookie and remove it from the list.
+ */
+Bool
+_XFetchEventCookie(Display *dpy, XGenericEventCookie* ev)
+{
+ Bool ret = False;
+ struct stored_event **head, *event;
+ head = (struct stored_event**)&dpy->cookiejar;
+
+ if (!_XIsEventCookie(dpy, (XEvent*)ev))
+ return ret;
+
+ DL_FOREACH(*head, event) {
+ if (event->ev.cookie == ev->cookie &&
+ event->ev.extension == ev->extension &&
+ event->ev.evtype == ev->evtype) {
+ *ev = event->ev;
+ DL_DELETE(*head, event);
+ Xfree(event);
+ ret = True;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+Bool
+_XCopyEventCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out)
+{
+ Bool ret = False;
+ int extension;
+
+ if (!_XIsEventCookie(dpy, (XEvent*)in) || !out)
+ return ret;
+
+ extension = in->extension & 0x7F;
+
+ if (!dpy->generic_event_copy_vec[extension])
+ return ret;
+
+ ret = ((*dpy->generic_event_copy_vec[extension])(dpy, in, out));
+ out->cookie = ret ? ++dpy->next_cookie : 0;
+ return ret;
+}
+
+
+/*
+ * _XEnq - Place event packets on the display's queue.
+ * note that no squishing of move events in V11, since there
+ * is pointer motion hints....
+ */
+void _XEnq(
+ register Display *dpy,
+ register xEvent *event)
+{
+ register _XQEvent *qelt;
+ int type, extension;
+
+ if ((qelt = dpy->qfree)) {
+ /* If dpy->qfree is non-NULL do this, else malloc a new one. */
+ dpy->qfree = qelt->next;
+ }
+ else if ((qelt =
+ (_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) {
+ /* Malloc call failed! */
+ ESET(ENOMEM);
+ _XIOError(dpy);
+ }
+ qelt->next = NULL;
+
+ type = event->u.u.type & 0177;
+ extension = ((xGenericEvent*)event)->extension;
+
+ qelt->event.type = type;
+ /* If an extension has registerd a generic_event_vec handler, then
+ * it can handle event cookies. Otherwise, proceed with the normal
+ * event handlers.
+ *
+ * If the generic_event_vec is called, qelt->event is a event cookie
+ * with the data pointer and the "free" pointer set. Data pointer is
+ * some memory allocated by the extension.
+ */
+ if (type == GenericEvent && dpy->generic_event_vec[extension & 0x7F]) {
+ XGenericEventCookie *cookie = &qelt->event.xcookie;
+ (*dpy->generic_event_vec[extension & 0x7F])(dpy, cookie, event);
+ cookie->cookie = ++dpy->next_cookie;
+
+ qelt->qserial_num = dpy->next_event_serial_num++;
+ if (dpy->tail) dpy->tail->next = qelt;
+ else dpy->head = qelt;
+
+ dpy->tail = qelt;
+ dpy->qlen++;
+ } else if ((*dpy->event_vec[type])(dpy, &qelt->event, event)) {
+ qelt->qserial_num = dpy->next_event_serial_num++;
+ if (dpy->tail) dpy->tail->next = qelt;
+ else dpy->head = qelt;
+
+ dpy->tail = qelt;
+ dpy->qlen++;
+ } else {
+ /* ignored, or stashed away for many-to-one compression */
+ qelt->next = dpy->qfree;
+ dpy->qfree = qelt;
+ }
+}
+
+/*
+ * _XDeq - Remove event packet from the display's queue.
+ */
+void _XDeq(
+ register Display *dpy,
+ register _XQEvent *prev, /* element before qelt */
+ register _XQEvent *qelt) /* element to be unlinked */
+{
+ if (prev) {
+ if ((prev->next = qelt->next) == NULL)
+ dpy->tail = prev;
+ } else {
+ /* no prev, so removing first elt */
+ if ((dpy->head = qelt->next) == NULL)
+ dpy->tail = NULL;
+ }
+ qelt->qserial_num = 0;
+ qelt->next = dpy->qfree;
+ dpy->qfree = qelt;
+ dpy->qlen--;
+
+ if (_XIsEventCookie(dpy, &qelt->event)) {
+ XGenericEventCookie* cookie = &qelt->event.xcookie;
+ /* dpy->qfree is re-used, reset memory to avoid double free on
+ * _XFreeDisplayStructure */
+ cookie->data = NULL;
+ }
+}
+
+/*
+ * EventToWire in separate file in that often not needed.
+ */
+
+/*ARGSUSED*/
+Bool
+_XUnknownWireEvent(
+ register Display *dpy, /* pointer to display structure */
+ register XEvent *re, /* pointer to where event should be reformatted */
+ register xEvent *event) /* wire protocol event */
+{
+#ifdef notdef
+ (void) fprintf(stderr,
+ "Xlib: unhandled wire event! event number = %d, display = %x\n.",
+ event->u.u.type, dpy);
+#endif
+ return(False);
+}
+
+Bool
+_XUnknownWireEventCookie(
+ Display *dpy, /* pointer to display structure */
+ XGenericEventCookie *re, /* pointer to where event should be reformatted */
+ xEvent *event) /* wire protocol event */
+{
+#ifdef notdef
+ fprintf(stderr,
+ "Xlib: unhandled wire cookie event! extension number = %d, display = %x\n.",
+ ((xGenericEvent*)event)->extension, dpy);
+#endif
+ return(False);
+}
+
+Bool
+_XUnknownCopyEventCookie(
+ Display *dpy, /* pointer to display structure */
+ XGenericEventCookie *in, /* source */
+ XGenericEventCookie *out) /* destination */
+{
+#ifdef notdef
+ fprintf(stderr,
+ "Xlib: unhandled cookie event copy! extension number = %d, display = %x\n.",
+ in->extension, dpy);
+#endif
+ return(False);
+}
+
+/*ARGSUSED*/
+Status
+_XUnknownNativeEvent(
+ register Display *dpy, /* pointer to display structure */
+ register XEvent *re, /* pointer to where event should be reformatted */
+ register xEvent *event) /* wire protocol event */
+{
+#ifdef notdef
+ (void) fprintf(stderr,
+ "Xlib: unhandled native event! event number = %d, display = %x\n.",
+ re->type, dpy);
+#endif
+ return(0);
+}
+/*
+ * reformat a wire event into an XEvent structure of the right type.
+ */
+Bool
+_XWireToEvent(
+ register Display *dpy, /* pointer to display structure */
+ register XEvent *re, /* pointer to where event should be reformatted */
+ register xEvent *event) /* wire protocol event */
+{
+
+ re->type = event->u.u.type & 0x7f;
+ ((XAnyEvent *)re)->serial = _XSetLastRequestRead(dpy,
+ (xGenericReply *)event);
+ ((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0);
+ ((XAnyEvent *)re)->display = dpy;
+
+ /* Ignore the leading bit of the event type since it is set when a
+ client sends an event rather than the server. */
+
+ switch (event-> u.u.type & 0177) {
+ case KeyPress:
+ case KeyRelease:
+ {
+ register XKeyEvent *ev = (XKeyEvent*) re;
+ ev->root = event->u.keyButtonPointer.root;
+ ev->window = event->u.keyButtonPointer.event;
+ ev->subwindow = event->u.keyButtonPointer.child;
+ ev->time = event->u.keyButtonPointer.time;
+ ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX);
+ ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY);
+ ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX);
+ ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY);
+ ev->state = event->u.keyButtonPointer.state;
+ ev->same_screen = event->u.keyButtonPointer.sameScreen;
+ ev->keycode = event->u.u.detail;
+ }
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ {
+ register XButtonEvent *ev = (XButtonEvent *) re;
+ ev->root = event->u.keyButtonPointer.root;
+ ev->window = event->u.keyButtonPointer.event;
+ ev->subwindow = event->u.keyButtonPointer.child;
+ ev->time = event->u.keyButtonPointer.time;
+ ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX);
+ ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY);
+ ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX);
+ ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY);
+ ev->state = event->u.keyButtonPointer.state;
+ ev->same_screen = event->u.keyButtonPointer.sameScreen;
+ ev->button = event->u.u.detail;
+ }
+ break;
+ case MotionNotify:
+ {
+ register XMotionEvent *ev = (XMotionEvent *)re;
+ ev->root = event->u.keyButtonPointer.root;
+ ev->window = event->u.keyButtonPointer.event;
+ ev->subwindow = event->u.keyButtonPointer.child;
+ ev->time = event->u.keyButtonPointer.time;
+ ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX);
+ ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY);
+ ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX);
+ ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY);
+ ev->state = event->u.keyButtonPointer.state;
+ ev->same_screen = event->u.keyButtonPointer.sameScreen;
+ ev->is_hint = event->u.u.detail;
+ }
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ {
+ register XCrossingEvent *ev = (XCrossingEvent *) re;
+ ev->root = event->u.enterLeave.root;
+ ev->window = event->u.enterLeave.event;
+ ev->subwindow = event->u.enterLeave.child;
+ ev->time = event->u.enterLeave.time;
+ ev->x = cvtINT16toInt(event->u.enterLeave.eventX);
+ ev->y = cvtINT16toInt(event->u.enterLeave.eventY);
+ ev->x_root = cvtINT16toInt(event->u.enterLeave.rootX);
+ ev->y_root = cvtINT16toInt(event->u.enterLeave.rootY);
+ ev->state = event->u.enterLeave.state;
+ ev->mode = event->u.enterLeave.mode;
+ ev->same_screen = (event->u.enterLeave.flags &
+ ELFlagSameScreen) && True;
+ ev->focus = (event->u.enterLeave.flags &
+ ELFlagFocus) && True;
+ ev->detail = event->u.u.detail;
+ }
+ break;
+ case FocusIn:
+ case FocusOut:
+ {
+ register XFocusChangeEvent *ev = (XFocusChangeEvent *) re;
+ ev->window = event->u.focus.window;
+ ev->mode = event->u.focus.mode;
+ ev->detail = event->u.u.detail;
+ }
+ break;
+ case KeymapNotify:
+ {
+ register XKeymapEvent *ev = (XKeymapEvent *) re;
+ ev->window = None;
+ memcpy(&ev->key_vector[1],
+ (char *)((xKeymapEvent *) event)->map,
+ sizeof (((xKeymapEvent *) event)->map));
+ }
+ break;
+ case Expose:
+ {
+ register XExposeEvent *ev = (XExposeEvent *) re;
+ ev->window = event->u.expose.window;
+ ev->x = event->u.expose.x;
+ ev->y = event->u.expose.y;
+ ev->width = event->u.expose.width;
+ ev->height = event->u.expose.height;
+ ev->count = event->u.expose.count;
+ }
+ break;
+ case GraphicsExpose:
+ {
+ register XGraphicsExposeEvent *ev =
+ (XGraphicsExposeEvent *) re;
+ ev->drawable = event->u.graphicsExposure.drawable;
+ ev->x = event->u.graphicsExposure.x;
+ ev->y = event->u.graphicsExposure.y;
+ ev->width = event->u.graphicsExposure.width;
+ ev->height = event->u.graphicsExposure.height;
+ ev->count = event->u.graphicsExposure.count;
+ ev->major_code = event->u.graphicsExposure.majorEvent;
+ ev->minor_code = event->u.graphicsExposure.minorEvent;
+ }
+ break;
+ case NoExpose:
+ {
+ register XNoExposeEvent *ev = (XNoExposeEvent *) re;
+ ev->drawable = event->u.noExposure.drawable;
+ ev->major_code = event->u.noExposure.majorEvent;
+ ev->minor_code = event->u.noExposure.minorEvent;
+ }
+ break;
+ case VisibilityNotify:
+ {
+ register XVisibilityEvent *ev = (XVisibilityEvent *) re;
+ ev->window = event->u.visibility.window;
+ ev->state = event->u.visibility.state;
+ }
+ break;
+ case CreateNotify:
+ {
+ register XCreateWindowEvent *ev =
+ (XCreateWindowEvent *) re;
+ ev->window = event->u.createNotify.window;
+ ev->parent = event->u.createNotify.parent;
+ ev->x = cvtINT16toInt(event->u.createNotify.x);
+ ev->y = cvtINT16toInt(event->u.createNotify.y);
+ ev->width = event->u.createNotify.width;
+ ev->height = event->u.createNotify.height;
+ ev->border_width = event->u.createNotify.borderWidth;
+ ev->override_redirect = event->u.createNotify.override;
+ }
+ break;
+ case DestroyNotify:
+ {
+ register XDestroyWindowEvent *ev =
+ (XDestroyWindowEvent *) re;
+ ev->window = event->u.destroyNotify.window;
+ ev->event = event->u.destroyNotify.event;
+ }
+ break;
+ case UnmapNotify:
+ {
+ register XUnmapEvent *ev = (XUnmapEvent *) re;
+ ev->window = event->u.unmapNotify.window;
+ ev->event = event->u.unmapNotify.event;
+ ev->from_configure = event->u.unmapNotify.fromConfigure;
+ }
+ break;
+ case MapNotify:
+ {
+ register XMapEvent *ev = (XMapEvent *) re;
+ ev->window = event->u.mapNotify.window;
+ ev->event = event->u.mapNotify.event;
+ ev->override_redirect = event->u.mapNotify.override;
+ }
+ break;
+ case MapRequest:
+ {
+ register XMapRequestEvent *ev = (XMapRequestEvent *) re;
+ ev->window = event->u.mapRequest.window;
+ ev->parent = event->u.mapRequest.parent;
+ }
+ break;
+ case ReparentNotify:
+ {
+ register XReparentEvent *ev = (XReparentEvent *) re;
+ ev->event = event->u.reparent.event;
+ ev->window = event->u.reparent.window;
+ ev->parent = event->u.reparent.parent;
+ ev->x = cvtINT16toInt(event->u.reparent.x);
+ ev->y = cvtINT16toInt(event->u.reparent.y);
+ ev->override_redirect = event->u.reparent.override;
+ }
+ break;
+ case ConfigureNotify:
+ {
+ register XConfigureEvent *ev = (XConfigureEvent *) re;
+ ev->event = event->u.configureNotify.event;
+ ev->window = event->u.configureNotify.window;
+ ev->above = event->u.configureNotify.aboveSibling;
+ ev->x = cvtINT16toInt(event->u.configureNotify.x);
+ ev->y = cvtINT16toInt(event->u.configureNotify.y);
+ ev->width = event->u.configureNotify.width;
+ ev->height = event->u.configureNotify.height;
+ ev->border_width = event->u.configureNotify.borderWidth;
+ ev->override_redirect = event->u.configureNotify.override;
+ }
+ break;
+ case ConfigureRequest:
+ {
+ register XConfigureRequestEvent *ev =
+ (XConfigureRequestEvent *) re;
+ ev->window = event->u.configureRequest.window;
+ ev->parent = event->u.configureRequest.parent;
+ ev->above = event->u.configureRequest.sibling;
+ ev->x = cvtINT16toInt(event->u.configureRequest.x);
+ ev->y = cvtINT16toInt(event->u.configureRequest.y);
+ ev->width = event->u.configureRequest.width;
+ ev->height = event->u.configureRequest.height;
+ ev->border_width = event->u.configureRequest.borderWidth;
+ ev->value_mask = event->u.configureRequest.valueMask;
+ ev->detail = event->u.u.detail;
+ }
+ break;
+ case GravityNotify:
+ {
+ register XGravityEvent *ev = (XGravityEvent *) re;
+ ev->window = event->u.gravity.window;
+ ev->event = event->u.gravity.event;
+ ev->x = cvtINT16toInt(event->u.gravity.x);
+ ev->y = cvtINT16toInt(event->u.gravity.y);
+ }
+ break;
+ case ResizeRequest:
+ {
+ register XResizeRequestEvent *ev =
+ (XResizeRequestEvent *) re;
+ ev->window = event->u.resizeRequest.window;
+ ev->width = event->u.resizeRequest.width;
+ ev->height = event->u.resizeRequest.height;
+ }
+ break;
+ case CirculateNotify:
+ {
+ register XCirculateEvent *ev = (XCirculateEvent *) re;
+ ev->window = event->u.circulate.window;
+ ev->event = event->u.circulate.event;
+ ev->place = event->u.circulate.place;
+ }
+ break;
+ case CirculateRequest:
+ {
+ register XCirculateRequestEvent *ev =
+ (XCirculateRequestEvent *) re;
+ ev->window = event->u.circulate.window;
+ ev->parent = event->u.circulate.event;
+ ev->place = event->u.circulate.place;
+ }
+ break;
+ case PropertyNotify:
+ {
+ register XPropertyEvent *ev = (XPropertyEvent *) re;
+ ev->window = event->u.property.window;
+ ev->atom = event->u.property.atom;
+ ev->time = event->u.property.time;
+ ev->state = event->u.property.state;
+ }
+ break;
+ case SelectionClear:
+ {
+ register XSelectionClearEvent *ev =
+ (XSelectionClearEvent *) re;
+ ev->window = event->u.selectionClear.window;
+ ev->selection = event->u.selectionClear.atom;
+ ev->time = event->u.selectionClear.time;
+ }
+ break;
+ case SelectionRequest:
+ {
+ register XSelectionRequestEvent *ev =
+ (XSelectionRequestEvent *) re;
+ ev->owner = event->u.selectionRequest.owner;
+ ev->requestor = event->u.selectionRequest.requestor;
+ ev->selection = event->u.selectionRequest.selection;
+ ev->target = event->u.selectionRequest.target;
+ ev->property = event->u.selectionRequest.property;
+ ev->time = event->u.selectionRequest.time;
+ }
+ break;
+ case SelectionNotify:
+ {
+ register XSelectionEvent *ev = (XSelectionEvent *) re;
+ ev->requestor = event->u.selectionNotify.requestor;
+ ev->selection = event->u.selectionNotify.selection;
+ ev->target = event->u.selectionNotify.target;
+ ev->property = event->u.selectionNotify.property;
+ ev->time = event->u.selectionNotify.time;
+ }
+ break;
+ case ColormapNotify:
+ {
+ register XColormapEvent *ev = (XColormapEvent *) re;
+ ev->window = event->u.colormap.window;
+ ev->colormap = event->u.colormap.colormap;
+ ev->new = event->u.colormap.new;
+ ev->state = event->u.colormap.state;
+ }
+ break;
+ case ClientMessage:
+ {
+ register int i;
+ register XClientMessageEvent *ev
+ = (XClientMessageEvent *) re;
+ ev->window = event->u.clientMessage.window;
+ ev->format = event->u.u.detail;
+ switch (ev->format) {
+ case 8:
+ ev->message_type = event->u.clientMessage.u.b.type;
+ for (i = 0; i < 20; i++)
+ ev->data.b[i] = event->u.clientMessage.u.b.bytes[i];
+ break;
+ case 16:
+ ev->message_type = event->u.clientMessage.u.s.type;
+ ev->data.s[0] = cvtINT16toShort(event->u.clientMessage.u.s.shorts0);
+ ev->data.s[1] = cvtINT16toShort(event->u.clientMessage.u.s.shorts1);
+ ev->data.s[2] = cvtINT16toShort(event->u.clientMessage.u.s.shorts2);
+ ev->data.s[3] = cvtINT16toShort(event->u.clientMessage.u.s.shorts3);
+ ev->data.s[4] = cvtINT16toShort(event->u.clientMessage.u.s.shorts4);
+ ev->data.s[5] = cvtINT16toShort(event->u.clientMessage.u.s.shorts5);
+ ev->data.s[6] = cvtINT16toShort(event->u.clientMessage.u.s.shorts6);
+ ev->data.s[7] = cvtINT16toShort(event->u.clientMessage.u.s.shorts7);
+ ev->data.s[8] = cvtINT16toShort(event->u.clientMessage.u.s.shorts8);
+ ev->data.s[9] = cvtINT16toShort(event->u.clientMessage.u.s.shorts9);
+ break;
+ case 32:
+ ev->message_type = event->u.clientMessage.u.l.type;
+ ev->data.l[0] = cvtINT32toLong(event->u.clientMessage.u.l.longs0);
+ ev->data.l[1] = cvtINT32toLong(event->u.clientMessage.u.l.longs1);
+ ev->data.l[2] = cvtINT32toLong(event->u.clientMessage.u.l.longs2);
+ ev->data.l[3] = cvtINT32toLong(event->u.clientMessage.u.l.longs3);
+ ev->data.l[4] = cvtINT32toLong(event->u.clientMessage.u.l.longs4);
+ break;
+ default: /* XXX should never occur */
+ break;
+ }
+ }
+ break;
+ case MappingNotify:
+ {
+ register XMappingEvent *ev = (XMappingEvent *)re;
+ ev->window = 0;
+ ev->first_keycode = event->u.mappingNotify.firstKeyCode;
+ ev->request = event->u.mappingNotify.request;
+ ev->count = event->u.mappingNotify.count;
+ }
+ break;
+ default:
+ return(_XUnknownWireEvent(dpy, re, event));
+ }
+ return(True);
+}
+
+
+/*
+ * _XDefaultIOError - Default fatal system error reporting routine. Called
+ * when an X internal system error is encountered.
+ */
+int _XDefaultIOError(
+ Display *dpy)
+{
+ if (ECHECK(EPIPE)) {
+ (void) fprintf (stderr,
+ "X connection to %s broken (explicit kill or server shutdown).\r\n",
+ DisplayString (dpy));
+ } else {
+ (void) fprintf (stderr,
+ "XIO: fatal IO error %d (%s) on X server \"%s\"\r\n",
+#ifdef WIN32
+ WSAGetLastError(), strerror(WSAGetLastError()),
+#else
+ errno, strerror (errno),
+#endif
+ DisplayString (dpy));
+ (void) fprintf (stderr,
+ " after %lu requests (%lu known processed) with %d events remaining.\r\n",
+ NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy),
+ QLength(dpy));
+
+ }
+ exit(1);
+ return(0); /* dummy - function should never return */
+}
+
+
+static int _XPrintDefaultError(
+ Display *dpy,
+ XErrorEvent *event,
+ FILE *fp)
+{
+ char buffer[BUFSIZ];
+ char mesg[BUFSIZ];
+ char number[32];
+ const char *mtype = "XlibMessage";
+ register _XExtension *ext = (_XExtension *)NULL;
+ _XExtension *bext = (_XExtension *)NULL;
+ XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
+ XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
+ (void) fprintf(fp, "%s: %s\n ", mesg, buffer);
+ XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
+ mesg, BUFSIZ);
+ (void) fprintf(fp, mesg, event->request_code);
+ if (event->request_code < 128) {
+ sprintf(number, "%d", event->request_code);
+ XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
+ } else {
+ for (ext = dpy->ext_procs;
+ ext && (ext->codes.major_opcode != event->request_code);
+ ext = ext->next)
+ ;
+ if (ext)
+ strcpy(buffer, ext->name);
+ else
+ buffer[0] = '\0';
+ }
+ (void) fprintf(fp, " (%s)\n", buffer);
+ if (event->request_code >= 128) {
+ XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
+ mesg, BUFSIZ);
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->minor_code);
+ if (ext) {
+ sprintf(mesg, "%s.%d", ext->name, event->minor_code);
+ XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
+ (void) fprintf(fp, " (%s)", buffer);
+ }
+ fputs("\n", fp);
+ }
+ if (event->error_code >= 128) {
+ /* kludge, try to find the extension that caused it */
+ buffer[0] = '\0';
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->error_string)
+ (*ext->error_string)(dpy, event->error_code, &ext->codes,
+ buffer, BUFSIZ);
+ if (buffer[0]) {
+ bext = ext;
+ break;
+ }
+ if (ext->codes.first_error &&
+ ext->codes.first_error < (int)event->error_code &&
+ (!bext || ext->codes.first_error > bext->codes.first_error))
+ bext = ext;
+ }
+ if (bext)
+ sprintf(buffer, "%s.%d", bext->name,
+ event->error_code - bext->codes.first_error);
+ else
+ strcpy(buffer, "Value");
+ XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
+ if (mesg[0]) {
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->resourceid);
+ fputs("\n", fp);
+ }
+ /* let extensions try to print the values */
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->error_values)
+ (*ext->error_values)(dpy, event, fp);
+ }
+ } else if ((event->error_code == BadWindow) ||
+ (event->error_code == BadPixmap) ||
+ (event->error_code == BadCursor) ||
+ (event->error_code == BadFont) ||
+ (event->error_code == BadDrawable) ||
+ (event->error_code == BadColor) ||
+ (event->error_code == BadGC) ||
+ (event->error_code == BadIDChoice) ||
+ (event->error_code == BadValue) ||
+ (event->error_code == BadAtom)) {
+ if (event->error_code == BadValue)
+ XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
+ mesg, BUFSIZ);
+ else if (event->error_code == BadAtom)
+ XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
+ mesg, BUFSIZ);
+ else
+ XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
+ mesg, BUFSIZ);
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->resourceid);
+ fputs("\n", fp);
+ }
+ XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
+ mesg, BUFSIZ);
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->serial);
+ XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
+ mesg, BUFSIZ);
+ fputs("\n ", fp);
+ (void) fprintf(fp, mesg, dpy->request);
+ fputs("\n", fp);
+ if (event->error_code == BadImplementation) return 0;
+ return 1;
+}
+
+int _XDefaultError(
+ Display *dpy,
+ XErrorEvent *event)
+{
+ if (_XPrintDefaultError (dpy, event, stderr) == 0) return 0;
+ exit(1);
+ /*NOTREACHED*/
+}
+
+/*ARGSUSED*/
+Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we)
+{
+ return True;
+}
+
+/*
+ * _XError - upcall internal or user protocol error handler
+ */
+int _XError (
+ Display *dpy,
+ register xError *rep)
+{
+ /*
+ * X_Error packet encountered! We need to unpack the error before
+ * giving it to the user.
+ */
+ XEvent event; /* make it a large event */
+ register _XAsyncHandler *async, *next;
+
+ event.xerror.serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep);
+
+ for (async = dpy->async_handlers; async; async = next) {
+ next = async->next;
+ if ((*async->handler)(dpy, (xReply *)rep,
+ (char *)rep, SIZEOF(xError), async->data))
+ return 0;
+ }
+
+ event.xerror.display = dpy;
+ event.xerror.type = X_Error;
+ event.xerror.resourceid = rep->resourceID;
+ event.xerror.error_code = rep->errorCode;
+ event.xerror.request_code = rep->majorCode;
+ event.xerror.minor_code = rep->minorCode;
+ if (dpy->error_vec &&
+ !(*dpy->error_vec[rep->errorCode])(dpy, &event.xerror, rep))
+ return 0;
+ if (_XErrorFunction != NULL) {
+ return (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */
+ } else {
+ return _XDefaultError(dpy, (XErrorEvent *)&event);
+ }
+}
+
+/*
+ * _XIOError - call user connection error handler and exit
+ */
+int
+_XIOError (
+ Display *dpy)
+{
+ dpy->flags |= XlibDisplayIOError;
+#ifdef WIN32
+ errno = WSAGetLastError();
+#endif
+
+ /* This assumes that the thread calling exit will call any atexit handlers.
+ * If this does not hold, then an alternate solution would involve
+ * registering an atexit handler to take over the lock, which would only
+ * assume that the same thread calls all the atexit handlers. */
+#ifdef XTHREADS
+ if (dpy->lock)
+ (*dpy->lock->user_lock_display)(dpy);
+#endif
+ UnlockDisplay(dpy);
+
+ if (_XIOErrorFunction != NULL)
+ (*_XIOErrorFunction)(dpy);
+ else
+ _XDefaultIOError(dpy);
+ exit (1);
+ return 0;
+}
+
+
+/*
+ * This routine can be used to (cheaply) get some memory within a single
+ * Xlib routine for scratch space. A single buffer is reused each time
+ * if possible. To be MT safe, you can only call this between a call to
+ * GetReq* and a call to Data* or _XSend*, or in a context when the thread
+ * is guaranteed to not unlock the display.
+ */
+char *_XAllocScratch(
+ register Display *dpy,
+ unsigned long nbytes)
+{
+ if (nbytes > dpy->scratch_length) {
+ if (dpy->scratch_buffer) Xfree (dpy->scratch_buffer);
+ if ((dpy->scratch_buffer = Xmalloc((unsigned) nbytes)))
+ dpy->scratch_length = nbytes;
+ else dpy->scratch_length = 0;
+ }
+ return (dpy->scratch_buffer);
+}
+
+/*
+ * Scratch space allocator you can call any time, multiple times, and be
+ * MT safe, but you must hand the buffer back with _XFreeTemp.
+ */
+char *_XAllocTemp(
+ register Display *dpy,
+ unsigned long nbytes)
+{
+ char *buf;
+
+ buf = _XAllocScratch(dpy, nbytes);
+ dpy->scratch_buffer = NULL;
+ dpy->scratch_length = 0;
+ return buf;
+}
+
+void _XFreeTemp(
+ register Display *dpy,
+ char *buf,
+ unsigned long nbytes)
+{
+ if (dpy->scratch_buffer)
+ Xfree(dpy->scratch_buffer);
+ dpy->scratch_buffer = buf;
+ dpy->scratch_length = nbytes;
+}
+
+/*
+ * Given a visual id, find the visual structure for this id on this display.
+ */
+Visual *_XVIDtoVisual(
+ Display *dpy,
+ VisualID id)
+{
+ register int i, j, k;
+ register Screen *sp;
+ register Depth *dp;
+ register Visual *vp;
+ for (i = 0; i < dpy->nscreens; i++) {
+ sp = &dpy->screens[i];
+ for (j = 0; j < sp->ndepths; j++) {
+ dp = &sp->depths[j];
+ /* if nvisuals == 0 then visuals will be NULL */
+ for (k = 0; k < dp->nvisuals; k++) {
+ vp = &dp->visuals[k];
+ if (vp->visualid == id) return (vp);
+ }
+ }
+ }
+ return (NULL);
+}
+
+int
+XFree (void *data)
+{
+ Xfree (data);
+ return 1;
+}
+
+#ifdef _XNEEDBCOPYFUNC
+void _Xbcopy(b1, b2, length)
+ register char *b1, *b2;
+ register length;
+{
+ if (b1 < b2) {
+ b2 += length;
+ b1 += length;
+ while (length--)
+ *--b2 = *--b1;
+ } else {
+ while (length--)
+ *b2++ = *b1++;
+ }
+}
+#endif
+
+#ifdef DataRoutineIsProcedure
+void Data(
+ Display *dpy,
+ char *data,
+ long len)
+{
+ if (dpy->bufptr + (len) <= dpy->bufmax) {
+ memcpy(dpy->bufptr, data, (int)len);
+ dpy->bufptr += ((len) + 3) & ~3;
+ } else {
+ _XSend(dpy, data, len);
+ }
+}
+#endif /* DataRoutineIsProcedure */
+
+
+#ifdef LONG64
+int
+_XData32(
+ Display *dpy,
+ register long *data,
+ unsigned len)
+{
+ register int *buf;
+ register long i;
+
+ while (len) {
+ buf = (int *)dpy->bufptr;
+ i = dpy->bufmax - (char *)buf;
+ if (!i) {
+ _XFlush(dpy);
+ continue;
+ }
+ if (len < i)
+ i = len;
+ dpy->bufptr = (char *)buf + i;
+ len -= i;
+ i >>= 2;
+ while (--i >= 0)
+ *buf++ = *data++;
+ }
+ return 0;
+}
+#endif /* LONG64 */
+
+#ifdef WORD64
+
+/*
+ * XXX This is a *really* stupid way of doing this. It should just use
+ * dpy->bufptr directly, taking into account where in the word it is.
+ */
+
+/*
+ * Data16 - Place 16 bit data in the buffer.
+ *
+ * "dpy" is a pointer to a Display.
+ * "data" is a pointer to the data.
+ * "len" is the length in bytes of the data.
+ */
+
+static doData16(
+ register Display *dpy,
+ short *data,
+ unsigned len,
+ char *packbuffer)
+{
+ long *lp,*lpack;
+ long i, nwords,bits;
+ long mask16 = 0x000000000000ffff;
+
+ lp = (long *)data;
+ lpack = (long *)packbuffer;
+
+/* nwords is the number of 16 bit values to be packed,
+ * the low order 16 bits of each word will be packed
+ * into 64 bit words
+ */
+ nwords = len >> 1;
+ bits = 48;
+
+ for(i=0;i<nwords;i++){
+ if (bits == 48) *lpack = 0;
+ *lpack ^= (*lp & mask16) << bits;
+ bits -= 16 ;
+ lp++;
+ if(bits < 0){
+ lpack++;
+ bits = 48;
+ }
+ }
+ Data(dpy, packbuffer, len);
+}
+
+_XData16 (
+ Display *dpy,
+ short *data,
+ unsigned len)
+{
+ char packbuffer[PACKBUFFERSIZE];
+ unsigned nunits = PACKBUFFERSIZE >> 1;
+
+ for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
+ doData16 (dpy, data, PACKBUFFERSIZE, packbuffer);
+ }
+ if (len) doData16 (dpy, data, len, packbuffer);
+}
+
+/*
+ * Data32 - Place 32 bit data in the buffer.
+ *
+ * "dpy" is a pointer to a Display.
+ * "data" is a pointer to the data.
+ * "len" is the length in bytes of the data.
+ */
+
+static doData32(
+ register Display *dpy
+ long *data,
+ unsigned len,
+ char *packbuffer)
+{
+ long *lp,*lpack;
+ long i,bits,nwords;
+ long mask32 = 0x00000000ffffffff;
+
+ lpack = (long *) packbuffer;
+ lp = data;
+
+/* nwords is the number of 32 bit values to be packed
+ * the low order 32 bits of each word will be packed
+ * into 64 bit words
+ */
+ nwords = len >> 2;
+ bits = 32;
+
+ for(i=0;i<nwords;i++){
+ if (bits == 32) *lpack = 0;
+ *lpack ^= (*lp & mask32) << bits;
+ bits = bits ^32;
+ lp++;
+ if(bits)
+ lpack++;
+ }
+ Data(dpy, packbuffer, len);
+}
+
+void _XData32(
+ Display *dpy,
+ long *data,
+ unsigned len)
+{
+ char packbuffer[PACKBUFFERSIZE];
+ unsigned nunits = PACKBUFFERSIZE >> 2;
+
+ for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
+ doData32 (dpy, data, PACKBUFFERSIZE, packbuffer);
+ }
+ if (len) doData32 (dpy, data, len, packbuffer);
+}
+
+#endif /* WORD64 */
+
+
+/* Make sure this produces the same string as DefineLocal/DefineSelf in xdm.
+ * Otherwise, Xau will not be able to find your cookies in the Xauthority file.
+ *
+ * Note: POSIX says that the ``nodename'' member of utsname does _not_ have
+ * to have sufficient information for interfacing to the network,
+ * and so, you may be better off using gethostname (if it exists).
+ */
+
+#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(SVR4)
+#define NEED_UTSNAME
+#include <sys/utsname.h>
+#else
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#endif
+
+/*
+ * _XGetHostname - similar to gethostname but allows special processing.
+ */
+int _XGetHostname (
+ char *buf,
+ int maxlen)
+{
+ int len;
+
+#ifdef NEED_UTSNAME
+ struct utsname name;
+
+ if (maxlen <= 0 || buf == NULL)
+ return 0;
+
+ uname (&name);
+ len = strlen (name.nodename);
+ if (len >= maxlen) len = maxlen - 1;
+ strncpy (buf, name.nodename, len);
+ buf[len] = '\0';
+#else
+ if (maxlen <= 0 || buf == NULL)
+ return 0;
+
+ buf[0] = '\0';
+ (void) gethostname (buf, maxlen);
+ buf [maxlen - 1] = '\0';
+ len = strlen(buf);
+#endif /* NEED_UTSNAME */
+ return len;
+}
+
+
+/*
+ * _XScreenOfWindow - get the Screen of a given window
+ */
+
+Screen *_XScreenOfWindow(Display *dpy, Window w)
+{
+ register int i;
+ Window root;
+ int x, y; /* dummy variables */
+ unsigned int width, height, bw, depth; /* dummy variables */
+
+ if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height,
+ &bw, &depth) == False) {
+ return NULL;
+ }
+ for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */
+ if (root == RootWindow (dpy, i)) {
+ return ScreenOfDisplay (dpy, i);
+ }
+ }
+ return NULL;
+}
+
+
+#if defined(WIN32)
+
+/*
+ * These functions are intended to be used internally to Xlib only.
+ * These functions will always prefix the path with a DOS drive in the
+ * form "<drive-letter>:". As such, these functions are only suitable
+ * for use by Xlib function that supply a root-based path to some
+ * particular file, e.g. <ProjectRoot>/lib/X11/locale/locale.dir will
+ * be converted to "C:/usr/X11R6.3/lib/X11/locale/locale.dir".
+ */
+
+static int access_file (path, pathbuf, len_pathbuf, pathret)
+ char* path;
+ char* pathbuf;
+ int len_pathbuf;
+ char** pathret;
+{
+ if (access (path, F_OK) == 0) {
+ if (strlen (path) < len_pathbuf)
+ *pathret = pathbuf;
+ else
+ *pathret = Xmalloc (strlen (path) + 1);
+ if (*pathret) {
+ strcpy (*pathret, path);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int AccessFile (path, pathbuf, len_pathbuf, pathret)
+ char* path;
+ char* pathbuf;
+ int len_pathbuf;
+ char** pathret;
+{
+ unsigned long drives;
+ int i, len;
+ char* drive;
+ char buf[MAX_PATH];
+ char* bufp;
+
+ /* just try the "raw" name first and see if it works */
+ if (access_file (path, pathbuf, len_pathbuf, pathret))
+ return 1;
+
+ /* try the places set in the environment */
+ drive = getenv ("_XBASEDRIVE");
+#ifdef __UNIXOS2__
+ if (!drive)
+ drive = getenv ("X11ROOT");
+#endif
+ if (!drive)
+ drive = "C:";
+ len = strlen (drive) + strlen (path);
+ if (len < MAX_PATH) bufp = buf;
+ else bufp = Xmalloc (len + 1);
+ strcpy (bufp, drive);
+ strcat (bufp, path);
+ if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
+ if (bufp != buf) Xfree (bufp);
+ return 1;
+ }
+
+#ifndef __UNIXOS2__
+ /* one last place to look */
+ drive = getenv ("HOMEDRIVE");
+ if (drive) {
+ len = strlen (drive) + strlen (path);
+ if (len < MAX_PATH) bufp = buf;
+ else bufp = Xmalloc (len + 1);
+ strcpy (bufp, drive);
+ strcat (bufp, path);
+ if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
+ if (bufp != buf) Xfree (bufp);
+ return 1;
+ }
+ }
+
+ /* tried everywhere else, go fishing */
+#define C_DRIVE ('C' - 'A')
+#define Z_DRIVE ('Z' - 'A')
+ /* does OS/2 (with or with gcc-emx) have getdrives? */
+ drives = _getdrives ();
+ for (i = C_DRIVE; i <= Z_DRIVE; i++) { /* don't check on A: or B: */
+ if ((1 << i) & drives) {
+ len = 2 + strlen (path);
+ if (len < MAX_PATH) bufp = buf;
+ else bufp = Xmalloc (len + 1);
+ *bufp = 'A' + i;
+ *(bufp + 1) = ':';
+ *(bufp + 2) = '\0';
+ strcat (bufp, path);
+ if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
+ if (bufp != buf) Xfree (bufp);
+ return 1;
+ }
+ }
+ }
+#endif
+ return 0;
+}
+
+int _XOpenFile(path, flags)
+ _Xconst char* path;
+ int flags;
+{
+ char buf[MAX_PATH];
+ char* bufp = NULL;
+ int ret = -1;
+ UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
+
+ if (AccessFile (path, buf, MAX_PATH, &bufp))
+ ret = open (bufp, flags);
+
+ (void) SetErrorMode (olderror);
+
+ if (bufp != buf) Xfree (bufp);
+
+ return ret;
+}
+
+int _XOpenFileMode(path, flags, mode)
+ _Xconst char* path;
+ int flags;
+ mode_t mode;
+{
+ char buf[MAX_PATH];
+ char* bufp = NULL;
+ int ret = -1;
+ UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
+
+ if (AccessFile (path, buf, MAX_PATH, &bufp))
+ ret = open (bufp, flags, mode);
+
+ (void) SetErrorMode (olderror);
+
+ if (bufp != buf) Xfree (bufp);
+
+ return ret;
+}
+
+void* _XFopenFile(path, mode)
+ _Xconst char* path;
+ _Xconst char* mode;
+{
+ char buf[MAX_PATH];
+ char* bufp = NULL;
+ void* ret = NULL;
+ UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
+
+ if (AccessFile (path, buf, MAX_PATH, &bufp))
+ ret = fopen (bufp, mode);
+
+ (void) SetErrorMode (olderror);
+
+ if (bufp != buf) Xfree (bufp);
+
+ return ret;
+}
+
+int _XAccessFile(path)
+ _Xconst char* path;
+{
+ char buf[MAX_PATH];
+ char* bufp;
+ int ret = -1;
+ UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
+
+ ret = AccessFile (path, buf, MAX_PATH, &bufp);
+
+ (void) SetErrorMode (olderror);
+
+ if (bufp != buf) Xfree (bufp);
+
+ return ret;
+}
+
+#endif
+
+#ifdef WIN32
+#undef _Xdebug
+int _Xdebug = 0;
+int *_Xdebug_p = &_Xdebug;
+void (**_XCreateMutex_fn_p)(LockInfoPtr) = &_XCreateMutex_fn;
+void (**_XFreeMutex_fn_p)(LockInfoPtr) = &_XFreeMutex_fn;
+void (**_XLockMutex_fn_p)(LockInfoPtr
+#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
+ , char * /* file */
+ , int /* line */
+#endif
+ ) = &_XLockMutex_fn;
+void (**_XUnlockMutex_fn_p)(LockInfoPtr
+#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
+ , char * /* file */
+ , int /* line */
+#endif
+ ) = &_XUnlockMutex_fn;
+LockInfoPtr *_Xglobal_lock_p = &_Xglobal_lock;
+#endif
diff --git a/libX11/src/xkb/XKB.c b/libX11/src/xkb/XKB.c
index fea57870b..374e27d2d 100644
--- a/libX11/src/xkb/XKB.c
+++ b/libX11/src/xkb/XKB.c
@@ -1,772 +1,772 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdio.h>
-
-#ifdef XKB_IN_SERVER
-#define XkbVirtualModsToReal SrvXkbVirtualModsToReal
-#endif
-
-#include "Xlibint.h"
-#include <X11/extensions/XKBproto.h>
-#include "XKBlibint.h"
-
-XkbInternAtomFunc _XkbInternAtomFunc= XInternAtom;
-XkbGetAtomNameFunc _XkbGetAtomNameFunc= XGetAtomName;
-
-Bool
-XkbQueryExtension( Display *dpy,
- int * opcodeReturn,
- int * eventBaseReturn,
- int * errorBaseReturn,
- int * majorReturn,
- int * minorReturn)
-{
- if (!XkbUseExtension(dpy,majorReturn,minorReturn))
- return False;
- if (opcodeReturn)
- *opcodeReturn = dpy->xkb_info->codes->major_opcode;
- if (eventBaseReturn)
- *eventBaseReturn = dpy->xkb_info->codes->first_event;
- if (errorBaseReturn)
- *errorBaseReturn = dpy->xkb_info->codes->first_error;
- if (majorReturn)
- *majorReturn = dpy->xkb_info->srv_major;
- if (minorReturn)
- *minorReturn = dpy->xkb_info->srv_minor;
- return True;
-}
-
-Bool
-XkbLibraryVersion(int *libMajorRtrn,int *libMinorRtrn)
-{
-int supported;
-
- if (*libMajorRtrn != XkbMajorVersion) {
- /* version 0.65 is (almost) compatible with 1.00 */
- if ((XkbMajorVersion==1)&&(((*libMajorRtrn)==0)&&((*libMinorRtrn)==65)))
- supported= True;
- else supported= False;
- }
- else {
- supported = True;
- }
-
- *libMajorRtrn = XkbMajorVersion;
- *libMinorRtrn = XkbMinorVersion;
- return supported;
-}
-
-Bool
-XkbSelectEvents( Display * dpy,
- unsigned int deviceSpec,
- unsigned int affect,
- unsigned int selectAll)
-{
- register xkbSelectEventsReq *req;
- XkbInfoPtr xkbi;
-
- if ((dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
- return False;
- LockDisplay(dpy);
- xkbi = dpy->xkb_info;
- xkbi->selected_events&= ~affect;
- xkbi->selected_events|= (affect&selectAll);
- GetReq(kbSelectEvents, req);
- req->reqType = xkbi->codes->major_opcode;
- req->xkbReqType = X_kbSelectEvents;
- req->deviceSpec = deviceSpec;
- req->affectWhich = (CARD16)affect;
- req->clear = affect&(~selectAll);
- req->selectAll = affect&selectAll;
- if (affect&XkbMapNotifyMask) {
- req->affectMap= XkbAllMapComponentsMask;
- /* the implicit support needs the client info */
- /* even if the client itself doesn't want it */
- if (selectAll&XkbMapNotifyMask)
- req->map= XkbAllMapEventsMask;
- else req->map= XkbAllClientInfoMask;
- if (selectAll&XkbMapNotifyMask)
- xkbi->selected_map_details= XkbAllMapEventsMask;
- else xkbi->selected_map_details= 0;
- }
- if (affect&XkbNewKeyboardNotifyMask) {
- if (selectAll&XkbNewKeyboardNotifyMask)
- xkbi->selected_nkn_details= XkbAllNewKeyboardEventsMask;
- else xkbi->selected_nkn_details= 0;
- if (!(xkbi->xlib_ctrls&XkbLC_IgnoreNewKeyboards)) {
- /* we want it, even if the client doesn't. Don't mess */
- /* around with details -- ask for all of them and throw */
- /* away the ones we don't need */
- req->selectAll|= XkbNewKeyboardNotifyMask;
- }
- }
- UnlockDisplay(dpy);
- SyncHandle();
- return True;
-}
-
-Bool
-XkbSelectEventDetails( Display * dpy,
- unsigned deviceSpec,
- unsigned eventType,
- unsigned long int affect,
- unsigned long int details)
-{
- register xkbSelectEventsReq *req;
- XkbInfoPtr xkbi;
- int size = 0;
- char *out;
- union {
- CARD8 *c8;
- CARD16 *c16;
- CARD32 *c32;
- } u;
-
- if ((dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
- return False;
- LockDisplay(dpy);
- xkbi = dpy->xkb_info;
- if (affect&details) xkbi->selected_events|= (1<<eventType);
- else xkbi->selected_events&= ~(1<<eventType);
- GetReq(kbSelectEvents, req);
- req->reqType = xkbi->codes->major_opcode;
- req->xkbReqType = X_kbSelectEvents;
- req->deviceSpec = deviceSpec;
- req->clear= req->selectAll= 0;
- if (eventType==XkbMapNotify) {
- /* we need all of the client info, even if the application */
- /* doesn't. Make sure that we always request the stuff */
- /* that the implicit support needs, and just filter out anything */
- /* the client doesn't want later */
- req->affectWhich = 0;
- req->selectAll = 0;
- req->clear = 0;
- req->affectMap = (CARD16)affect;
- req->map = (CARD16)details|(XkbAllClientInfoMask&affect);
- req->affectWhich = XkbMapNotifyMask;
- xkbi->selected_map_details&= ~affect;
- xkbi->selected_map_details|= (details&affect);
- }
- else {
- req->affectMap = req->map = 0;
- req->affectWhich= (1<<eventType);
- switch (eventType) {
- case XkbNewKeyboardNotify:
- xkbi->selected_nkn_details&= ~affect;
- xkbi->selected_nkn_details|= (details&affect);
- if (!(xkbi->xlib_ctrls&XkbLC_IgnoreNewKeyboards))
- details= (affect&XkbAllNewKeyboardEventsMask);
- case XkbStateNotify:
- case XkbNamesNotify:
- case XkbAccessXNotify:
- case XkbExtensionDeviceNotify:
- size= 2;
- req->length+= 1;
- break;
- case XkbControlsNotify:
- case XkbIndicatorStateNotify:
- case XkbIndicatorMapNotify:
- size= 4;
- req->length+= 2;
- break;
- case XkbBellNotify:
- case XkbActionMessage:
- case XkbCompatMapNotify:
- size= 1;
- req->length+= 1;
- break;
- }
- BufAlloc(char *,out,(((size*2)+(unsigned)3)/4)*4);
- u.c8= (CARD8 *)out;
- if (size==2) {
- u.c16[0]= (CARD16)affect;
- u.c16[1]= (CARD16)details;
- }
- else if (size==4) {
- u.c32[0]= (CARD32)affect;
- u.c32[1]= (CARD32)details;
- }
- else {
- u.c8[0]= (CARD8)affect;
- u.c8[1]= (CARD8)details;
- }
- }
- UnlockDisplay(dpy);
- SyncHandle();
- return True;
-}
-
-Bool
-XkbLockModifiers( Display * dpy,
- unsigned int deviceSpec,
- unsigned int affect,
- unsigned int values)
-{
- register xkbLatchLockStateReq *req;
- XkbInfoPtr xkbi;
-
- if ((dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
- return False;
- LockDisplay(dpy);
- xkbi = dpy->xkb_info;
- GetReq(kbLatchLockState, req);
- req->reqType = xkbi->codes->major_opcode;
- req->xkbReqType = X_kbLatchLockState;
- req->deviceSpec = deviceSpec;
- req->affectModLocks= affect;
- req->modLocks = values;
- req->lockGroup = False;
- req->groupLock = 0;
-
- req->affectModLatches = req->modLatches = 0;
- req->latchGroup = False;
- req->groupLatch = 0;
- UnlockDisplay(dpy);
- SyncHandle();
- return True;
-}
-
-Bool
-XkbLatchModifiers( Display * dpy,
- unsigned int deviceSpec,
- unsigned int affect,
- unsigned int values)
-{
- register xkbLatchLockStateReq *req;
- XkbInfoPtr xkbi;
-
- if ((dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
- return False;
- LockDisplay(dpy);
- xkbi = dpy->xkb_info;
- GetReq(kbLatchLockState, req);
- req->reqType = xkbi->codes->major_opcode;
- req->xkbReqType = X_kbLatchLockState;
- req->deviceSpec = deviceSpec;
-
- req->affectModLatches= affect;
- req->modLatches = values;
- req->latchGroup = False;
- req->groupLatch = 0;
-
- req->affectModLocks = req->modLocks = 0;
- req->lockGroup = False;
- req->groupLock = 0;
-
- UnlockDisplay(dpy);
- SyncHandle();
- return True;
-}
-
-Bool
-XkbLockGroup(Display *dpy,unsigned int deviceSpec,unsigned int group)
-{
- register xkbLatchLockStateReq *req;
- XkbInfoPtr xkbi;
-
- if ((dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
- return False;
- LockDisplay(dpy);
- xkbi = dpy->xkb_info;
- GetReq(kbLatchLockState, req);
- req->reqType = xkbi->codes->major_opcode;
- req->xkbReqType = X_kbLatchLockState;
- req->deviceSpec = deviceSpec;
- req->affectModLocks= 0;
- req->modLocks = 0;
- req->lockGroup = True;
- req->groupLock = group;
-
- req->affectModLatches = req->modLatches = 0;
- req->latchGroup = False;
- req->groupLatch = 0;
- UnlockDisplay(dpy);
- SyncHandle();
- return True;
-}
-
-Bool
-XkbLatchGroup(Display *dpy,unsigned int deviceSpec,unsigned int group)
-{
- register xkbLatchLockStateReq *req;
- XkbInfoPtr xkbi;
-
- if ((dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
- return False;
- LockDisplay(dpy);
- xkbi = dpy->xkb_info;
- GetReq(kbLatchLockState, req);
- req->reqType = xkbi->codes->major_opcode;
- req->xkbReqType = X_kbLatchLockState;
- req->deviceSpec = deviceSpec;
-
- req->affectModLatches= 0;
- req->modLatches = 0;
- req->latchGroup = True;
- req->groupLatch = group;
-
- req->affectModLocks = req->modLocks = 0;
- req->lockGroup = False;
- req->groupLock = 0;
-
- UnlockDisplay(dpy);
- SyncHandle();
- return True;
-}
-
-unsigned
-XkbSetXlibControls(Display *dpy,unsigned affect,unsigned values)
-{
- if (!dpy->xkb_info)
- XkbUseExtension(dpy,NULL,NULL);
- if (!dpy->xkb_info)
- return 0;
- affect&= XkbLC_AllControls;
- dpy->xkb_info->xlib_ctrls&= ~affect;
- dpy->xkb_info->xlib_ctrls|= (affect&values);
- return dpy->xkb_info->xlib_ctrls;
-}
-
-unsigned
-XkbGetXlibControls(Display *dpy)
-{
- if (!dpy->xkb_info)
- XkbUseExtension(dpy,NULL,NULL);
- if (!dpy->xkb_info)
- return 0;
- return dpy->xkb_info->xlib_ctrls;
-}
-
-unsigned int
-XkbXlibControlsImplemented(void)
-{
-#ifdef __sgi
- return XkbLC_AllControls;
-#else
- return XkbLC_AllControls&~XkbLC_AllComposeControls;
-#endif
-}
-
-Bool
-XkbSetDebuggingFlags( Display * dpy,
- unsigned int mask,
- unsigned int flags,
- char * msg,
- unsigned int ctrls_mask,
- unsigned int ctrls,
- unsigned int * rtrn_flags,
- unsigned int * rtrn_ctrls)
-{
- register xkbSetDebuggingFlagsReq *req;
- xkbSetDebuggingFlagsReply rep;
- XkbInfoPtr xkbi;
-
- if ((dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
- return False;
- LockDisplay(dpy);
- xkbi = dpy->xkb_info;
- GetReq(kbSetDebuggingFlags, req);
- req->reqType= xkbi->codes->major_opcode;
- req->xkbReqType= X_kbSetDebuggingFlags;
- req->affectFlags= mask;
- req->flags= flags;
- req->affectCtrls= ctrls_mask;
- req->ctrls= ctrls;
-
- if (msg) {
- char *out;
- req->msgLength= (unsigned short)strlen(msg)+1;
- req->length+= (req->msgLength+(unsigned)3)>>2;
- BufAlloc(char *,out,((req->msgLength+(unsigned)3)/4)*4);
- memcpy(out,msg,req->msgLength);
- }
- else req->msgLength= 0;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return False;
- }
- if (rtrn_flags)
- *rtrn_flags= rep.currentFlags;
- if (rtrn_ctrls)
- *rtrn_ctrls= rep.currentCtrls;
- UnlockDisplay(dpy);
- SyncHandle();
- return True;
-}
-
-Bool
-XkbComputeEffectiveMap( XkbDescPtr xkb,
- XkbKeyTypePtr type,
- unsigned char * map_rtrn)
-{
-register int i;
-unsigned tmp;
-XkbKTMapEntryPtr entry = NULL;
-
- if ((!xkb)||(!type)||(!xkb->server))
- return False;
-
- if (type->mods.vmods!=0) {
- if (!XkbVirtualModsToReal(xkb,type->mods.vmods,&tmp))
- return False;
-
- type->mods.mask= tmp|type->mods.real_mods;
- entry= type->map;
- for (i=0;i<type->map_count;i++,entry++) {
- tmp= 0;
- if (entry->mods.vmods!=0) {
- if (!XkbVirtualModsToReal(xkb,entry->mods.vmods,&tmp))
- return False;
- if (tmp==0) {
- entry->active= False;
- continue;
- }
- }
- entry->active= True;
- entry->mods.mask= (entry->mods.real_mods|tmp)&type->mods.mask;
- }
- }
- else {
- type->mods.mask= type->mods.real_mods;
- }
- if (map_rtrn!=NULL) {
- bzero(map_rtrn,type->mods.mask+1);
- for (i=0;i<type->map_count;i++) {
- if (entry->active) {
- map_rtrn[type->map[i].mods.mask]= type->map[i].level;
- }
- }
- }
- return True;
-}
-
-Status
-XkbGetState(Display *dpy,unsigned deviceSpec,XkbStatePtr rtrn)
-{
- register xkbGetStateReq *req;
- xkbGetStateReply rep;
- XkbInfoPtr xkbi;
-
- if ((dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
- return BadAccess;
- LockDisplay(dpy);
- xkbi = dpy->xkb_info;
- GetReq(kbGetState, req);
- req->reqType = xkbi->codes->major_opcode;
- req->xkbReqType = X_kbGetState;
- req->deviceSpec = deviceSpec;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return BadImplementation;
- }
- rtrn->mods= rep.mods;
- rtrn->base_mods= rep.baseMods;
- rtrn->latched_mods= rep.latchedMods;
- rtrn->locked_mods= rep.lockedMods;
- rtrn->group= rep.group;
- rtrn->base_group= rep.baseGroup;
- rtrn->latched_group= rep.latchedGroup;
- rtrn->locked_group= rep.lockedGroup;
- rtrn->compat_state= rep.compatState;
- rtrn->grab_mods= rep.grabMods;
- rtrn->compat_grab_mods= rep.compatGrabMods;
- rtrn->lookup_mods= rep.lookupMods;
- rtrn->compat_lookup_mods= rep.compatLookupMods;
- rtrn->ptr_buttons= rep.ptrBtnState;
- UnlockDisplay(dpy);
- SyncHandle();
- return Success;
-}
-
-Bool
-XkbSetDetectableAutoRepeat(Display *dpy,Bool detectable,Bool *supported)
-{
-register xkbPerClientFlagsReq * req;
-xkbPerClientFlagsReply rep;
-XkbInfoPtr xkbi;
-
- if ((dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
- return False;
- LockDisplay(dpy);
- xkbi = dpy->xkb_info;
- GetReq(kbPerClientFlags, req);
- req->reqType = xkbi->codes->major_opcode;
- req->xkbReqType = X_kbPerClientFlags;
- req->deviceSpec = XkbUseCoreKbd;
- req->change = XkbPCF_DetectableAutoRepeatMask;
- if (detectable)
- req->value = XkbPCF_DetectableAutoRepeatMask;
- else req->value = 0;
- req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return False;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- if (supported!=NULL)
- *supported= ((rep.supported&XkbPCF_DetectableAutoRepeatMask)!=0);
- return ((rep.value&XkbPCF_DetectableAutoRepeatMask)!=0);
-}
-
-Bool
-XkbGetDetectableAutoRepeat(Display *dpy,Bool *supported)
-{
-register xkbPerClientFlagsReq * req;
-xkbPerClientFlagsReply rep;
-XkbInfoPtr xkbi;
-
- if ((dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
- return False;
- LockDisplay(dpy);
- xkbi = dpy->xkb_info;
- GetReq(kbPerClientFlags, req);
- req->reqType = xkbi->codes->major_opcode;
- req->xkbReqType = X_kbPerClientFlags;
- req->deviceSpec = XkbUseCoreKbd;
- req->change = 0;
- req->value = 0;
- req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return False;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- if (supported!=NULL)
- *supported= ((rep.supported&XkbPCF_DetectableAutoRepeatMask)!=0);
- return ((rep.value&XkbPCF_DetectableAutoRepeatMask)!=0);
-}
-
-Bool
-XkbSetAutoResetControls( Display * dpy,
- unsigned changes,
- unsigned * auto_ctrls,
- unsigned * auto_values)
-{
-register xkbPerClientFlagsReq * req;
-xkbPerClientFlagsReply rep;
-XkbInfoPtr xkbi;
-
- if ((dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
- return False;
- LockDisplay(dpy);
- xkbi = dpy->xkb_info;
- GetReq(kbPerClientFlags, req);
- req->reqType = xkbi->codes->major_opcode;
- req->xkbReqType = X_kbPerClientFlags;
- req->change = XkbPCF_AutoResetControlsMask;
- req->deviceSpec = XkbUseCoreKbd;
- req->value = XkbPCF_AutoResetControlsMask;
- req->ctrlsToChange= changes;
- req->autoCtrls= *auto_ctrls;
- req->autoCtrlValues= *auto_values;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return False;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- *auto_ctrls= rep.autoCtrls;
- *auto_values= rep.autoCtrlValues;
- return ((rep.value&XkbPCF_AutoResetControlsMask)!=0);
-}
-
-Bool
-XkbGetAutoResetControls( Display * dpy,
- unsigned * auto_ctrls,
- unsigned * auto_ctrl_values)
-{
-register xkbPerClientFlagsReq * req;
-xkbPerClientFlagsReply rep;
-XkbInfoPtr xkbi;
-
- if ((dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
- return False;
- LockDisplay(dpy);
- xkbi = dpy->xkb_info;
- GetReq(kbPerClientFlags, req);
- req->reqType = xkbi->codes->major_opcode;
- req->xkbReqType = X_kbPerClientFlags;
- req->deviceSpec = XkbUseCoreKbd;
- req->change = 0;
- req->value = 0;
- req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return False;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- if (auto_ctrls)
- *auto_ctrls= rep.autoCtrls;
- if (auto_ctrl_values)
- *auto_ctrl_values= rep.autoCtrlValues;
- return ((rep.value&XkbPCF_AutoResetControlsMask)!=0);
-}
-
-Bool
-XkbSetPerClientControls( Display * dpy,
- unsigned change,
- unsigned * values)
-{
-register xkbPerClientFlagsReq * req;
-xkbPerClientFlagsReply rep;
-XkbInfoPtr xkbi;
-unsigned value_hold = *values;
-
- if ((dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) ||
- (change & ~(XkbPCF_GrabsUseXKBStateMask|XkbPCF_LookupStateWhenGrabbed|XkbPCF_SendEventUsesXKBState)))
- return False;
- LockDisplay(dpy);
- xkbi = dpy->xkb_info;
- GetReq(kbPerClientFlags, req);
- req->reqType = xkbi->codes->major_opcode;
- req->xkbReqType = X_kbPerClientFlags;
- req->change = change;
- req->deviceSpec = XkbUseCoreKbd;
- req->value = *values;
- req->ctrlsToChange = req->autoCtrls = req->autoCtrlValues= 0;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return False;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- *values = rep.value;
- return ((rep.value&value_hold)!=0);
-}
-
-Bool
-XkbGetPerClientControls( Display * dpy,
- unsigned * ctrls)
-{
-register xkbPerClientFlagsReq * req;
-xkbPerClientFlagsReply rep;
-XkbInfoPtr xkbi;
-
- if ((dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) ||
- (*ctrls & ~(XkbPCF_GrabsUseXKBStateMask|XkbPCF_LookupStateWhenGrabbed|XkbPCF_SendEventUsesXKBState)))
- return False;
- LockDisplay(dpy);
- xkbi = dpy->xkb_info;
- GetReq(kbPerClientFlags, req);
- req->reqType = xkbi->codes->major_opcode;
- req->xkbReqType = X_kbPerClientFlags;
- req->deviceSpec = XkbUseCoreKbd;
- req->change = 0;
- req->value = 0;
- req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return False;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- if (ctrls)
- *ctrls= (rep.value & (XkbPCF_GrabsUseXKBStateMask |
- XkbPCF_LookupStateWhenGrabbed |
- XkbPCF_SendEventUsesXKBState));
- return (True);
-}
-
-Display *
-XkbOpenDisplay( char * name,
- int * ev_rtrn,
- int * err_rtrn,
- int * major_rtrn,
- int * minor_rtrn,
- int * reason)
-{
- Display* dpy;
- int major_num,minor_num;
-
- if ((major_rtrn!=NULL) && (minor_rtrn!=NULL)) {
- if (!XkbLibraryVersion(major_rtrn,minor_rtrn)) {
- if (reason!=NULL)
- *reason= XkbOD_BadLibraryVersion;
- return NULL;
- }
- }
- else {
- major_num= XkbMajorVersion;
- minor_num= XkbMinorVersion;
- major_rtrn= &major_num;
- minor_rtrn= &minor_num;
- }
- dpy= XOpenDisplay(name);
- if (dpy==NULL) {
- if (reason!=NULL)
- *reason= XkbOD_ConnectionRefused;
- return NULL;
- }
- if (!XkbQueryExtension(dpy,NULL,ev_rtrn,err_rtrn,major_rtrn,minor_rtrn)) {
- if (reason!=NULL) {
- if ((*major_rtrn!=0)||(*minor_rtrn!=0))
- *reason= XkbOD_BadServerVersion;
- else *reason= XkbOD_NonXkbServer;
- }
- XCloseDisplay(dpy);
- return NULL;
- }
- if (reason!=NULL)
- *reason= XkbOD_Success;
- return dpy;
-}
-
-void
-XkbSetAtomFuncs(XkbInternAtomFunc getAtom,XkbGetAtomNameFunc getName)
-{
- _XkbInternAtomFunc= (getAtom?getAtom:XInternAtom);
- _XkbGetAtomNameFunc= (getName?getName:XGetAtomName);
- return;
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+
+#ifdef XKB_IN_SERVER
+#define XkbVirtualModsToReal SrvXkbVirtualModsToReal
+#endif
+
+#include "Xlibint.h"
+#include <X11/extensions/XKBproto.h>
+#include "XKBlibint.h"
+
+XkbInternAtomFunc _XkbInternAtomFunc= XInternAtom;
+XkbGetAtomNameFunc _XkbGetAtomNameFunc= XGetAtomName;
+
+Bool
+XkbQueryExtension( Display *dpy,
+ int * opcodeReturn,
+ int * eventBaseReturn,
+ int * errorBaseReturn,
+ int * majorReturn,
+ int * minorReturn)
+{
+ if (!XkbUseExtension(dpy,majorReturn,minorReturn))
+ return False;
+ if (opcodeReturn)
+ *opcodeReturn = dpy->xkb_info->codes->major_opcode;
+ if (eventBaseReturn)
+ *eventBaseReturn = dpy->xkb_info->codes->first_event;
+ if (errorBaseReturn)
+ *errorBaseReturn = dpy->xkb_info->codes->first_error;
+ if (majorReturn)
+ *majorReturn = dpy->xkb_info->srv_major;
+ if (minorReturn)
+ *minorReturn = dpy->xkb_info->srv_minor;
+ return True;
+}
+
+Bool
+XkbLibraryVersion(int *libMajorRtrn,int *libMinorRtrn)
+{
+int supported;
+
+ if (*libMajorRtrn != XkbMajorVersion) {
+ /* version 0.65 is (almost) compatible with 1.00 */
+ if ((XkbMajorVersion==1)&&(((*libMajorRtrn)==0)&&((*libMinorRtrn)==65)))
+ supported= True;
+ else supported= False;
+ }
+ else {
+ supported = True;
+ }
+
+ *libMajorRtrn = XkbMajorVersion;
+ *libMinorRtrn = XkbMinorVersion;
+ return supported;
+}
+
+Bool
+XkbSelectEvents( Display * dpy,
+ unsigned int deviceSpec,
+ unsigned int affect,
+ unsigned int selectAll)
+{
+ register xkbSelectEventsReq *req;
+ XkbInfoPtr xkbi;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return False;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ xkbi->selected_events&= ~affect;
+ xkbi->selected_events|= (affect&selectAll);
+ GetReq(kbSelectEvents, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbSelectEvents;
+ req->deviceSpec = deviceSpec;
+ req->affectWhich = (CARD16)affect;
+ req->clear = affect&(~selectAll);
+ req->selectAll = affect&selectAll;
+ if (affect&XkbMapNotifyMask) {
+ req->affectMap= XkbAllMapComponentsMask;
+ /* the implicit support needs the client info */
+ /* even if the client itself doesn't want it */
+ if (selectAll&XkbMapNotifyMask)
+ req->map= XkbAllMapEventsMask;
+ else req->map= XkbAllClientInfoMask;
+ if (selectAll&XkbMapNotifyMask)
+ xkbi->selected_map_details= XkbAllMapEventsMask;
+ else xkbi->selected_map_details= 0;
+ }
+ if (affect&XkbNewKeyboardNotifyMask) {
+ if (selectAll&XkbNewKeyboardNotifyMask)
+ xkbi->selected_nkn_details= XkbAllNewKeyboardEventsMask;
+ else xkbi->selected_nkn_details= 0;
+ if (!(xkbi->xlib_ctrls&XkbLC_IgnoreNewKeyboards)) {
+ /* we want it, even if the client doesn't. Don't mess */
+ /* around with details -- ask for all of them and throw */
+ /* away the ones we don't need */
+ req->selectAll|= XkbNewKeyboardNotifyMask;
+ }
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+XkbSelectEventDetails( Display * dpy,
+ unsigned deviceSpec,
+ unsigned eventType,
+ unsigned long int affect,
+ unsigned long int details)
+{
+ register xkbSelectEventsReq *req;
+ XkbInfoPtr xkbi;
+ int size = 0;
+ char *out;
+ union {
+ CARD8 *c8;
+ CARD16 *c16;
+ CARD32 *c32;
+ } u;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return False;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ if (affect&details) xkbi->selected_events|= (1<<eventType);
+ else xkbi->selected_events&= ~(1<<eventType);
+ GetReq(kbSelectEvents, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbSelectEvents;
+ req->deviceSpec = deviceSpec;
+ req->clear= req->selectAll= 0;
+ if (eventType==XkbMapNotify) {
+ /* we need all of the client info, even if the application */
+ /* doesn't. Make sure that we always request the stuff */
+ /* that the implicit support needs, and just filter out anything */
+ /* the client doesn't want later */
+ req->affectWhich = 0;
+ req->selectAll = 0;
+ req->clear = 0;
+ req->affectMap = (CARD16)affect;
+ req->map = (CARD16)details|(XkbAllClientInfoMask&affect);
+ req->affectWhich = XkbMapNotifyMask;
+ xkbi->selected_map_details&= ~affect;
+ xkbi->selected_map_details|= (details&affect);
+ }
+ else {
+ req->affectMap = req->map = 0;
+ req->affectWhich= (1<<eventType);
+ switch (eventType) {
+ case XkbNewKeyboardNotify:
+ xkbi->selected_nkn_details&= ~affect;
+ xkbi->selected_nkn_details|= (details&affect);
+ if (!(xkbi->xlib_ctrls&XkbLC_IgnoreNewKeyboards))
+ details= (affect&XkbAllNewKeyboardEventsMask);
+ case XkbStateNotify:
+ case XkbNamesNotify:
+ case XkbAccessXNotify:
+ case XkbExtensionDeviceNotify:
+ size= 2;
+ req->length+= 1;
+ break;
+ case XkbControlsNotify:
+ case XkbIndicatorStateNotify:
+ case XkbIndicatorMapNotify:
+ size= 4;
+ req->length+= 2;
+ break;
+ case XkbBellNotify:
+ case XkbActionMessage:
+ case XkbCompatMapNotify:
+ size= 1;
+ req->length+= 1;
+ break;
+ }
+ BufAlloc(char *,out,(((size*2)+(unsigned)3)/4)*4);
+ u.c8= (CARD8 *)out;
+ if (size==2) {
+ u.c16[0]= (CARD16)affect;
+ u.c16[1]= (CARD16)details;
+ }
+ else if (size==4) {
+ u.c32[0]= (CARD32)affect;
+ u.c32[1]= (CARD32)details;
+ }
+ else {
+ u.c8[0]= (CARD8)affect;
+ u.c8[1]= (CARD8)details;
+ }
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+XkbLockModifiers( Display * dpy,
+ unsigned int deviceSpec,
+ unsigned int affect,
+ unsigned int values)
+{
+ register xkbLatchLockStateReq *req;
+ XkbInfoPtr xkbi;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return False;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ GetReq(kbLatchLockState, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbLatchLockState;
+ req->deviceSpec = deviceSpec;
+ req->affectModLocks= affect;
+ req->modLocks = values;
+ req->lockGroup = False;
+ req->groupLock = 0;
+
+ req->affectModLatches = req->modLatches = 0;
+ req->latchGroup = False;
+ req->groupLatch = 0;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+XkbLatchModifiers( Display * dpy,
+ unsigned int deviceSpec,
+ unsigned int affect,
+ unsigned int values)
+{
+ register xkbLatchLockStateReq *req;
+ XkbInfoPtr xkbi;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return False;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ GetReq(kbLatchLockState, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbLatchLockState;
+ req->deviceSpec = deviceSpec;
+
+ req->affectModLatches= affect;
+ req->modLatches = values;
+ req->latchGroup = False;
+ req->groupLatch = 0;
+
+ req->affectModLocks = req->modLocks = 0;
+ req->lockGroup = False;
+ req->groupLock = 0;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+XkbLockGroup(Display *dpy,unsigned int deviceSpec,unsigned int group)
+{
+ register xkbLatchLockStateReq *req;
+ XkbInfoPtr xkbi;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return False;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ GetReq(kbLatchLockState, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbLatchLockState;
+ req->deviceSpec = deviceSpec;
+ req->affectModLocks= 0;
+ req->modLocks = 0;
+ req->lockGroup = True;
+ req->groupLock = group;
+
+ req->affectModLatches = req->modLatches = 0;
+ req->latchGroup = False;
+ req->groupLatch = 0;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+XkbLatchGroup(Display *dpy,unsigned int deviceSpec,unsigned int group)
+{
+ register xkbLatchLockStateReq *req;
+ XkbInfoPtr xkbi;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return False;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ GetReq(kbLatchLockState, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbLatchLockState;
+ req->deviceSpec = deviceSpec;
+
+ req->affectModLatches= 0;
+ req->modLatches = 0;
+ req->latchGroup = True;
+ req->groupLatch = group;
+
+ req->affectModLocks = req->modLocks = 0;
+ req->lockGroup = False;
+ req->groupLock = 0;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+unsigned
+XkbSetXlibControls(Display *dpy,unsigned affect,unsigned values)
+{
+ if (!dpy->xkb_info)
+ XkbUseExtension(dpy,NULL,NULL);
+ if (!dpy->xkb_info)
+ return 0;
+ affect&= XkbLC_AllControls;
+ dpy->xkb_info->xlib_ctrls&= ~affect;
+ dpy->xkb_info->xlib_ctrls|= (affect&values);
+ return dpy->xkb_info->xlib_ctrls;
+}
+
+unsigned
+XkbGetXlibControls(Display *dpy)
+{
+ if (!dpy->xkb_info)
+ XkbUseExtension(dpy,NULL,NULL);
+ if (!dpy->xkb_info)
+ return 0;
+ return dpy->xkb_info->xlib_ctrls;
+}
+
+unsigned int
+XkbXlibControlsImplemented(void)
+{
+#ifdef __sgi
+ return XkbLC_AllControls;
+#else
+ return XkbLC_AllControls&~XkbLC_AllComposeControls;
+#endif
+}
+
+Bool
+XkbSetDebuggingFlags( Display * dpy,
+ unsigned int mask,
+ unsigned int flags,
+ char * msg,
+ unsigned int ctrls_mask,
+ unsigned int ctrls,
+ unsigned int * rtrn_flags,
+ unsigned int * rtrn_ctrls)
+{
+ register xkbSetDebuggingFlagsReq *req;
+ xkbSetDebuggingFlagsReply rep;
+ XkbInfoPtr xkbi;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return False;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ GetReq(kbSetDebuggingFlags, req);
+ req->reqType= xkbi->codes->major_opcode;
+ req->xkbReqType= X_kbSetDebuggingFlags;
+ req->affectFlags= mask;
+ req->flags= flags;
+ req->affectCtrls= ctrls_mask;
+ req->ctrls= ctrls;
+
+ if (msg) {
+ char *out;
+ req->msgLength= (unsigned short)strlen(msg)+1;
+ req->length+= (req->msgLength+(unsigned)3)>>2;
+ BufAlloc(char *,out,((req->msgLength+(unsigned)3)/4)*4);
+ memcpy(out,msg,req->msgLength);
+ }
+ else req->msgLength= 0;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ if (rtrn_flags)
+ *rtrn_flags= rep.currentFlags;
+ if (rtrn_ctrls)
+ *rtrn_ctrls= rep.currentCtrls;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+XkbComputeEffectiveMap( XkbDescPtr xkb,
+ XkbKeyTypePtr type,
+ unsigned char * map_rtrn)
+{
+register int i;
+unsigned tmp;
+XkbKTMapEntryPtr entry = NULL;
+
+ if ((!xkb)||(!type)||(!xkb->server))
+ return False;
+
+ if (type->mods.vmods!=0) {
+ if (!XkbVirtualModsToReal(xkb,type->mods.vmods,&tmp))
+ return False;
+
+ type->mods.mask= tmp|type->mods.real_mods;
+ entry= type->map;
+ for (i=0;i<type->map_count;i++,entry++) {
+ tmp= 0;
+ if (entry->mods.vmods!=0) {
+ if (!XkbVirtualModsToReal(xkb,entry->mods.vmods,&tmp))
+ return False;
+ if (tmp==0) {
+ entry->active= False;
+ continue;
+ }
+ }
+ entry->active= True;
+ entry->mods.mask= (entry->mods.real_mods|tmp)&type->mods.mask;
+ }
+ }
+ else {
+ type->mods.mask= type->mods.real_mods;
+ }
+ if (map_rtrn!=NULL) {
+ bzero(map_rtrn,type->mods.mask+1);
+ for (i=0;i<type->map_count;i++) {
+ if (entry && entry->active) {
+ map_rtrn[type->map[i].mods.mask]= type->map[i].level;
+ }
+ }
+ }
+ return True;
+}
+
+Status
+XkbGetState(Display *dpy,unsigned deviceSpec,XkbStatePtr rtrn)
+{
+ register xkbGetStateReq *req;
+ xkbGetStateReply rep;
+ XkbInfoPtr xkbi;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return BadAccess;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ GetReq(kbGetState, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbGetState;
+ req->deviceSpec = deviceSpec;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return BadImplementation;
+ }
+ rtrn->mods= rep.mods;
+ rtrn->base_mods= rep.baseMods;
+ rtrn->latched_mods= rep.latchedMods;
+ rtrn->locked_mods= rep.lockedMods;
+ rtrn->group= rep.group;
+ rtrn->base_group= rep.baseGroup;
+ rtrn->latched_group= rep.latchedGroup;
+ rtrn->locked_group= rep.lockedGroup;
+ rtrn->compat_state= rep.compatState;
+ rtrn->grab_mods= rep.grabMods;
+ rtrn->compat_grab_mods= rep.compatGrabMods;
+ rtrn->lookup_mods= rep.lookupMods;
+ rtrn->compat_lookup_mods= rep.compatLookupMods;
+ rtrn->ptr_buttons= rep.ptrBtnState;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return Success;
+}
+
+Bool
+XkbSetDetectableAutoRepeat(Display *dpy,Bool detectable,Bool *supported)
+{
+register xkbPerClientFlagsReq * req;
+xkbPerClientFlagsReply rep;
+XkbInfoPtr xkbi;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return False;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ GetReq(kbPerClientFlags, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbPerClientFlags;
+ req->deviceSpec = XkbUseCoreKbd;
+ req->change = XkbPCF_DetectableAutoRepeatMask;
+ if (detectable)
+ req->value = XkbPCF_DetectableAutoRepeatMask;
+ else req->value = 0;
+ req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ if (supported!=NULL)
+ *supported= ((rep.supported&XkbPCF_DetectableAutoRepeatMask)!=0);
+ return ((rep.value&XkbPCF_DetectableAutoRepeatMask)!=0);
+}
+
+Bool
+XkbGetDetectableAutoRepeat(Display *dpy,Bool *supported)
+{
+register xkbPerClientFlagsReq * req;
+xkbPerClientFlagsReply rep;
+XkbInfoPtr xkbi;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return False;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ GetReq(kbPerClientFlags, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbPerClientFlags;
+ req->deviceSpec = XkbUseCoreKbd;
+ req->change = 0;
+ req->value = 0;
+ req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ if (supported!=NULL)
+ *supported= ((rep.supported&XkbPCF_DetectableAutoRepeatMask)!=0);
+ return ((rep.value&XkbPCF_DetectableAutoRepeatMask)!=0);
+}
+
+Bool
+XkbSetAutoResetControls( Display * dpy,
+ unsigned changes,
+ unsigned * auto_ctrls,
+ unsigned * auto_values)
+{
+register xkbPerClientFlagsReq * req;
+xkbPerClientFlagsReply rep;
+XkbInfoPtr xkbi;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return False;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ GetReq(kbPerClientFlags, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbPerClientFlags;
+ req->change = XkbPCF_AutoResetControlsMask;
+ req->deviceSpec = XkbUseCoreKbd;
+ req->value = XkbPCF_AutoResetControlsMask;
+ req->ctrlsToChange= changes;
+ req->autoCtrls= *auto_ctrls;
+ req->autoCtrlValues= *auto_values;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ *auto_ctrls= rep.autoCtrls;
+ *auto_values= rep.autoCtrlValues;
+ return ((rep.value&XkbPCF_AutoResetControlsMask)!=0);
+}
+
+Bool
+XkbGetAutoResetControls( Display * dpy,
+ unsigned * auto_ctrls,
+ unsigned * auto_ctrl_values)
+{
+register xkbPerClientFlagsReq * req;
+xkbPerClientFlagsReply rep;
+XkbInfoPtr xkbi;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return False;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ GetReq(kbPerClientFlags, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbPerClientFlags;
+ req->deviceSpec = XkbUseCoreKbd;
+ req->change = 0;
+ req->value = 0;
+ req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ if (auto_ctrls)
+ *auto_ctrls= rep.autoCtrls;
+ if (auto_ctrl_values)
+ *auto_ctrl_values= rep.autoCtrlValues;
+ return ((rep.value&XkbPCF_AutoResetControlsMask)!=0);
+}
+
+Bool
+XkbSetPerClientControls( Display * dpy,
+ unsigned change,
+ unsigned * values)
+{
+register xkbPerClientFlagsReq * req;
+xkbPerClientFlagsReply rep;
+XkbInfoPtr xkbi;
+unsigned value_hold = *values;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) ||
+ (change & ~(XkbPCF_GrabsUseXKBStateMask|XkbPCF_LookupStateWhenGrabbed|XkbPCF_SendEventUsesXKBState)))
+ return False;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ GetReq(kbPerClientFlags, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbPerClientFlags;
+ req->change = change;
+ req->deviceSpec = XkbUseCoreKbd;
+ req->value = *values;
+ req->ctrlsToChange = req->autoCtrls = req->autoCtrlValues= 0;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ *values = rep.value;
+ return ((rep.value&value_hold)!=0);
+}
+
+Bool
+XkbGetPerClientControls( Display * dpy,
+ unsigned * ctrls)
+{
+register xkbPerClientFlagsReq * req;
+xkbPerClientFlagsReply rep;
+XkbInfoPtr xkbi;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) ||
+ (*ctrls & ~(XkbPCF_GrabsUseXKBStateMask|XkbPCF_LookupStateWhenGrabbed|XkbPCF_SendEventUsesXKBState)))
+ return False;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ GetReq(kbPerClientFlags, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbPerClientFlags;
+ req->deviceSpec = XkbUseCoreKbd;
+ req->change = 0;
+ req->value = 0;
+ req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ if (ctrls)
+ *ctrls= (rep.value & (XkbPCF_GrabsUseXKBStateMask |
+ XkbPCF_LookupStateWhenGrabbed |
+ XkbPCF_SendEventUsesXKBState));
+ return (True);
+}
+
+Display *
+XkbOpenDisplay( char * name,
+ int * ev_rtrn,
+ int * err_rtrn,
+ int * major_rtrn,
+ int * minor_rtrn,
+ int * reason)
+{
+ Display* dpy;
+ int major_num,minor_num;
+
+ if ((major_rtrn!=NULL) && (minor_rtrn!=NULL)) {
+ if (!XkbLibraryVersion(major_rtrn,minor_rtrn)) {
+ if (reason!=NULL)
+ *reason= XkbOD_BadLibraryVersion;
+ return NULL;
+ }
+ }
+ else {
+ major_num= XkbMajorVersion;
+ minor_num= XkbMinorVersion;
+ major_rtrn= &major_num;
+ minor_rtrn= &minor_num;
+ }
+ dpy= XOpenDisplay(name);
+ if (dpy==NULL) {
+ if (reason!=NULL)
+ *reason= XkbOD_ConnectionRefused;
+ return NULL;
+ }
+ if (!XkbQueryExtension(dpy,NULL,ev_rtrn,err_rtrn,major_rtrn,minor_rtrn)) {
+ if (reason!=NULL) {
+ if ((*major_rtrn!=0)||(*minor_rtrn!=0))
+ *reason= XkbOD_BadServerVersion;
+ else *reason= XkbOD_NonXkbServer;
+ }
+ XCloseDisplay(dpy);
+ return NULL;
+ }
+ if (reason!=NULL)
+ *reason= XkbOD_Success;
+ return dpy;
+}
+
+void
+XkbSetAtomFuncs(XkbInternAtomFunc getAtom,XkbGetAtomNameFunc getName)
+{
+ _XkbInternAtomFunc= (getAtom?getAtom:XInternAtom);
+ _XkbGetAtomNameFunc= (getName?getName:XGetAtomName);
+ return;
+}
diff --git a/libX11/src/xkb/XKBList.c b/libX11/src/xkb/XKBList.c
index 1afe3685f..8f245f245 100644
--- a/libX11/src/xkb/XKBList.c
+++ b/libX11/src/xkb/XKBList.c
@@ -1,247 +1,249 @@
-/************************************************************
-Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#define NEED_MAP_READERS
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "Xlibint.h"
-#include <X11/extensions/XKBproto.h>
-#include "XKBlibint.h"
-
-/***====================================================================***/
-
-static void
-_FreeComponentNames(int num,XkbComponentNamePtr names)
-{
-int i;
-XkbComponentNamePtr tmp;
-
- if ((num<1)||(names==NULL))
- return;
- for (i=0,tmp=names;i<num;i++,tmp++) {
- if (tmp->name) {
- _XkbFree(tmp->name);
- tmp->name= NULL;
- }
- }
- _XkbFree(names);
- return;
-}
-
-/***====================================================================***/
-
-static XkbComponentNamePtr
-_ReadListing(XkbReadBufferPtr buf,int count,Status *status_rtrn)
-{
-XkbComponentNamePtr first,this;
-register int i;
-CARD16 * flags;
-int slen,wlen;
-char * str;
-
- if (count<1)
- return NULL;
- first= _XkbTypedCalloc(count,XkbComponentNameRec);
- if (!first)
- return NULL;
- for (this=first,i=0;i<count;i++,this++) {
- flags= (CARD16 *)_XkbGetReadBufferPtr(buf,2*sizeof(CARD16));
- if (!flags)
- goto BAILOUT;
- this->flags= flags[0];
- slen= flags[1];
- wlen= ((slen+1)/2)*2; /* pad to 2 byte boundary */
- this->name= _XkbTypedCalloc(slen+1,char);
- if (!this->name)
- goto BAILOUT;
- str= (char *)_XkbGetReadBufferPtr(buf,wlen);
- memcpy(this->name,str,slen);
- }
- return first;
-BAILOUT:
- *status_rtrn= BadAlloc;
- _FreeComponentNames(i,first);
- return NULL;
-}
-
-/***====================================================================***/
-
-XkbComponentListPtr
-XkbListComponents( Display * dpy,
- unsigned deviceSpec,
- XkbComponentNamesPtr ptrns,
- int * max_inout)
-{
-register xkbListComponentsReq* req;
-xkbListComponentsReply rep;
-XkbInfoPtr xkbi;
-XkbComponentListPtr list;
-XkbReadBufferRec buf;
-int left;
-char * str;
-int extraLen,len,mapLen,codesLen,typesLen,compatLen,symsLen,geomLen;
-
- if ( (dpy==NULL) || (dpy->flags & XlibDisplayNoXkb) ||
- (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) ||
- (ptrns==NULL) || (max_inout==NULL))
- return NULL;
-
- xkbi= dpy->xkb_info;
- LockDisplay(dpy);
- GetReq(kbListComponents, req);
- req->reqType = xkbi->codes->major_opcode;
- req->xkbReqType = X_kbListComponents;
- req->deviceSpec = deviceSpec;
- req->maxNames = *max_inout;
-
- mapLen= codesLen= typesLen= compatLen= symsLen= geomLen= 0;
- if (ptrns->keymap)
- mapLen= (int)strlen(ptrns->keymap);
- if (ptrns->keycodes)
- codesLen= (int)strlen(ptrns->keycodes);
- if (ptrns->types)
- typesLen= (int)strlen(ptrns->types);
- if (ptrns->compat)
- compatLen= (int)strlen(ptrns->compat);
- if (ptrns->symbols)
- symsLen= (int)strlen(ptrns->symbols);
- if (ptrns->geometry)
- geomLen= (int)strlen(ptrns->geometry);
- if (mapLen>255) mapLen= 255;
- if (codesLen>255) codesLen= 255;
- if (typesLen>255) typesLen= 255;
- if (compatLen>255) compatLen= 255;
- if (symsLen>255) symsLen= 255;
- if (geomLen>255) geomLen= 255;
-
- len= mapLen+codesLen+typesLen+compatLen+symsLen+geomLen+6;
- len= XkbPaddedSize(len);
- req->length+= len/4;
- BufAlloc(char *,str,len);
- *str++= mapLen;
- if (mapLen>0) {
- memcpy(str,ptrns->keymap,mapLen);
- str+= mapLen;
- }
- *str++= codesLen;
- if (codesLen>0) {
- memcpy(str,ptrns->keycodes,codesLen);
- str+= codesLen;
- }
- *str++= typesLen;
- if (typesLen>0) {
- memcpy(str,ptrns->types,typesLen);
- str+= typesLen;
- }
- *str++= compatLen;
- if (compatLen>0) {
- memcpy(str,ptrns->compat,compatLen);
- str+= compatLen;
- }
- *str++= symsLen;
- if (symsLen>0) {
- memcpy(str,ptrns->symbols,symsLen);
- str+= symsLen;
- }
- *str++= geomLen;
- if (geomLen>0) {
- memcpy(str,ptrns->geometry,geomLen);
- str+= geomLen;
- }
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
- goto BAILOUT;
- extraLen= (int)rep.length*4;
- *max_inout= rep.extra;
- if (extraLen==0) { /* no matches, but we don't want to report a failure */
- list= _XkbTypedCalloc(1,XkbComponentListRec);
- UnlockDisplay(dpy);
- SyncHandle();
- return list;
- }
- if (_XkbInitReadBuffer(dpy,&buf,extraLen)) {
- Status status;
-
- status= Success;
- list= _XkbTypedCalloc(1,XkbComponentListRec);
- if (!list) {
- _XkbFreeReadBuffer(&buf);
- goto BAILOUT;
- }
- list->num_keymaps= rep.nKeymaps;
- list->num_keycodes= rep.nKeycodes;
- list->num_types= rep.nTypes;
- list->num_compat= rep.nCompatMaps;
- list->num_symbols= rep.nSymbols;
- list->num_geometry= rep.nGeometries;
- if ((status==Success)&&(list->num_keymaps>0))
- list->keymaps= _ReadListing(&buf,list->num_keymaps,&status);
- if ((status==Success)&&(list->num_keycodes>0))
- list->keycodes= _ReadListing(&buf,list->num_keycodes,&status);
- if ((status==Success)&&(list->num_types>0))
- list->types= _ReadListing(&buf,list->num_types,&status);
- if ((status==Success)&&(list->num_compat>0))
- list->compat= _ReadListing(&buf,list->num_compat,&status);
- if ((status==Success)&&(list->num_symbols>0))
- list->symbols= _ReadListing(&buf,list->num_symbols,&status);
- if ((status==Success)&&(list->num_geometry>0))
- list->geometry= _ReadListing(&buf,list->num_geometry,&status);
- left= _XkbFreeReadBuffer(&buf);
- if ((status!=Success)||(buf.error)||(left>2)) {
- XkbFreeComponentList(list);
- goto BAILOUT;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- return list;
- }
-BAILOUT:
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
-}
-
-void
-XkbFreeComponentList(XkbComponentListPtr list)
-{
- if (list) {
- if (list->keymaps)
- _FreeComponentNames(list->num_keymaps,list->keymaps);
- if (list->keycodes)
- _FreeComponentNames(list->num_keycodes,list->keycodes);
- if (list->types)
- _FreeComponentNames(list->num_types,list->types);
- if (list->compat)
- _FreeComponentNames(list->num_compat,list->compat);
- if (list->symbols)
- _FreeComponentNames(list->num_symbols,list->symbols);
- if (list->geometry)
- _FreeComponentNames(list->num_geometry,list->geometry);
- bzero((char *)list,sizeof(XkbComponentListRec));
- _XkbFree(list);
- }
- return;
-}
+/************************************************************
+Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#define NEED_MAP_READERS
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include <X11/extensions/XKBproto.h>
+#include "XKBlibint.h"
+
+/***====================================================================***/
+
+static void
+_FreeComponentNames(int num,XkbComponentNamePtr names)
+{
+int i;
+XkbComponentNamePtr tmp;
+
+ if ((num<1)||(names==NULL))
+ return;
+ for (i=0,tmp=names;i<num;i++,tmp++) {
+ if (tmp->name) {
+ _XkbFree(tmp->name);
+ tmp->name= NULL;
+ }
+ }
+ _XkbFree(names);
+ return;
+}
+
+/***====================================================================***/
+
+static XkbComponentNamePtr
+_ReadListing(XkbReadBufferPtr buf,int count,Status *status_rtrn)
+{
+XkbComponentNamePtr first,this;
+register int i;
+CARD16 * flags;
+int slen,wlen;
+char * str;
+
+ if (count<1)
+ return NULL;
+ first= _XkbTypedCalloc(count,XkbComponentNameRec);
+ if (!first)
+ return NULL;
+ for (this=first,i=0;i<count;i++,this++) {
+ flags= (CARD16 *)_XkbGetReadBufferPtr(buf,2*sizeof(CARD16));
+ if (!flags)
+ goto BAILOUT;
+ this->flags= flags[0];
+ slen= flags[1];
+ wlen= ((slen+1)/2)*2; /* pad to 2 byte boundary */
+ this->name= _XkbTypedCalloc(slen+1,char);
+ if (!this->name)
+ goto BAILOUT;
+ str= (char *)_XkbGetReadBufferPtr(buf,wlen);
+ if (!str)
+ goto BAILOUT;
+ memcpy(this->name,str,slen);
+ }
+ return first;
+BAILOUT:
+ *status_rtrn= BadAlloc;
+ _FreeComponentNames(i,first);
+ return NULL;
+}
+
+/***====================================================================***/
+
+XkbComponentListPtr
+XkbListComponents( Display * dpy,
+ unsigned deviceSpec,
+ XkbComponentNamesPtr ptrns,
+ int * max_inout)
+{
+register xkbListComponentsReq* req;
+xkbListComponentsReply rep;
+XkbInfoPtr xkbi;
+XkbComponentListPtr list;
+XkbReadBufferRec buf;
+int left;
+char * str;
+int extraLen,len,mapLen,codesLen,typesLen,compatLen,symsLen,geomLen;
+
+ if ( (dpy==NULL) || (dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) ||
+ (ptrns==NULL) || (max_inout==NULL))
+ return NULL;
+
+ xkbi= dpy->xkb_info;
+ LockDisplay(dpy);
+ GetReq(kbListComponents, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbListComponents;
+ req->deviceSpec = deviceSpec;
+ req->maxNames = *max_inout;
+
+ mapLen= codesLen= typesLen= compatLen= symsLen= geomLen= 0;
+ if (ptrns->keymap)
+ mapLen= (int)strlen(ptrns->keymap);
+ if (ptrns->keycodes)
+ codesLen= (int)strlen(ptrns->keycodes);
+ if (ptrns->types)
+ typesLen= (int)strlen(ptrns->types);
+ if (ptrns->compat)
+ compatLen= (int)strlen(ptrns->compat);
+ if (ptrns->symbols)
+ symsLen= (int)strlen(ptrns->symbols);
+ if (ptrns->geometry)
+ geomLen= (int)strlen(ptrns->geometry);
+ if (mapLen>255) mapLen= 255;
+ if (codesLen>255) codesLen= 255;
+ if (typesLen>255) typesLen= 255;
+ if (compatLen>255) compatLen= 255;
+ if (symsLen>255) symsLen= 255;
+ if (geomLen>255) geomLen= 255;
+
+ len= mapLen+codesLen+typesLen+compatLen+symsLen+geomLen+6;
+ len= XkbPaddedSize(len);
+ req->length+= len/4;
+ BufAlloc(char *,str,len);
+ *str++= mapLen;
+ if (mapLen>0) {
+ memcpy(str,ptrns->keymap,mapLen);
+ str+= mapLen;
+ }
+ *str++= codesLen;
+ if (codesLen>0) {
+ memcpy(str,ptrns->keycodes,codesLen);
+ str+= codesLen;
+ }
+ *str++= typesLen;
+ if (typesLen>0) {
+ memcpy(str,ptrns->types,typesLen);
+ str+= typesLen;
+ }
+ *str++= compatLen;
+ if (compatLen>0) {
+ memcpy(str,ptrns->compat,compatLen);
+ str+= compatLen;
+ }
+ *str++= symsLen;
+ if (symsLen>0) {
+ memcpy(str,ptrns->symbols,symsLen);
+ str+= symsLen;
+ }
+ *str++= geomLen;
+ if (geomLen>0) {
+ memcpy(str,ptrns->geometry,geomLen);
+ str+= geomLen;
+ }
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
+ goto BAILOUT;
+ extraLen= (int)rep.length*4;
+ *max_inout= rep.extra;
+ if (extraLen==0) { /* no matches, but we don't want to report a failure */
+ list= _XkbTypedCalloc(1,XkbComponentListRec);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return list;
+ }
+ if (_XkbInitReadBuffer(dpy,&buf,extraLen)) {
+ Status status;
+
+ status= Success;
+ list= _XkbTypedCalloc(1,XkbComponentListRec);
+ if (!list) {
+ _XkbFreeReadBuffer(&buf);
+ goto BAILOUT;
+ }
+ list->num_keymaps= rep.nKeymaps;
+ list->num_keycodes= rep.nKeycodes;
+ list->num_types= rep.nTypes;
+ list->num_compat= rep.nCompatMaps;
+ list->num_symbols= rep.nSymbols;
+ list->num_geometry= rep.nGeometries;
+ if ((status==Success)&&(list->num_keymaps>0))
+ list->keymaps= _ReadListing(&buf,list->num_keymaps,&status);
+ if ((status==Success)&&(list->num_keycodes>0))
+ list->keycodes= _ReadListing(&buf,list->num_keycodes,&status);
+ if ((status==Success)&&(list->num_types>0))
+ list->types= _ReadListing(&buf,list->num_types,&status);
+ if ((status==Success)&&(list->num_compat>0))
+ list->compat= _ReadListing(&buf,list->num_compat,&status);
+ if ((status==Success)&&(list->num_symbols>0))
+ list->symbols= _ReadListing(&buf,list->num_symbols,&status);
+ if ((status==Success)&&(list->num_geometry>0))
+ list->geometry= _ReadListing(&buf,list->num_geometry,&status);
+ left= _XkbFreeReadBuffer(&buf);
+ if ((status!=Success)||(buf.error)||(left>2)) {
+ XkbFreeComponentList(list);
+ goto BAILOUT;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return list;
+ }
+BAILOUT:
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+}
+
+void
+XkbFreeComponentList(XkbComponentListPtr list)
+{
+ if (list) {
+ if (list->keymaps)
+ _FreeComponentNames(list->num_keymaps,list->keymaps);
+ if (list->keycodes)
+ _FreeComponentNames(list->num_keycodes,list->keycodes);
+ if (list->types)
+ _FreeComponentNames(list->num_types,list->types);
+ if (list->compat)
+ _FreeComponentNames(list->num_compat,list->compat);
+ if (list->symbols)
+ _FreeComponentNames(list->num_symbols,list->symbols);
+ if (list->geometry)
+ _FreeComponentNames(list->num_geometry,list->geometry);
+ bzero((char *)list,sizeof(XkbComponentListRec));
+ _XkbFree(list);
+ }
+ return;
+}
diff --git a/libX11/src/xkb/XKBMisc.c b/libX11/src/xkb/XKBMisc.c
index f736d1851..ac1e8c062 100644
--- a/libX11/src/xkb/XKBMisc.c
+++ b/libX11/src/xkb/XKBMisc.c
@@ -1,979 +1,979 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#elif defined(HAVE_CONFIG_H)
-#include <config.h>
-#endif
-
-#ifndef XKB_IN_SERVER
-
-#include <stdio.h>
-#include "Xlibint.h"
-#include <X11/extensions/XKBproto.h>
-#include <X11/keysym.h>
-#include "XKBlibint.h"
-
-#else
-
-#include <stdio.h>
-#include <X11/X.h>
-#define XkbVirtualModsToReal SrvXkbVirtualModsToReal
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "inputstr.h"
-#include <X11/keysym.h>
-#define XKBSRV_NEED_FILE_FUNCS
-#include <X11/extensions/XKBsrv.h>
-
-#endif /* XKB_IN_SERVER */
-
-/***====================================================================***/
-
-#define mapSize(m) (sizeof(m)/sizeof(XkbKTMapEntryRec))
-static XkbKTMapEntryRec map2Level[]= {
- { True, ShiftMask, {1, ShiftMask, 0} }
-};
-
-static XkbKTMapEntryRec mapAlpha[]= {
- { True, ShiftMask, { 1, ShiftMask, 0 } },
- { True, LockMask, { 0, LockMask, 0 } }
-};
-
-static XkbModsRec preAlpha[]= {
- { 0, 0, 0 },
- { LockMask, LockMask, 0 }
-};
-
-#define NL_VMOD_MASK 0
-static XkbKTMapEntryRec mapKeypad[]= {
- { True, ShiftMask, { 1, ShiftMask, 0 } },
- { False, 0, { 1, 0, NL_VMOD_MASK } }
-};
-
-static XkbKeyTypeRec canonicalTypes[XkbNumRequiredTypes] = {
- { { 0, 0, 0 },
- 1, /* num_levels */
- 0, /* map_count */
- NULL, NULL,
- None, NULL
- },
- { { ShiftMask, ShiftMask, 0 },
- 2, /* num_levels */
- mapSize(map2Level), /* map_count */
- map2Level, NULL,
- None, NULL
- },
- { { ShiftMask|LockMask, ShiftMask|LockMask, 0 },
- 2, /* num_levels */
- mapSize(mapAlpha), /* map_count */
- mapAlpha, preAlpha,
- None, NULL
- },
- { { ShiftMask, ShiftMask, NL_VMOD_MASK },
- 2, /* num_levels */
- mapSize(mapKeypad), /* map_count */
- mapKeypad, NULL,
- None, NULL
- }
-};
-
-Status
-XkbInitCanonicalKeyTypes(XkbDescPtr xkb,unsigned which,int keypadVMod)
-{
-XkbClientMapPtr map;
-XkbKeyTypePtr from,to;
-Status rtrn;
-
- if (!xkb)
- return BadMatch;
- rtrn= XkbAllocClientMap(xkb,XkbKeyTypesMask,XkbNumRequiredTypes);
- if (rtrn!=Success)
- return rtrn;
- map= xkb->map;
- if ((which&XkbAllRequiredTypes)==0)
- return Success;
- rtrn= Success;
- from= canonicalTypes;
- to= map->types;
- if (which&XkbOneLevelMask)
- rtrn= XkbCopyKeyType(&from[XkbOneLevelIndex],&to[XkbOneLevelIndex]);
- if ((which&XkbTwoLevelMask)&&(rtrn==Success))
- rtrn= XkbCopyKeyType(&from[XkbTwoLevelIndex],&to[XkbTwoLevelIndex]);
- if ((which&XkbAlphabeticMask)&&(rtrn==Success))
- rtrn= XkbCopyKeyType(&from[XkbAlphabeticIndex],&to[XkbAlphabeticIndex]);
- if ((which&XkbKeypadMask)&&(rtrn==Success)) {
- XkbKeyTypePtr type;
- rtrn= XkbCopyKeyType(&from[XkbKeypadIndex],&to[XkbKeypadIndex]);
- type= &to[XkbKeypadIndex];
- if ((keypadVMod>=0)&&(keypadVMod<XkbNumVirtualMods)&&(rtrn==Success)) {
- type->mods.vmods= (1<<keypadVMod);
- type->map[0].active= True;
- type->map[0].mods.mask= ShiftMask;
- type->map[0].mods.real_mods= ShiftMask;
- type->map[0].mods.vmods= 0;
- type->map[0].level= 1;
- type->map[1].active= False;
- type->map[1].mods.mask= 0;
- type->map[1].mods.real_mods= 0;
- type->map[1].mods.vmods= (1<<keypadVMod);
- type->map[1].level= 1;
- }
- }
- return Success;
-}
-
-/***====================================================================***/
-
-#define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol)
-#define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l))
-
-int
-XkbKeyTypesForCoreSymbols( XkbDescPtr xkb,
- int map_width,
- KeySym * core_syms,
- unsigned int protected,
- int * types_inout,
- KeySym * xkb_syms_rtrn)
-{
-register int i;
-unsigned int empty;
-int nSyms[XkbNumKbdGroups];
-int nGroups,tmp,groupsWidth;
-
- /* Section 12.2 of the protocol describes this process in more detail */
- /* Step 1: find the # of symbols in the core mapping per group */
- groupsWidth= 2;
- for (i=0;i<XkbNumKbdGroups;i++) {
- if ((protected&(1<<i))&&(types_inout[i]<xkb->map->num_types)) {
- nSyms[i]= xkb->map->types[types_inout[i]].num_levels;
- if (nSyms[i]>groupsWidth)
- groupsWidth= nSyms[i];
- }
- else {
- types_inout[i]= XkbTwoLevelIndex; /* don't really know, yet */
- nSyms[i]= 2;
- }
- }
- if (nSyms[XkbGroup1Index]<2)
- nSyms[XkbGroup1Index]= 2;
- if (nSyms[XkbGroup2Index]<2)
- nSyms[XkbGroup2Index]= 2;
- /* Step 2: Copy the symbols from the core ordering to XKB ordering */
- /* symbols in the core are in the order: */
- /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,0)]= CORE_SYM(0);
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,1)]= CORE_SYM(1);
- for (i=2;i<nSyms[XkbGroup1Index];i++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,i)]= CORE_SYM(2+i);
- }
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,0)]= CORE_SYM(2);
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,1)]= CORE_SYM(3);
- tmp= 2+(nSyms[XkbGroup1Index]-2); /* offset to extra group2 syms */
- for (i=2;i<nSyms[XkbGroup2Index];i++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,i)]= CORE_SYM(tmp+i);
- }
- tmp= nSyms[XkbGroup1Index]+nSyms[XkbGroup2Index];
- if ((tmp>=map_width)&&
- ((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) {
- nSyms[XkbGroup3Index]= 0;
- nSyms[XkbGroup4Index]= 0;
- nGroups= 2;
- }
- else {
- nGroups= 3;
- for (i=0;i<nSyms[XkbGroup3Index];i++,tmp++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index,i)]= CORE_SYM(tmp);
- }
- if ((tmp<map_width)||(protected&XkbExplicitKeyType4Mask)) {
- nGroups= 4;
- for (i=0;i<nSyms[XkbGroup4Index];i++,tmp++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index,i)]= CORE_SYM(tmp);
- }
- }
- else {
- nSyms[XkbGroup4Index]= 0;
- }
- }
- /* steps 3&4: alphanumeric expansion, assign canonical types */
- empty= 0;
- for (i=0;i<nGroups;i++) {
- KeySym *syms;
- syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
- if ((nSyms[i]>1)&&(syms[1]==NoSymbol)&&(syms[0]!=NoSymbol)) {
- KeySym upper,lower;
- XConvertCase(syms[0],&lower,&upper);
- if (upper!=lower) {
- xkb_syms_rtrn[XKB_OFFSET(i,0)]= lower;
- xkb_syms_rtrn[XKB_OFFSET(i,1)]= upper;
- if ((protected&(1<<i))==0)
- types_inout[i]= XkbAlphabeticIndex;
- }
- else if ((protected&(1<<i))==0) {
- types_inout[i]= XkbOneLevelIndex;
- /* nSyms[i]= 1;*/
- }
- }
- if (((protected&(1<<i))==0)&&(types_inout[i]==XkbTwoLevelIndex)) {
- if (IsKeypadKey(syms[0])||IsKeypadKey(syms[1]))
- types_inout[i]= XkbKeypadIndex;
- else {
- KeySym upper,lower;
- XConvertCase(syms[0],&lower,&upper);
- if ((syms[0]==lower)&&(syms[1]==upper))
- types_inout[i]= XkbAlphabeticIndex;
- }
- }
- if (syms[0]==NoSymbol) {
- register int n;
- Bool found;
- for (n=1,found=False;(!found)&&(n<nSyms[i]);n++) {
- found= (syms[n]!=NoSymbol);
- }
- if (!found)
- empty|= (1<<i);
- }
- }
- /* step 5: squoosh out empty groups */
- if (empty) {
- for (i=nGroups-1;i>=0;i--) {
- if (((empty&(1<<i))==0)||(protected&(1<<i)))
- break;
- nGroups--;
- }
- }
- if (nGroups<1)
- return 0;
-
- /* step 6: replicate group 1 into group two, if necessary */
- if ((nGroups>1)&&((empty&(XkbGroup1Mask|XkbGroup2Mask))==XkbGroup2Mask)) {
- if ((protected&(XkbExplicitKeyType1Mask|XkbExplicitKeyType2Mask))==0) {
- nSyms[XkbGroup2Index]= nSyms[XkbGroup1Index];
- types_inout[XkbGroup2Index]= types_inout[XkbGroup1Index];
- memcpy((char *)&xkb_syms_rtrn[2],(char *)xkb_syms_rtrn,
- 2*sizeof(KeySym));
- }
- else if (types_inout[XkbGroup1Index]==types_inout[XkbGroup2Index]) {
- memcpy((char *)&xkb_syms_rtrn[nSyms[XkbGroup1Index]],
- (char *)xkb_syms_rtrn,
- nSyms[XkbGroup1Index]*sizeof(KeySym));
- }
- }
-
- /* step 7: check for all groups identical or all width 1 */
- if (nGroups>1) {
- Bool sameType,allOneLevel;
- allOneLevel= (xkb->map->types[types_inout[0]].num_levels==1);
- for (i=1,sameType=True;(allOneLevel||sameType)&&(i<nGroups);i++) {
- sameType=(sameType&&(types_inout[i]==types_inout[XkbGroup1Index]));
- if (allOneLevel)
- allOneLevel= (xkb->map->types[types_inout[i]].num_levels==1);
- }
- if ((sameType)&&
- (!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){
- register int s;
- Bool identical;
- for (i=1,identical=True;identical&&(i<nGroups);i++) {
- KeySym *syms;
- syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
- for (s=0;identical&&(s<nSyms[i]);s++) {
- if (syms[s]!=xkb_syms_rtrn[s])
- identical= False;
- }
- }
- if (identical)
- nGroups= 1;
- }
- if (allOneLevel && (nGroups>1)) {
- KeySym *syms;
- syms= &xkb_syms_rtrn[nSyms[XkbGroup1Index]];
- nSyms[XkbGroup1Index]= 1;
- for (i=1;i<nGroups;i++) {
- xkb_syms_rtrn[i]= syms[0];
- syms+= nSyms[i];
- nSyms[i]= 1;
- }
- }
- }
- return nGroups;
-}
-
-static XkbSymInterpretPtr
-_XkbFindMatchingInterp( XkbDescPtr xkb,
- KeySym sym,
- unsigned int real_mods,
- unsigned int level)
-{
-register unsigned i;
-XkbSymInterpretPtr interp,rtrn;
-CARD8 mods;
-
- rtrn= NULL;
- interp= xkb->compat->sym_interpret;
- for (i=0;i<xkb->compat->num_si;i++,interp++) {
- if ((interp->sym==NoSymbol)||(sym==interp->sym)) {
- int match;
- if ((level==0)||((interp->match&XkbSI_LevelOneOnly)==0))
- mods= real_mods;
- else mods= 0;
- switch (interp->match&XkbSI_OpMask) {
- case XkbSI_NoneOf:
- match= ((interp->mods&mods)==0);
- break;
- case XkbSI_AnyOfOrNone:
- match= ((mods==0)||((interp->mods&mods)!=0));
- break;
- case XkbSI_AnyOf:
- match= ((interp->mods&mods)!=0);
- break;
- case XkbSI_AllOf:
- match= ((interp->mods&mods)==interp->mods);
- break;
- case XkbSI_Exactly:
- match= (interp->mods==mods);
- break;
- default:
- match= 0;
- break;
- }
- if (match) {
- if (interp->sym!=NoSymbol) {
- return interp;
- }
- else if (rtrn==NULL) {
- rtrn= interp;
- }
- }
- }
- }
- return rtrn;
-}
-
-static void
-_XkbAddKeyChange(KeyCode *pFirst,unsigned char *pNum,KeyCode newKey)
-{
-KeyCode last;
-
- last= (*pFirst)+(*pNum);
- if (newKey<*pFirst) {
- *pFirst= newKey;
- *pNum= (last-newKey)+1;
- }
- else if (newKey>last) {
- *pNum= (last-*pFirst)+1;
- }
- return;
-}
-
-static void
-_XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
-{
-unsigned tmp;
-
- switch (act->type) {
- case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
- if (act->mods.flags&XkbSA_UseModMapMods)
- act->mods.real_mods= act->mods.mask= mods;
- if ((tmp= XkbModActionVMods(&act->mods))!=0) {
- XkbVirtualModsToReal(xkb,tmp,&tmp);
- act->mods.mask|= tmp;
- }
- break;
- case XkbSA_ISOLock:
- if (act->iso.flags&XkbSA_UseModMapMods)
- act->iso.real_mods= act->iso.mask= mods;
- if ((tmp= XkbModActionVMods(&act->iso))!=0) {
- XkbVirtualModsToReal(xkb,tmp,&tmp);
- act->iso.mask|= tmp;
- }
- break;
- }
- return;
-}
-
-#define IBUF_SIZE 8
-
-Bool
-XkbApplyCompatMapToKey(XkbDescPtr xkb,KeyCode key,XkbChangesPtr changes)
-{
-KeySym * syms;
-unsigned char explicit,mods;
-XkbSymInterpretPtr *interps,ibuf[IBUF_SIZE];
-int n,nSyms,found;
-unsigned changed,tmp;
-
- if ((!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)||
- (!xkb->compat)||(!xkb->compat->sym_interpret)||
- (key<xkb->min_key_code)||(key>xkb->max_key_code)) {
- return False;
- }
- if (((!xkb->server)||(!xkb->server->key_acts))&&
- (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success)) {
- return False;
- }
- changed= 0; /* keeps track of what has changed in _this_ call */
- explicit= xkb->server->explicit[key];
- if (explicit&XkbExplicitInterpretMask) /* nothing to do */
- return True;
- mods= (xkb->map->modmap?xkb->map->modmap[key]:0);
- nSyms= XkbKeyNumSyms(xkb,key);
- syms= XkbKeySymsPtr(xkb,key);
- if (nSyms>IBUF_SIZE) {
- interps= _XkbTypedCalloc(nSyms,XkbSymInterpretPtr);
- if (interps==NULL) {
- interps= ibuf;
- nSyms= IBUF_SIZE;
- }
- }
- else {
- interps= ibuf;
- }
- found= 0;
- for (n=0;n<nSyms;n++) {
- unsigned level= (n%XkbKeyGroupsWidth(xkb,key));
- interps[n]= NULL;
- if (syms[n]!=NoSymbol) {
- interps[n]= _XkbFindMatchingInterp(xkb,syms[n],mods,level);
- if (interps[n]&&interps[n]->act.type!=XkbSA_NoAction)
- found++;
- else interps[n]= NULL;
- }
- }
- /* 1/28/96 (ef) -- XXX! WORKING HERE */
- if (!found) {
- if (xkb->server->key_acts[key]!=0) {
- xkb->server->key_acts[key]= 0;
- changed|= XkbKeyActionsMask;
- }
- }
- else {
- XkbAction *pActs;
- unsigned int new_vmodmask;
- changed|= XkbKeyActionsMask;
- pActs= XkbResizeKeyActions(xkb,key,nSyms);
- if (!pActs) {
- if (nSyms > IBUF_SIZE)
- Xfree(interps);
- return False;
- }
- new_vmodmask= 0;
- for (n=0;n<nSyms;n++) {
- if (interps[n]) {
- unsigned effMods;
-
- pActs[n]= *((XkbAction *)&interps[n]->act);
- if ((n==0)||((interps[n]->match&XkbSI_LevelOneOnly)==0)) {
- effMods= mods;
- if (interps[n]->virtual_mod!=XkbNoModifier)
- new_vmodmask|= (1<<interps[n]->virtual_mod);
- }
- else effMods= 0;
- _XkbSetActionKeyMods(xkb,&pActs[n],effMods);
- }
- else pActs[n].type= XkbSA_NoAction;
- }
- if (((explicit&XkbExplicitVModMapMask)==0)&&
- (xkb->server->vmodmap[key]!=new_vmodmask)) {
- changed|= XkbVirtualModMapMask;
- xkb->server->vmodmap[key]= new_vmodmask;
- }
- if (interps[0]) {
- if ((interps[0]->flags&XkbSI_LockingKey)&&
- ((explicit&XkbExplicitBehaviorMask)==0)) {
- xkb->server->behaviors[key].type= XkbKB_Lock;
- changed|= XkbKeyBehaviorsMask;
- }
- if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
- CARD8 old;
- old= xkb->ctrls->per_key_repeat[key/8];
- if (interps[0]->flags&XkbSI_AutoRepeat)
- xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
- else xkb->ctrls->per_key_repeat[key/8]&= ~(1<<(key%8));
- if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
- changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
- }
- }
- }
- if ((!found)||(interps[0]==NULL)) {
- if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
- CARD8 old;
- old= xkb->ctrls->per_key_repeat[key/8];
-#ifdef RETURN_SHOULD_REPEAT
- if (*XkbKeySymsPtr(xkb,key) != XK_Return)
-#endif
- xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
- if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
- changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
- }
- if (((explicit&XkbExplicitBehaviorMask)==0)&&
- (xkb->server->behaviors[key].type==XkbKB_Lock)) {
- xkb->server->behaviors[key].type= XkbKB_Default;
- changed|= XkbKeyBehaviorsMask;
- }
- }
- if (changes) {
- XkbMapChangesPtr mc;
- mc= &changes->map;
- tmp= (changed&mc->changed);
- if (tmp&XkbKeyActionsMask)
- _XkbAddKeyChange(&mc->first_key_act,&mc->num_key_acts,key);
- else if (changed&XkbKeyActionsMask) {
- mc->changed|= XkbKeyActionsMask;
- mc->first_key_act= key;
- mc->num_key_acts= 1;
- }
- if (tmp&XkbKeyBehaviorsMask) {
- _XkbAddKeyChange(&mc->first_key_behavior,&mc->num_key_behaviors,
- key);
- }
- else if (changed&XkbKeyBehaviorsMask) {
- mc->changed|= XkbKeyBehaviorsMask;
- mc->first_key_behavior= key;
- mc->num_key_behaviors= 1;
- }
- if (tmp&XkbVirtualModMapMask)
- _XkbAddKeyChange(&mc->first_vmodmap_key,&mc->num_vmodmap_keys,key);
- else if (changed&XkbVirtualModMapMask) {
- mc->changed|= XkbVirtualModMapMask;
- mc->first_vmodmap_key= key;
- mc->num_vmodmap_keys= 1;
- }
- mc->changed|= changed;
- }
- if (interps!=ibuf)
- _XkbFree(interps);
- return True;
-}
-
-Bool
-XkbUpdateMapFromCore( XkbDescPtr xkb,
- KeyCode first_key,
- int num_keys,
- int map_width,
- KeySym * core_keysyms,
- XkbChangesPtr changes)
-{
-register int key,last_key;
-KeySym * syms;
-
- syms= &core_keysyms[(first_key-xkb->min_key_code)*map_width];
- if (changes) {
- if (changes->map.changed&XkbKeySymsMask) {
- _XkbAddKeyChange(&changes->map.first_key_sym,
- &changes->map.num_key_syms,first_key);
- if (num_keys>1) {
- _XkbAddKeyChange(&changes->map.first_key_sym,
- &changes->map.num_key_syms,
- first_key+num_keys-1);
- }
- }
- else {
- changes->map.changed|= XkbKeySymsMask;
- changes->map.first_key_sym= first_key;
- changes->map.num_key_syms= num_keys;
- }
- }
- last_key= first_key+num_keys-1;
- for (key=first_key;key<=last_key;key++,syms+= map_width) {
- XkbMapChangesPtr mc;
- unsigned explicit;
- KeySym tsyms[XkbMaxSymsPerKey];
- int types[XkbNumKbdGroups];
- int nG;
-
- explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask;
- types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
- types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index);
- types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index);
- types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index);
- nG= XkbKeyTypesForCoreSymbols(xkb,map_width,syms,explicit,types,tsyms);
- if (changes)
- mc= &changes->map;
- else mc= NULL;
- XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc);
- memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms,
- XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
- XkbApplyCompatMapToKey(xkb,key,changes);
- }
-
- if ((xkb->server->vmods!=NULL)&&(xkb->map->modmap!=NULL)&&(changes)&&
- (changes->map.changed&(XkbVirtualModMapMask|XkbModifierMapMask))) {
- unsigned char newVMods[XkbNumVirtualMods];
- register unsigned bit,i;
- unsigned present;
-
- bzero(newVMods,XkbNumVirtualMods);
- present= 0;
- for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
- if (xkb->server->vmodmap[key]==0)
- continue;
- for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if (bit&xkb->server->vmodmap[key]) {
- present|= bit;
- newVMods[i]|= xkb->map->modmap[key];
- }
- }
- }
- for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if ((bit&present)&&(newVMods[i]!=xkb->server->vmods[i])) {
- changes->map.changed|= XkbVirtualModsMask;
- changes->map.vmods|= bit;
- xkb->server->vmods[i]= newVMods[i];
- }
- }
- }
- if (changes && (changes->map.changed&XkbVirtualModsMask))
- XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes);
- return True;
-}
-
-Status
-XkbChangeTypesOfKey( XkbDescPtr xkb,
- int key,
- int nGroups,
- unsigned groups,
- int * newTypesIn,
- XkbMapChangesPtr changes)
-{
-XkbKeyTypePtr pOldType,pNewType;
-register int i;
-int width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups];
-
- if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) ||
- (!xkb->map->types)||((groups&XkbAllGroupsMask)==0)||
- (nGroups>XkbNumKbdGroups)) {
- return BadMatch;
- }
- if (nGroups==0) {
- for (i=0;i<XkbNumKbdGroups;i++) {
- xkb->map->key_sym_map[key].kt_index[i]= XkbOneLevelIndex;
- }
- i= xkb->map->key_sym_map[key].group_info;
- i= XkbSetNumGroups(i,0);
- xkb->map->key_sym_map[key].group_info= i;
- XkbResizeKeySyms(xkb,key,0);
- return Success;
- }
-
- nOldGroups= XkbKeyNumGroups(xkb,key);
- oldWidth= XkbKeyGroupsWidth(xkb,key);
- for (width=i=0;i<nGroups;i++) {
- if (groups&(1<<i))
- newTypes[i]= newTypesIn[i];
- else if (i<nOldGroups)
- newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,i);
- else if (nOldGroups>0)
- newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
- else newTypes[i]= XkbTwoLevelIndex;
- if (newTypes[i]>xkb->map->num_types)
- return BadMatch;
- pNewType= &xkb->map->types[newTypes[i]];
- if (pNewType->num_levels>width)
- width= pNewType->num_levels;
- }
- if ((xkb->ctrls)&&(nGroups>xkb->ctrls->num_groups))
- xkb->ctrls->num_groups= nGroups;
- if ((width!=oldWidth)||(nGroups!=nOldGroups)) {
- KeySym oldSyms[XkbMaxSymsPerKey],*pSyms;
- int nCopy;
-
- if (nOldGroups==0) {
- pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
- if (pSyms!=NULL) {
- i= xkb->map->key_sym_map[key].group_info;
- i= XkbSetNumGroups(i,nGroups);
- xkb->map->key_sym_map[key].group_info= i;
- xkb->map->key_sym_map[key].width= width;
- for (i=0;i<nGroups;i++) {
- xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
- }
- return Success;
- }
- return BadAlloc;
- }
- pSyms= XkbKeySymsPtr(xkb,key);
- memcpy(oldSyms,pSyms,XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
- pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
- if (pSyms==NULL)
- return BadAlloc;
- bzero(pSyms,width*nGroups*sizeof(KeySym));
- for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
- pOldType= XkbKeyKeyType(xkb,key,i);
- pNewType= &xkb->map->types[newTypes[i]];
- if (pNewType->num_levels>pOldType->num_levels)
- nCopy= pOldType->num_levels;
- else nCopy= pNewType->num_levels;
- memcpy(&pSyms[i*width],&oldSyms[i*oldWidth],nCopy*sizeof(KeySym));
- }
- if (XkbKeyHasActions(xkb,key)) {
- XkbAction oldActs[XkbMaxSymsPerKey],*pActs;
- pActs= XkbKeyActionsPtr(xkb,key);
- memcpy(oldActs,pActs,XkbKeyNumSyms(xkb,key)*sizeof(XkbAction));
- pActs= XkbResizeKeyActions(xkb,key,width*nGroups);
- if (pActs==NULL)
- return BadAlloc;
- bzero(pActs,width*nGroups*sizeof(XkbAction));
- for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
- pOldType= XkbKeyKeyType(xkb,key,i);
- pNewType= &xkb->map->types[newTypes[i]];
- if (pNewType->num_levels>pOldType->num_levels)
- nCopy= pOldType->num_levels;
- else nCopy= pNewType->num_levels;
- memcpy(&pActs[i*width],&oldActs[i*oldWidth],
- nCopy*sizeof(XkbAction));
- }
- }
- i= xkb->map->key_sym_map[key].group_info;
- i= XkbSetNumGroups(i,nGroups);
- xkb->map->key_sym_map[key].group_info= i;
- xkb->map->key_sym_map[key].width= width;
- }
- width= 0;
- for (i=0;i<nGroups;i++) {
- xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
- if (xkb->map->types[newTypes[i]].num_levels>width)
- width= xkb->map->types[newTypes[i]].num_levels;
- }
- xkb->map->key_sym_map[key].width= width;
- if (changes!=NULL) {
- if (changes->changed&XkbKeySymsMask) {
- _XkbAddKeyChange(&changes->first_key_sym,&changes->num_key_syms,
- key);
- }
- else {
- changes->changed|= XkbKeySymsMask;
- changes->first_key_sym= key;
- changes->num_key_syms= 1;
- }
- }
- return Success;
-}
-
-/***====================================================================***/
-
-Bool
-XkbVirtualModsToReal(XkbDescPtr xkb,unsigned virtual_mask,unsigned *mask_rtrn)
-{
-register int i,bit;
-register unsigned mask;
-
- if (xkb==NULL)
- return False;
- if (virtual_mask==0) {
- *mask_rtrn= 0;
- return True;
- }
- if (xkb->server==NULL)
- return False;
- for (i=mask=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if (virtual_mask&bit)
- mask|= xkb->server->vmods[i];
- }
- *mask_rtrn= mask;
- return True;
-}
-
-/***====================================================================***/
-
-Bool
-XkbUpdateActionVirtualMods(XkbDescPtr xkb,XkbAction *act,unsigned changed)
-{
-unsigned int tmp;
-
- switch (act->type) {
- case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
- if (((tmp= XkbModActionVMods(&act->mods))&changed)!=0) {
- XkbVirtualModsToReal(xkb,tmp,&tmp);
- act->mods.mask= act->mods.real_mods;
- act->mods.mask|= tmp;
- return True;
- }
- break;
- case XkbSA_ISOLock:
- if ((((tmp= XkbModActionVMods(&act->iso))!=0)&changed)!=0) {
- XkbVirtualModsToReal(xkb,tmp,&tmp);
- act->iso.mask= act->iso.real_mods;
- act->iso.mask|= tmp;
- return True;
- }
- break;
- }
- return False;
-}
-
-void
-XkbUpdateKeyTypeVirtualMods( XkbDescPtr xkb,
- XkbKeyTypePtr type,
- unsigned int changed,
- XkbChangesPtr changes)
-{
-register unsigned int i;
-unsigned int mask;
-
- XkbVirtualModsToReal(xkb,type->mods.vmods,&mask);
- type->mods.mask= type->mods.real_mods|mask;
- if ((type->map_count>0)&&(type->mods.vmods!=0)) {
- XkbKTMapEntryPtr entry;
- for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
- if (entry->mods.vmods!=0) {
- XkbVirtualModsToReal(xkb,entry->mods.vmods,&mask);
- entry->mods.mask=entry->mods.real_mods|mask;
- /* entry is active if vmods are bound*/
- entry->active= (mask!=0);
- }
- else entry->active= 1;
- }
- }
- if (changes) {
- int type_ndx;
- type_ndx= type-xkb->map->types;
- if ((type_ndx<0)||(type_ndx>xkb->map->num_types))
- return;
- if (changes->map.changed&XkbKeyTypesMask) {
- int last;
- last= changes->map.first_type+changes->map.num_types-1;
- if (type_ndx<changes->map.first_type) {
- changes->map.first_type= type_ndx;
- changes->map.num_types= (last-type_ndx)+1;
- }
- else if (type_ndx>last) {
- changes->map.num_types= (type_ndx-changes->map.first_type)+1;
- }
- }
- else {
- changes->map.changed|= XkbKeyTypesMask;
- changes->map.first_type= type_ndx;
- changes->map.num_types= 1;
- }
- }
- return;
-}
-
-Bool
-XkbApplyVirtualModChanges(XkbDescPtr xkb,unsigned changed,XkbChangesPtr changes)
-{
-register int i;
-unsigned int checkState = 0;
-
- if ((!xkb) || (!xkb->map) || (changed==0))
- return False;
- for (i=0;i<xkb->map->num_types;i++) {
- if (xkb->map->types[i].mods.vmods & changed)
- XkbUpdateKeyTypeVirtualMods(xkb,&xkb->map->types[i],changed,changes);
- }
- if (changed&xkb->ctrls->internal.vmods) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb,xkb->ctrls->internal.vmods,&newMask);
- newMask|= xkb->ctrls->internal.real_mods;
- if (xkb->ctrls->internal.mask!=newMask) {
- xkb->ctrls->internal.mask= newMask;
- if (changes) {
- changes->ctrls.changed_ctrls|= XkbInternalModsMask;
- checkState= True;
- }
- }
- }
- if (changed&xkb->ctrls->ignore_lock.vmods) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb,xkb->ctrls->ignore_lock.vmods,&newMask);
- newMask|= xkb->ctrls->ignore_lock.real_mods;
- if (xkb->ctrls->ignore_lock.mask!=newMask) {
- xkb->ctrls->ignore_lock.mask= newMask;
- if (changes) {
- changes->ctrls.changed_ctrls|= XkbIgnoreLockModsMask;
- checkState= True;
- }
- }
- }
- if (xkb->indicators!=NULL) {
- XkbIndicatorMapPtr map;
- map= &xkb->indicators->maps[0];
- for (i=0;i<XkbNumIndicators;i++,map++) {
- if (map->mods.vmods&changed) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb,map->mods.vmods,&newMask);
- newMask|= map->mods.real_mods;
- if (newMask!=map->mods.mask) {
- map->mods.mask= newMask;
- if (changes) {
- changes->indicators.map_changes|= (1<<i);
- checkState= True;
- }
- }
- }
- }
- }
- if (xkb->compat!=NULL) {
- XkbCompatMapPtr compat;
- compat= xkb->compat;
- for (i=0;i<XkbNumKbdGroups;i++) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb,compat->groups[i].vmods,&newMask);
- newMask|= compat->groups[i].real_mods;
- if (compat->groups[i].mask!=newMask) {
- compat->groups[i].mask= newMask;
- if (changes) {
- changes->compat.changed_groups|= (1<<i);
- checkState= True;
- }
- }
- }
- }
- if (xkb->map && xkb->server) {
- int highChange = 0, lowChange = -1;
- for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
- if (XkbKeyHasActions(xkb,i)) {
- register XkbAction *pAct;
- register int n;
-
- pAct= XkbKeyActionsPtr(xkb,i);
- for (n=XkbKeyNumActions(xkb,i);n>0;n--,pAct++) {
- if ((pAct->type!=XkbSA_NoAction)&&
- XkbUpdateActionVirtualMods(xkb,pAct,changed)) {
- if (lowChange<0)
- lowChange= i;
- highChange= i;
- }
- }
- }
- }
- if (changes && (lowChange>0)) { /* something changed */
- if (changes->map.changed&XkbKeyActionsMask) {
- int last;
- if (changes->map.first_key_act<lowChange)
- lowChange= changes->map.first_key_act;
- last= changes->map.first_key_act+changes->map.num_key_acts-1;
- if (last>highChange)
- highChange= last;
- }
- changes->map.changed|= XkbKeyActionsMask;
- changes->map.first_key_act= lowChange;
- changes->map.num_key_acts= (highChange-lowChange)+1;
- }
- }
- return checkState;
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#ifndef XKB_IN_SERVER
+
+#include <stdio.h>
+#include "Xlibint.h"
+#include <X11/extensions/XKBproto.h>
+#include <X11/keysym.h>
+#include "XKBlibint.h"
+
+#else
+
+#include <stdio.h>
+#include <X11/X.h>
+#define XkbVirtualModsToReal SrvXkbVirtualModsToReal
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <X11/keysym.h>
+#define XKBSRV_NEED_FILE_FUNCS
+#include <X11/extensions/XKBsrv.h>
+
+#endif /* XKB_IN_SERVER */
+
+/***====================================================================***/
+
+#define mapSize(m) (sizeof(m)/sizeof(XkbKTMapEntryRec))
+static XkbKTMapEntryRec map2Level[]= {
+ { True, ShiftMask, {1, ShiftMask, 0} }
+};
+
+static XkbKTMapEntryRec mapAlpha[]= {
+ { True, ShiftMask, { 1, ShiftMask, 0 } },
+ { True, LockMask, { 0, LockMask, 0 } }
+};
+
+static XkbModsRec preAlpha[]= {
+ { 0, 0, 0 },
+ { LockMask, LockMask, 0 }
+};
+
+#define NL_VMOD_MASK 0
+static XkbKTMapEntryRec mapKeypad[]= {
+ { True, ShiftMask, { 1, ShiftMask, 0 } },
+ { False, 0, { 1, 0, NL_VMOD_MASK } }
+};
+
+static XkbKeyTypeRec canonicalTypes[XkbNumRequiredTypes] = {
+ { { 0, 0, 0 },
+ 1, /* num_levels */
+ 0, /* map_count */
+ NULL, NULL,
+ None, NULL
+ },
+ { { ShiftMask, ShiftMask, 0 },
+ 2, /* num_levels */
+ mapSize(map2Level), /* map_count */
+ map2Level, NULL,
+ None, NULL
+ },
+ { { ShiftMask|LockMask, ShiftMask|LockMask, 0 },
+ 2, /* num_levels */
+ mapSize(mapAlpha), /* map_count */
+ mapAlpha, preAlpha,
+ None, NULL
+ },
+ { { ShiftMask, ShiftMask, NL_VMOD_MASK },
+ 2, /* num_levels */
+ mapSize(mapKeypad), /* map_count */
+ mapKeypad, NULL,
+ None, NULL
+ }
+};
+
+Status
+XkbInitCanonicalKeyTypes(XkbDescPtr xkb,unsigned which,int keypadVMod)
+{
+XkbClientMapPtr map;
+XkbKeyTypePtr from,to;
+Status rtrn;
+
+ if (!xkb)
+ return BadMatch;
+ rtrn= XkbAllocClientMap(xkb,XkbKeyTypesMask,XkbNumRequiredTypes);
+ if (rtrn!=Success)
+ return rtrn;
+ map= xkb->map;
+ if ((which&XkbAllRequiredTypes)==0)
+ return Success;
+ rtrn= Success;
+ from= canonicalTypes;
+ to= map->types;
+ if (which&XkbOneLevelMask)
+ rtrn= XkbCopyKeyType(&from[XkbOneLevelIndex],&to[XkbOneLevelIndex]);
+ if ((which&XkbTwoLevelMask)&&(rtrn==Success))
+ rtrn= XkbCopyKeyType(&from[XkbTwoLevelIndex],&to[XkbTwoLevelIndex]);
+ if ((which&XkbAlphabeticMask)&&(rtrn==Success))
+ rtrn= XkbCopyKeyType(&from[XkbAlphabeticIndex],&to[XkbAlphabeticIndex]);
+ if ((which&XkbKeypadMask)&&(rtrn==Success)) {
+ XkbKeyTypePtr type;
+ rtrn= XkbCopyKeyType(&from[XkbKeypadIndex],&to[XkbKeypadIndex]);
+ type= &to[XkbKeypadIndex];
+ if ((keypadVMod>=0)&&(keypadVMod<XkbNumVirtualMods)&&(rtrn==Success)) {
+ type->mods.vmods= (1<<keypadVMod);
+ type->map[0].active= True;
+ type->map[0].mods.mask= ShiftMask;
+ type->map[0].mods.real_mods= ShiftMask;
+ type->map[0].mods.vmods= 0;
+ type->map[0].level= 1;
+ type->map[1].active= False;
+ type->map[1].mods.mask= 0;
+ type->map[1].mods.real_mods= 0;
+ type->map[1].mods.vmods= (1<<keypadVMod);
+ type->map[1].level= 1;
+ }
+ }
+ return Success;
+}
+
+/***====================================================================***/
+
+#define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol)
+#define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l))
+
+int
+XkbKeyTypesForCoreSymbols( XkbDescPtr xkb,
+ int map_width,
+ KeySym * core_syms,
+ unsigned int protected,
+ int * types_inout,
+ KeySym * xkb_syms_rtrn)
+{
+register int i;
+unsigned int empty;
+int nSyms[XkbNumKbdGroups];
+int nGroups,tmp,groupsWidth;
+
+ /* Section 12.2 of the protocol describes this process in more detail */
+ /* Step 1: find the # of symbols in the core mapping per group */
+ groupsWidth= 2;
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ if ((protected&(1<<i))&&(types_inout[i]<xkb->map->num_types)) {
+ nSyms[i]= xkb->map->types[types_inout[i]].num_levels;
+ if (nSyms[i]>groupsWidth)
+ groupsWidth= nSyms[i];
+ }
+ else {
+ types_inout[i]= XkbTwoLevelIndex; /* don't really know, yet */
+ nSyms[i]= 2;
+ }
+ }
+ if (nSyms[XkbGroup1Index]<2)
+ nSyms[XkbGroup1Index]= 2;
+ if (nSyms[XkbGroup2Index]<2)
+ nSyms[XkbGroup2Index]= 2;
+ /* Step 2: Copy the symbols from the core ordering to XKB ordering */
+ /* symbols in the core are in the order: */
+ /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,0)]= CORE_SYM(0);
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,1)]= CORE_SYM(1);
+ for (i=2;i<nSyms[XkbGroup1Index];i++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,i)]= CORE_SYM(2+i);
+ }
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,0)]= CORE_SYM(2);
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,1)]= CORE_SYM(3);
+ tmp= 2+(nSyms[XkbGroup1Index]-2); /* offset to extra group2 syms */
+ for (i=2;i<nSyms[XkbGroup2Index];i++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,i)]= CORE_SYM(tmp+i);
+ }
+ tmp= nSyms[XkbGroup1Index]+nSyms[XkbGroup2Index];
+ if ((tmp>=map_width)&&
+ ((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) {
+ nSyms[XkbGroup3Index]= 0;
+ nSyms[XkbGroup4Index]= 0;
+ nGroups= 2;
+ }
+ else {
+ nGroups= 3;
+ for (i=0;i<nSyms[XkbGroup3Index];i++,tmp++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index,i)]= CORE_SYM(tmp);
+ }
+ if ((tmp<map_width)||(protected&XkbExplicitKeyType4Mask)) {
+ nGroups= 4;
+ for (i=0;i<nSyms[XkbGroup4Index];i++,tmp++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index,i)]= CORE_SYM(tmp);
+ }
+ }
+ else {
+ nSyms[XkbGroup4Index]= 0;
+ }
+ }
+ /* steps 3&4: alphanumeric expansion, assign canonical types */
+ empty= 0;
+ for (i=0;i<nGroups;i++) {
+ KeySym *syms;
+ syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
+ if ((nSyms[i]>1)&&(syms[1]==NoSymbol)&&(syms[0]!=NoSymbol)) {
+ KeySym upper,lower;
+ XConvertCase(syms[0],&lower,&upper);
+ if (upper!=lower) {
+ xkb_syms_rtrn[XKB_OFFSET(i,0)]= lower;
+ xkb_syms_rtrn[XKB_OFFSET(i,1)]= upper;
+ if ((protected&(1<<i))==0)
+ types_inout[i]= XkbAlphabeticIndex;
+ }
+ else if ((protected&(1<<i))==0) {
+ types_inout[i]= XkbOneLevelIndex;
+ /* nSyms[i]= 1;*/
+ }
+ }
+ if (((protected&(1<<i))==0)&&(types_inout[i]==XkbTwoLevelIndex)) {
+ if (IsKeypadKey(syms[0])||IsKeypadKey(syms[1]))
+ types_inout[i]= XkbKeypadIndex;
+ else {
+ KeySym upper,lower;
+ XConvertCase(syms[0],&lower,&upper);
+ if ((syms[0]==lower)&&(syms[1]==upper))
+ types_inout[i]= XkbAlphabeticIndex;
+ }
+ }
+ if (syms[0]==NoSymbol) {
+ register int n;
+ Bool found;
+ for (n=1,found=False;(!found)&&(n<nSyms[i]);n++) {
+ found= (syms[n]!=NoSymbol);
+ }
+ if (!found)
+ empty|= (1<<i);
+ }
+ }
+ /* step 5: squoosh out empty groups */
+ if (empty) {
+ for (i=nGroups-1;i>=0;i--) {
+ if (((empty&(1<<i))==0)||(protected&(1<<i)))
+ break;
+ nGroups--;
+ }
+ }
+ if (nGroups<1)
+ return 0;
+
+ /* step 6: replicate group 1 into group two, if necessary */
+ if ((nGroups>1)&&((empty&(XkbGroup1Mask|XkbGroup2Mask))==XkbGroup2Mask)) {
+ if ((protected&(XkbExplicitKeyType1Mask|XkbExplicitKeyType2Mask))==0) {
+ nSyms[XkbGroup2Index]= nSyms[XkbGroup1Index];
+ types_inout[XkbGroup2Index]= types_inout[XkbGroup1Index];
+ memcpy((char *)&xkb_syms_rtrn[2],(char *)xkb_syms_rtrn,
+ 2*sizeof(KeySym));
+ }
+ else if (types_inout[XkbGroup1Index]==types_inout[XkbGroup2Index]) {
+ memcpy((char *)&xkb_syms_rtrn[nSyms[XkbGroup1Index]],
+ (char *)xkb_syms_rtrn,
+ nSyms[XkbGroup1Index]*sizeof(KeySym));
+ }
+ }
+
+ /* step 7: check for all groups identical or all width 1 */
+ if (nGroups>1) {
+ Bool sameType,allOneLevel;
+ allOneLevel= (xkb->map->types[types_inout[0]].num_levels==1);
+ for (i=1,sameType=True;(allOneLevel||sameType)&&(i<nGroups);i++) {
+ sameType=(sameType&&(types_inout[i]==types_inout[XkbGroup1Index]));
+ if (allOneLevel)
+ allOneLevel= (xkb->map->types[types_inout[i]].num_levels==1);
+ }
+ if ((sameType)&&
+ (!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){
+ register int s;
+ Bool identical;
+ for (i=1,identical=True;identical&&(i<nGroups);i++) {
+ KeySym *syms;
+ syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
+ for (s=0;identical&&(s<nSyms[i]);s++) {
+ if (syms[s]!=xkb_syms_rtrn[s])
+ identical= False;
+ }
+ }
+ if (identical)
+ nGroups= 1;
+ }
+ if (allOneLevel && (nGroups>1)) {
+ KeySym *syms;
+ syms= &xkb_syms_rtrn[nSyms[XkbGroup1Index]];
+ nSyms[XkbGroup1Index]= 1;
+ for (i=1;i<nGroups;i++) {
+ xkb_syms_rtrn[i]= syms[0];
+ syms+= nSyms[i];
+ nSyms[i]= 1;
+ }
+ }
+ }
+ return nGroups;
+}
+
+static XkbSymInterpretPtr
+_XkbFindMatchingInterp( XkbDescPtr xkb,
+ KeySym sym,
+ unsigned int real_mods,
+ unsigned int level)
+{
+register unsigned i;
+XkbSymInterpretPtr interp,rtrn;
+CARD8 mods;
+
+ rtrn= NULL;
+ interp= xkb->compat->sym_interpret;
+ for (i=0;i<xkb->compat->num_si;i++,interp++) {
+ if ((interp->sym==NoSymbol)||(sym==interp->sym)) {
+ int match;
+ if ((level==0)||((interp->match&XkbSI_LevelOneOnly)==0))
+ mods= real_mods;
+ else mods= 0;
+ switch (interp->match&XkbSI_OpMask) {
+ case XkbSI_NoneOf:
+ match= ((interp->mods&mods)==0);
+ break;
+ case XkbSI_AnyOfOrNone:
+ match= ((mods==0)||((interp->mods&mods)!=0));
+ break;
+ case XkbSI_AnyOf:
+ match= ((interp->mods&mods)!=0);
+ break;
+ case XkbSI_AllOf:
+ match= ((interp->mods&mods)==interp->mods);
+ break;
+ case XkbSI_Exactly:
+ match= (interp->mods==mods);
+ break;
+ default:
+ match= 0;
+ break;
+ }
+ if (match) {
+ if (interp->sym!=NoSymbol) {
+ return interp;
+ }
+ else if (rtrn==NULL) {
+ rtrn= interp;
+ }
+ }
+ }
+ }
+ return rtrn;
+}
+
+static void
+_XkbAddKeyChange(KeyCode *pFirst,unsigned char *pNum,KeyCode newKey)
+{
+KeyCode last;
+
+ last= (*pFirst)+(*pNum);
+ if (newKey<*pFirst) {
+ *pFirst= newKey;
+ *pNum= (last-newKey)+1;
+ }
+ else if (newKey>last) {
+ *pNum= (last-*pFirst)+1;
+ }
+ return;
+}
+
+static void
+_XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
+{
+unsigned tmp;
+
+ switch (act->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
+ if (act->mods.flags&XkbSA_UseModMapMods)
+ act->mods.real_mods= act->mods.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->mods))!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->mods.mask|= tmp;
+ }
+ break;
+ case XkbSA_ISOLock:
+ if (act->iso.flags&XkbSA_UseModMapMods)
+ act->iso.real_mods= act->iso.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->iso))!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->iso.mask|= tmp;
+ }
+ break;
+ }
+ return;
+}
+
+#define IBUF_SIZE 8
+
+Bool
+XkbApplyCompatMapToKey(XkbDescPtr xkb,KeyCode key,XkbChangesPtr changes)
+{
+KeySym * syms;
+unsigned char explicit,mods;
+XkbSymInterpretPtr *interps,ibuf[IBUF_SIZE];
+int n,nSyms,found;
+unsigned changed,tmp;
+
+ if ((!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)||
+ (!xkb->compat)||(!xkb->compat->sym_interpret)||
+ (key<xkb->min_key_code)||(key>xkb->max_key_code)) {
+ return False;
+ }
+ if (((!xkb->server)||(!xkb->server->key_acts))&&
+ (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success)) {
+ return False;
+ }
+ changed= 0; /* keeps track of what has changed in _this_ call */
+ explicit= xkb->server->explicit[key];
+ if (explicit&XkbExplicitInterpretMask) /* nothing to do */
+ return True;
+ mods= (xkb->map->modmap?xkb->map->modmap[key]:0);
+ nSyms= XkbKeyNumSyms(xkb,key);
+ syms= XkbKeySymsPtr(xkb,key);
+ if (nSyms>IBUF_SIZE) {
+ interps= _XkbTypedCalloc(nSyms,XkbSymInterpretPtr);
+ if (interps==NULL) {
+ interps= ibuf;
+ nSyms= IBUF_SIZE;
+ }
+ }
+ else {
+ interps= ibuf;
+ }
+ found= 0;
+ for (n=0;n<nSyms;n++) {
+ unsigned level= (n%XkbKeyGroupsWidth(xkb,key));
+ interps[n]= NULL;
+ if (syms[n]!=NoSymbol) {
+ interps[n]= _XkbFindMatchingInterp(xkb,syms[n],mods,level);
+ if (interps[n]&&interps[n]->act.type!=XkbSA_NoAction)
+ found++;
+ else interps[n]= NULL;
+ }
+ }
+ /* 1/28/96 (ef) -- XXX! WORKING HERE */
+ if (!found) {
+ if (xkb->server->key_acts[key]!=0) {
+ xkb->server->key_acts[key]= 0;
+ changed|= XkbKeyActionsMask;
+ }
+ }
+ else {
+ XkbAction *pActs;
+ unsigned int new_vmodmask;
+ changed|= XkbKeyActionsMask;
+ pActs= XkbResizeKeyActions(xkb,key,nSyms);
+ if (!pActs) {
+ if (nSyms > IBUF_SIZE)
+ Xfree(interps);
+ return False;
+ }
+ new_vmodmask= 0;
+ for (n=0;n<nSyms;n++) {
+ if (interps[n]) {
+ unsigned effMods;
+
+ pActs[n]= *((XkbAction *)&interps[n]->act);
+ if ((n==0)||((interps[n]->match&XkbSI_LevelOneOnly)==0)) {
+ effMods= mods;
+ if (interps[n]->virtual_mod!=XkbNoModifier)
+ new_vmodmask|= (1<<interps[n]->virtual_mod);
+ }
+ else effMods= 0;
+ _XkbSetActionKeyMods(xkb,&pActs[n],effMods);
+ }
+ else pActs[n].type= XkbSA_NoAction;
+ }
+ if (((explicit&XkbExplicitVModMapMask)==0)&&
+ (xkb->server->vmodmap[key]!=new_vmodmask)) {
+ changed|= XkbVirtualModMapMask;
+ xkb->server->vmodmap[key]= new_vmodmask;
+ }
+ if (interps[0]) {
+ if ((interps[0]->flags&XkbSI_LockingKey)&&
+ ((explicit&XkbExplicitBehaviorMask)==0)) {
+ xkb->server->behaviors[key].type= XkbKB_Lock;
+ changed|= XkbKeyBehaviorsMask;
+ }
+ if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
+ CARD8 old;
+ old= xkb->ctrls->per_key_repeat[key/8];
+ if (interps[0]->flags&XkbSI_AutoRepeat)
+ xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
+ else xkb->ctrls->per_key_repeat[key/8]&= ~(1<<(key%8));
+ if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
+ changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
+ }
+ }
+ }
+ if ((!found)||(interps[0]==NULL)) {
+ if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
+ CARD8 old;
+ old= xkb->ctrls->per_key_repeat[key/8];
+#ifdef RETURN_SHOULD_REPEAT
+ if (*XkbKeySymsPtr(xkb,key) != XK_Return)
+#endif
+ xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
+ if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
+ changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
+ }
+ if (((explicit&XkbExplicitBehaviorMask)==0)&&
+ (xkb->server->behaviors[key].type==XkbKB_Lock)) {
+ xkb->server->behaviors[key].type= XkbKB_Default;
+ changed|= XkbKeyBehaviorsMask;
+ }
+ }
+ if (changes) {
+ XkbMapChangesPtr mc;
+ mc= &changes->map;
+ tmp= (changed&mc->changed);
+ if (tmp&XkbKeyActionsMask)
+ _XkbAddKeyChange(&mc->first_key_act,&mc->num_key_acts,key);
+ else if (changed&XkbKeyActionsMask) {
+ mc->changed|= XkbKeyActionsMask;
+ mc->first_key_act= key;
+ mc->num_key_acts= 1;
+ }
+ if (tmp&XkbKeyBehaviorsMask) {
+ _XkbAddKeyChange(&mc->first_key_behavior,&mc->num_key_behaviors,
+ key);
+ }
+ else if (changed&XkbKeyBehaviorsMask) {
+ mc->changed|= XkbKeyBehaviorsMask;
+ mc->first_key_behavior= key;
+ mc->num_key_behaviors= 1;
+ }
+ if (tmp&XkbVirtualModMapMask)
+ _XkbAddKeyChange(&mc->first_vmodmap_key,&mc->num_vmodmap_keys,key);
+ else if (changed&XkbVirtualModMapMask) {
+ mc->changed|= XkbVirtualModMapMask;
+ mc->first_vmodmap_key= key;
+ mc->num_vmodmap_keys= 1;
+ }
+ mc->changed|= changed;
+ }
+ if (interps!=ibuf)
+ _XkbFree(interps);
+ return True;
+}
+
+Bool
+XkbUpdateMapFromCore( XkbDescPtr xkb,
+ KeyCode first_key,
+ int num_keys,
+ int map_width,
+ KeySym * core_keysyms,
+ XkbChangesPtr changes)
+{
+register int key,last_key;
+KeySym * syms;
+
+ syms= &core_keysyms[(first_key-xkb->min_key_code)*map_width];
+ if (changes) {
+ if (changes->map.changed&XkbKeySymsMask) {
+ _XkbAddKeyChange(&changes->map.first_key_sym,
+ &changes->map.num_key_syms,first_key);
+ if (num_keys>1) {
+ _XkbAddKeyChange(&changes->map.first_key_sym,
+ &changes->map.num_key_syms,
+ first_key+num_keys-1);
+ }
+ }
+ else {
+ changes->map.changed|= XkbKeySymsMask;
+ changes->map.first_key_sym= first_key;
+ changes->map.num_key_syms= num_keys;
+ }
+ }
+ last_key= first_key+num_keys-1;
+ for (key=first_key;key<=last_key;key++,syms+= map_width) {
+ XkbMapChangesPtr mc;
+ unsigned explicit;
+ KeySym tsyms[XkbMaxSymsPerKey];
+ int types[XkbNumKbdGroups];
+ int nG;
+
+ explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask;
+ types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
+ types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index);
+ types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index);
+ types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index);
+ nG= XkbKeyTypesForCoreSymbols(xkb,map_width,syms,explicit,types,tsyms);
+ if (changes)
+ mc= &changes->map;
+ else mc= NULL;
+ XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc);
+ memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms,
+ XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
+ XkbApplyCompatMapToKey(xkb,key,changes);
+ }
+
+ if ((xkb->map->modmap!=NULL)&&(changes)&&
+ (changes->map.changed&(XkbVirtualModMapMask|XkbModifierMapMask))) {
+ unsigned char newVMods[XkbNumVirtualMods];
+ register unsigned bit,i;
+ unsigned present;
+
+ bzero(newVMods,XkbNumVirtualMods);
+ present= 0;
+ for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
+ if (xkb->server->vmodmap[key]==0)
+ continue;
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (bit&xkb->server->vmodmap[key]) {
+ present|= bit;
+ newVMods[i]|= xkb->map->modmap[key];
+ }
+ }
+ }
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if ((bit&present)&&(newVMods[i]!=xkb->server->vmods[i])) {
+ changes->map.changed|= XkbVirtualModsMask;
+ changes->map.vmods|= bit;
+ xkb->server->vmods[i]= newVMods[i];
+ }
+ }
+ }
+ if (changes && (changes->map.changed&XkbVirtualModsMask))
+ XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes);
+ return True;
+}
+
+Status
+XkbChangeTypesOfKey( XkbDescPtr xkb,
+ int key,
+ int nGroups,
+ unsigned groups,
+ int * newTypesIn,
+ XkbMapChangesPtr changes)
+{
+XkbKeyTypePtr pOldType,pNewType;
+register int i;
+int width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups];
+
+ if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) ||
+ (!xkb->map->types)||((groups&XkbAllGroupsMask)==0)||
+ (nGroups>XkbNumKbdGroups)) {
+ return BadMatch;
+ }
+ if (nGroups==0) {
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ xkb->map->key_sym_map[key].kt_index[i]= XkbOneLevelIndex;
+ }
+ i= xkb->map->key_sym_map[key].group_info;
+ i= XkbSetNumGroups(i,0);
+ xkb->map->key_sym_map[key].group_info= i;
+ XkbResizeKeySyms(xkb,key,0);
+ return Success;
+ }
+
+ nOldGroups= XkbKeyNumGroups(xkb,key);
+ oldWidth= XkbKeyGroupsWidth(xkb,key);
+ for (width=i=0;i<nGroups;i++) {
+ if (groups&(1<<i))
+ newTypes[i]= newTypesIn[i];
+ else if (i<nOldGroups)
+ newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,i);
+ else if (nOldGroups>0)
+ newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
+ else newTypes[i]= XkbTwoLevelIndex;
+ if (newTypes[i]>xkb->map->num_types)
+ return BadMatch;
+ pNewType= &xkb->map->types[newTypes[i]];
+ if (pNewType->num_levels>width)
+ width= pNewType->num_levels;
+ }
+ if ((xkb->ctrls)&&(nGroups>xkb->ctrls->num_groups))
+ xkb->ctrls->num_groups= nGroups;
+ if ((width!=oldWidth)||(nGroups!=nOldGroups)) {
+ KeySym oldSyms[XkbMaxSymsPerKey],*pSyms;
+ int nCopy;
+
+ if (nOldGroups==0) {
+ pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
+ if (pSyms!=NULL) {
+ i= xkb->map->key_sym_map[key].group_info;
+ i= XkbSetNumGroups(i,nGroups);
+ xkb->map->key_sym_map[key].group_info= i;
+ xkb->map->key_sym_map[key].width= width;
+ for (i=0;i<nGroups;i++) {
+ xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
+ }
+ return Success;
+ }
+ return BadAlloc;
+ }
+ pSyms= XkbKeySymsPtr(xkb,key);
+ memcpy(oldSyms,pSyms,XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
+ pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
+ if (pSyms==NULL)
+ return BadAlloc;
+ bzero(pSyms,width*nGroups*sizeof(KeySym));
+ for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
+ pOldType= XkbKeyKeyType(xkb,key,i);
+ pNewType= &xkb->map->types[newTypes[i]];
+ if (pNewType->num_levels>pOldType->num_levels)
+ nCopy= pOldType->num_levels;
+ else nCopy= pNewType->num_levels;
+ memcpy(&pSyms[i*width],&oldSyms[i*oldWidth],nCopy*sizeof(KeySym));
+ }
+ if (XkbKeyHasActions(xkb,key)) {
+ XkbAction oldActs[XkbMaxSymsPerKey],*pActs;
+ pActs= XkbKeyActionsPtr(xkb,key);
+ memcpy(oldActs,pActs,XkbKeyNumSyms(xkb,key)*sizeof(XkbAction));
+ pActs= XkbResizeKeyActions(xkb,key,width*nGroups);
+ if (pActs==NULL)
+ return BadAlloc;
+ bzero(pActs,width*nGroups*sizeof(XkbAction));
+ for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
+ pOldType= XkbKeyKeyType(xkb,key,i);
+ pNewType= &xkb->map->types[newTypes[i]];
+ if (pNewType->num_levels>pOldType->num_levels)
+ nCopy= pOldType->num_levels;
+ else nCopy= pNewType->num_levels;
+ memcpy(&pActs[i*width],&oldActs[i*oldWidth],
+ nCopy*sizeof(XkbAction));
+ }
+ }
+ i= xkb->map->key_sym_map[key].group_info;
+ i= XkbSetNumGroups(i,nGroups);
+ xkb->map->key_sym_map[key].group_info= i;
+ xkb->map->key_sym_map[key].width= width;
+ }
+ width= 0;
+ for (i=0;i<nGroups;i++) {
+ xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
+ if (xkb->map->types[newTypes[i]].num_levels>width)
+ width= xkb->map->types[newTypes[i]].num_levels;
+ }
+ xkb->map->key_sym_map[key].width= width;
+ if (changes!=NULL) {
+ if (changes->changed&XkbKeySymsMask) {
+ _XkbAddKeyChange(&changes->first_key_sym,&changes->num_key_syms,
+ key);
+ }
+ else {
+ changes->changed|= XkbKeySymsMask;
+ changes->first_key_sym= key;
+ changes->num_key_syms= 1;
+ }
+ }
+ return Success;
+}
+
+/***====================================================================***/
+
+Bool
+XkbVirtualModsToReal(XkbDescPtr xkb,unsigned virtual_mask,unsigned *mask_rtrn)
+{
+register int i,bit;
+register unsigned mask;
+
+ if (xkb==NULL)
+ return False;
+ if (virtual_mask==0) {
+ *mask_rtrn= 0;
+ return True;
+ }
+ if (xkb->server==NULL)
+ return False;
+ for (i=mask=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (virtual_mask&bit)
+ mask|= xkb->server->vmods[i];
+ }
+ *mask_rtrn= mask;
+ return True;
+}
+
+/***====================================================================***/
+
+Bool
+XkbUpdateActionVirtualMods(XkbDescPtr xkb,XkbAction *act,unsigned changed)
+{
+unsigned int tmp;
+
+ switch (act->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
+ if (((tmp= XkbModActionVMods(&act->mods))&changed)!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->mods.mask= act->mods.real_mods;
+ act->mods.mask|= tmp;
+ return True;
+ }
+ break;
+ case XkbSA_ISOLock:
+ if ((((tmp= XkbModActionVMods(&act->iso))!=0)&changed)!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->iso.mask= act->iso.real_mods;
+ act->iso.mask|= tmp;
+ return True;
+ }
+ break;
+ }
+ return False;
+}
+
+void
+XkbUpdateKeyTypeVirtualMods( XkbDescPtr xkb,
+ XkbKeyTypePtr type,
+ unsigned int changed,
+ XkbChangesPtr changes)
+{
+register unsigned int i;
+unsigned int mask;
+
+ XkbVirtualModsToReal(xkb,type->mods.vmods,&mask);
+ type->mods.mask= type->mods.real_mods|mask;
+ if ((type->map_count>0)&&(type->mods.vmods!=0)) {
+ XkbKTMapEntryPtr entry;
+ for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
+ if (entry->mods.vmods!=0) {
+ XkbVirtualModsToReal(xkb,entry->mods.vmods,&mask);
+ entry->mods.mask=entry->mods.real_mods|mask;
+ /* entry is active if vmods are bound*/
+ entry->active= (mask!=0);
+ }
+ else entry->active= 1;
+ }
+ }
+ if (changes) {
+ int type_ndx;
+ type_ndx= type-xkb->map->types;
+ if ((type_ndx<0)||(type_ndx>xkb->map->num_types))
+ return;
+ if (changes->map.changed&XkbKeyTypesMask) {
+ int last;
+ last= changes->map.first_type+changes->map.num_types-1;
+ if (type_ndx<changes->map.first_type) {
+ changes->map.first_type= type_ndx;
+ changes->map.num_types= (last-type_ndx)+1;
+ }
+ else if (type_ndx>last) {
+ changes->map.num_types= (type_ndx-changes->map.first_type)+1;
+ }
+ }
+ else {
+ changes->map.changed|= XkbKeyTypesMask;
+ changes->map.first_type= type_ndx;
+ changes->map.num_types= 1;
+ }
+ }
+ return;
+}
+
+Bool
+XkbApplyVirtualModChanges(XkbDescPtr xkb,unsigned changed,XkbChangesPtr changes)
+{
+register int i;
+unsigned int checkState = 0;
+
+ if ((!xkb) || (!xkb->map) || (changed==0))
+ return False;
+ for (i=0;i<xkb->map->num_types;i++) {
+ if (xkb->map->types[i].mods.vmods & changed)
+ XkbUpdateKeyTypeVirtualMods(xkb,&xkb->map->types[i],changed,changes);
+ }
+ if (changed&xkb->ctrls->internal.vmods) {
+ unsigned int newMask;
+ XkbVirtualModsToReal(xkb,xkb->ctrls->internal.vmods,&newMask);
+ newMask|= xkb->ctrls->internal.real_mods;
+ if (xkb->ctrls->internal.mask!=newMask) {
+ xkb->ctrls->internal.mask= newMask;
+ if (changes) {
+ changes->ctrls.changed_ctrls|= XkbInternalModsMask;
+ checkState= True;
+ }
+ }
+ }
+ if (changed&xkb->ctrls->ignore_lock.vmods) {
+ unsigned int newMask;
+ XkbVirtualModsToReal(xkb,xkb->ctrls->ignore_lock.vmods,&newMask);
+ newMask|= xkb->ctrls->ignore_lock.real_mods;
+ if (xkb->ctrls->ignore_lock.mask!=newMask) {
+ xkb->ctrls->ignore_lock.mask= newMask;
+ if (changes) {
+ changes->ctrls.changed_ctrls|= XkbIgnoreLockModsMask;
+ checkState= True;
+ }
+ }
+ }
+ if (xkb->indicators!=NULL) {
+ XkbIndicatorMapPtr map;
+ map= &xkb->indicators->maps[0];
+ for (i=0;i<XkbNumIndicators;i++,map++) {
+ if (map->mods.vmods&changed) {
+ unsigned int newMask;
+ XkbVirtualModsToReal(xkb,map->mods.vmods,&newMask);
+ newMask|= map->mods.real_mods;
+ if (newMask!=map->mods.mask) {
+ map->mods.mask= newMask;
+ if (changes) {
+ changes->indicators.map_changes|= (1<<i);
+ checkState= True;
+ }
+ }
+ }
+ }
+ }
+ if (xkb->compat!=NULL) {
+ XkbCompatMapPtr compat;
+ compat= xkb->compat;
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ unsigned int newMask;
+ XkbVirtualModsToReal(xkb,compat->groups[i].vmods,&newMask);
+ newMask|= compat->groups[i].real_mods;
+ if (compat->groups[i].mask!=newMask) {
+ compat->groups[i].mask= newMask;
+ if (changes) {
+ changes->compat.changed_groups|= (1<<i);
+ checkState= True;
+ }
+ }
+ }
+ }
+ if (xkb->map && xkb->server) {
+ int highChange = 0, lowChange = -1;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (XkbKeyHasActions(xkb,i)) {
+ register XkbAction *pAct;
+ register int n;
+
+ pAct= XkbKeyActionsPtr(xkb,i);
+ for (n=XkbKeyNumActions(xkb,i);n>0;n--,pAct++) {
+ if ((pAct->type!=XkbSA_NoAction)&&
+ XkbUpdateActionVirtualMods(xkb,pAct,changed)) {
+ if (lowChange<0)
+ lowChange= i;
+ highChange= i;
+ }
+ }
+ }
+ }
+ if (changes && (lowChange>0)) { /* something changed */
+ if (changes->map.changed&XkbKeyActionsMask) {
+ int last;
+ if (changes->map.first_key_act<lowChange)
+ lowChange= changes->map.first_key_act;
+ last= changes->map.first_key_act+changes->map.num_key_acts-1;
+ if (last>highChange)
+ highChange= last;
+ }
+ changes->map.changed|= XkbKeyActionsMask;
+ changes->map.first_key_act= lowChange;
+ changes->map.num_key_acts= (highChange-lowChange)+1;
+ }
+ }
+ return checkState;
+}