diff options
Diffstat (limited to 'nxcompext/NXlib.c')
-rw-r--r-- | nxcompext/NXlib.c | 4776 |
1 files changed, 0 insertions, 4776 deletions
diff --git a/nxcompext/NXlib.c b/nxcompext/NXlib.c deleted file mode 100644 index 0b8126557..000000000 --- a/nxcompext/NXlib.c +++ /dev/null @@ -1,4776 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */ -/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */ -/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */ -/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMPEXT, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE which comes in the source */ -/* distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include <sys/socket.h> - -#ifndef __sun -#include <strings.h> -#endif - -#include "NX.h" - -#include "dix.h" -#include "os.h" - -/* - * Needed to enable definition of the callback - * functions. - */ - -#define NX_TRANS_SOCKET - -#include "Xlib.h" -#include "Xutil.h" -#include "Xlibint.h" - -#include "NXlib.h" -#include "NXproto.h" -#include "NXpack.h" - -#include "Clean.h" -#include "Mask.h" -#include "Colormap.h" -#include "Alpha.h" -#include "Bitmap.h" -#include "Jpeg.h" -#include "Pgn.h" -#include "Rgb.h" -#include "Rle.h" -#include "Z.h" - -#include "MD5.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -/* - * Maximum number of colors allowed in - * Png encoding. - */ - -#define NB_COLOR_MAX 256 - -/* - * Dummy error handlers used internally to catch - * Xlib failures in replies. - */ - -static int _NXInternalReplyErrorFunction(Display *dpy, XErrorEvent *error); - -static void _NXInternalLostSequenceFunction(Display *dpy, unsigned long newseq, - unsigned long lastseq, unsigned int type); - -/* - * Resource ids that can be requested by - * the client for use in split or unpack - * operations. - */ - -static unsigned char _NXSplitResources[NXNumberOfResources]; -static unsigned char _NXUnpackResources[NXNumberOfResources]; - -static Display *_NXDisplayInitialized = NULL; - -/* - * Used in asynchronous handling of - * GetImage replies. - */ - -typedef struct -{ - unsigned long sequence; - unsigned int resource; - unsigned long mask; - int format; - int width; - int height; - _XAsyncHandler *handler; - XImage *image; -} _NXCollectImageState; - -static _NXCollectImageState *_NXCollectedImages[NXNumberOfResources]; - -/* - * Used in asynchronous handling of - * GetProperty replies. - */ - -typedef struct -{ - unsigned long sequence; - unsigned int resource; - Window window; - Atom property; - Atom type; - int format; - unsigned long items; - unsigned long after; - _XAsyncHandler *handler; - char *data; -} _NXCollectPropertyState; - -static _NXCollectPropertyState *_NXCollectedProperties[NXNumberOfResources]; - -/* - * Used in asynchronous handling of - * GrabPointer replies. - */ - -typedef struct -{ - unsigned long sequence; - unsigned int resource; - int status; - _XAsyncHandler *handler; -} _NXCollectGrabPointerState; - -static _NXCollectGrabPointerState *_NXCollectedGrabPointers[NXNumberOfResources]; - -/* - * Used in asynchronous handling of - * GetInputFocus replies. - */ - -typedef struct -{ - unsigned long sequence; - unsigned int resource; - Window focus; - int revert_to; - _XAsyncHandler *handler; -} _NXCollectInputFocusState; - -static _NXCollectInputFocusState *_NXCollectedInputFocuses[NXNumberOfResources]; - -/* - * Used by functions handling cache of - * packed images. - */ - -#define MD5_LENGTH 16 - -typedef struct -{ - md5_byte_t *md5; - XImage *image; - unsigned int method; -} _NXImageCacheEntry; - -int NXImageCacheSize = 0; -int NXImageCacheHits = 0; -int NXImageCacheOps = 0; - -_NXImageCacheEntry *NXImageCache = NULL; - -#ifdef DUMP - -void _NXCacheDump(const char *label); - -void _NXDumpData(const unsigned char *buffer, unsigned int size); - -#endif - -/* - * From X11/PutImage.c. - * - * Cancel a GetReq operation, before doing - * _XSend or Data. - */ - -#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) -#define UnGetReq(name)\ - dpy->bufptr -= SIZEOF(x##name##Req);\ - dpy->request-- -#else -#define UnGetReq(name)\ - dpy->bufptr -= SIZEOF(x/**/name/**/Req);\ - dpy->request-- -#endif - -#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) -#define UnGetEmptyReq()\ - dpy->bufptr -= 4;\ - dpy->request-- -#else -#define UnGetEmptyReq(name)\ - dpy->bufptr -= 4;\ - dpy->request-- -#endif - -/* - * From X11/ImUtil.c. - */ - -extern int _XGetBitsPerPixel(Display *dpy, int depth); -extern int _XGetScanlinePad(Display *dpy, int depth); - -#define ROUNDUP(nbytes, pad) (((nbytes) + ((pad) - 1)) & \ - ~(long)((pad) - 1)) - -static unsigned int DepthOnes(unsigned long mask) -{ - register unsigned long y; - - y = (mask >> 1) &033333333333; - y = mask - y - ((y >>1) & 033333333333); - return ((unsigned int) (((y + (y >> 3)) & - 030707070707) % 077)); -} - -#define CanMaskImage(image, mask) \ -\ -(image -> format == ZPixmap && mask != NULL && \ - (image -> depth == 32 || image -> depth == 24 || \ - (image -> depth == 16 && (image -> red_mask == 0xf800 && \ - image -> green_mask == 0x7e0 && image -> blue_mask == 0x1f)))) - -#define ShouldMaskImage(image, mask) (mask -> color_mask != 0xff) - -/* - * Initialize and reset the internal structures. - */ - -extern int _NXInternalInitResources(Display *dpy); -extern int _NXInternalResetResources(Display *dpy); -extern int _NXInternalInitEncoders(Display *dpy); -extern int _NXInternalResetEncoders(Display *dpy); - -int NXInitDisplay(Display *dpy) -{ - #ifdef TEST - fprintf(stderr, "******NXInitDisplay: Called for display at [%p].\n", (void *) dpy); - #endif - - if (_NXDisplayInitialized == NULL) - { - _NXInternalInitResources(dpy); - - _NXInternalInitEncoders(dpy); - - _NXDisplayInitialized = dpy; - - return 1; - } - - #ifdef TEST - fprintf(stderr, "******NXInitDisplay: WARNING! Internal structures already initialized.\n"); - #endif - - return 0; -} - -int NXResetDisplay(Display *dpy) -{ - #ifdef TEST - fprintf(stderr, "******NXResetDisplay: Called for display at [%p].\n", (void *) dpy); - #endif - - if (_NXDisplayInitialized != NULL) - { - _NXInternalResetResources(dpy); - - _NXInternalResetEncoders(dpy); - - _NXDisplayInitialized = NULL; - - return 1; - } - - #ifdef TEST - fprintf(stderr, "******NXResetDisplay: WARNING! Internal structures already reset.\n"); - #endif - - return 0; -} - -int _NXInternalInitResources(Display *dpy) -{ - return _NXInternalResetResources(dpy); -} - -int _NXInternalResetResources(Display *dpy) -{ - int i; - - #ifdef TEST - fprintf(stderr, "******_NXInternalResetResources: Clearing all the internal structures.\n"); - #endif - - for (i = 0; i < NXNumberOfResources; i++) - { - _NXSplitResources[i] = 0; - _NXUnpackResources[i] = 0; - - if (_NXCollectedImages[i] != NULL) - { - #ifdef TEST - fprintf(stderr, "******_NXInternalResetResources: WARNING! Clearing collect image data " - "for resource [%d].\n", i); - #endif - - if (_NXCollectedImages[i] -> handler != NULL) - { - DeqAsyncHandler(dpy, _NXCollectedImages[i] -> handler); - - Xfree(_NXCollectedImages[i] -> handler); - } - - if (_NXCollectedImages[i] -> image != NULL) - { - XDestroyImage(_NXCollectedImages[i] -> image); - } - - Xfree(_NXCollectedImages[i]); - - _NXCollectedImages[i] = NULL; - } - - if (_NXCollectedProperties[i] != NULL) - { - #ifdef TEST - fprintf(stderr, "******_NXInternalResetResources: WARNING! Clearing collect property data " - "for resource [%d].\n", i); - #endif - - if (_NXCollectedProperties[i] -> handler != NULL) - { - DeqAsyncHandler(dpy, _NXCollectedProperties[i] -> handler); - - Xfree(_NXCollectedProperties[i] -> handler); - } - - if (_NXCollectedProperties[i] -> data != NULL) - { - Xfree(_NXCollectedProperties[i] -> data); - } - - Xfree(_NXCollectedProperties[i]); - - _NXCollectedProperties[i] = NULL; - } - - if (_NXCollectedGrabPointers[i] != NULL) - { - #ifdef TEST - fprintf(stderr, "******_NXInternalResetResources: WARNING! Clearing grab pointer data " - "for resource [%d].\n", i); - #endif - - if (_NXCollectedGrabPointers[i] -> handler != NULL) - { - DeqAsyncHandler(dpy, _NXCollectedGrabPointers[i] -> handler); - - Xfree(_NXCollectedGrabPointers[i] -> handler); - } - - Xfree(_NXCollectedGrabPointers[i]); - - _NXCollectedGrabPointers[i] = NULL; - } - - if (_NXCollectedInputFocuses[i] != NULL) - { - #ifdef TEST - fprintf(stderr, "******_NXInternalResetResources: WARNING! Clearing collect input focus data " - "for resource [%d].\n", i); - #endif - - if (_NXCollectedInputFocuses[i] -> handler != NULL) - { - DeqAsyncHandler(dpy, _NXCollectedInputFocuses[i] -> handler); - - Xfree(_NXCollectedInputFocuses[i] -> handler); - } - - Xfree(_NXCollectedInputFocuses[i]); - - _NXCollectedInputFocuses[i] = NULL; - } - } - - return 1; -} - -int _NXInternalInitEncoders(Display *dpy) -{ - ZInitEncoder(); - - return 1; -} - -int _NXInternalResetEncoders(Display *dpy) -{ - ZResetEncoder(); - - return 1; -} - -int NXSetDisplayPolicy(Display *dpy, int policy) -{ - if (policy == NXPolicyImmediate) - { - return NXTransPolicy(NX_FD_ANY, NX_POLICY_IMMEDIATE); - } - else - { - return NXTransPolicy(NX_FD_ANY, NX_POLICY_DEFERRED); - } -} - -int NXSetDisplayBuffer(Display *dpy, int size) -{ - /* - * This is not multi-thread safe, so, - * if you have threads, be sure that - * they are stopped. - */ - - char *buffer; - - XFlush(dpy); - - if (dpy -> bufmax - size == dpy -> buffer) - { - #ifdef TEST - fprintf(stderr, "******NXSetDisplayBuffer: Nothing to do with buffer size matching.\n"); - #endif - - return 1; - } - else if (dpy -> bufptr != dpy -> buffer) - { - #ifdef PANIC - fprintf(stderr, "******NXSetDisplayBuffer: PANIC! The display buffer is not empty.\n"); - #endif - - return -1; - } - else if ((buffer = Xcalloc(1, size)) == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXSetDisplayBuffer: PANIC! Can't allocate [%d] bytes for the buffer.\n", - size); - #endif - - return -1; - } - - if (dpy -> buffer != NULL) - { - Xfree(dpy -> buffer); - } - - dpy -> buffer = buffer; - dpy -> bufptr = dpy -> buffer; - dpy -> bufmax = dpy -> bufptr + size; - - #ifdef TEST - fprintf(stderr, "******NXSetDisplayBuffer: Set the display output buffer size to [%d].\n", - size); - #endif - - return 1; -} - -/* - * If set, the Popen() function in the X server - * wil remove the LD_LIBRARY_PATH variable from - * the environment before calling the execl() - * function on the child process. - */ - -int NXUnsetLibraryPath(int value) -{ - int previous = _NXUnsetLibraryPath; - - _NXUnsetLibraryPath = value; - - #ifdef TEST - fprintf(stderr, "******NXUnsetLibraryPath: Set the flag to [%d] with previous value [%d].\n", - value, previous); - #endif - - return previous; -} - -/* - * If set, the Xlib I/O error handler will simply - * return, instead of quitting the program. This - * leaves to the application the responsibility - * of checking the state of the XlibDisplayIOEr- - * ror flag. - */ - -int NXHandleDisplayError(int value) -{ - int previous = _NXHandleDisplayError; - - _NXHandleDisplayError = value; - - #ifdef TEST - fprintf(stderr, "******NXHandleDisplayError: Set the flag to [%d] with previous value [%d].\n", - value, previous); - #endif - - return previous; -} - -/* - * Shutdown the display descriptor and force Xlib - * to set the I/O error flag. - */ - -Bool NXForceDisplayError(Display *dpy) -{ - if (dpy != NULL) - { - NXTransClose(dpy -> fd); - - if (!(dpy -> flags & XlibDisplayIOError)) - { - shutdown(dpy -> fd, SHUT_RDWR); - - _XIOError(dpy); - } - - return 1; - } - - return 0; -} - -/* - * Check if the display has become invalid. Similarly - * to the modified Xlib, we call the predicate funct- - * ion with the value of the XlibDisplayIOError flag - * only if the I/O error was not encountered already. - * The application can use this function to query the - * XlibDisplayIOError flag because Xlib doesn't expose - * the internals of the display structure to the appli- - * cation. - */ - -int NXDisplayError(Display *dpy) -{ - if (dpy != NULL) - { - return (_XGetIOError(dpy) || - (_NXDisplayErrorFunction != NULL && - (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))); - } - - return 1; -} - -/* - * Various queries related to the state of the - * display connection. - */ - -int NXDisplayReadable(Display *dpy) -{ - int result; - int readable; - - result = NXTransReadable(dpy -> fd, &readable); - - if (result == 0) - { - #ifdef DEBUG - fprintf(stderr, "******NXDisplayReadable: Returning [%d] bytes readable from fd [%d].\n", - readable, dpy -> fd); - #endif - - return readable; - } - - #ifdef DEBUG - fprintf(stderr, "******NXDisplayReadable: WARNING! Error detected on display fd [%d].\n", - dpy -> fd); - #endif - - return -1; -} - -int NXDisplayFlushable(Display *dpy) -{ - #ifdef DEBUG - - int flushable; - - flushable = NXTransFlushable(dpy -> fd) + - (dpy -> bufptr - dpy -> buffer); - - fprintf(stderr, "******NXDisplayFlushable: Returning [%d+%d=%d] bytes flushable " - "to fd [%d].\n", (int) (dpy -> bufptr - dpy -> buffer), - (int) (flushable - (dpy -> bufptr - dpy -> buffer)), - flushable, dpy -> fd); - - return flushable; - - #else - - return NXTransFlushable(dpy -> fd) + (dpy -> bufptr - dpy -> buffer); - - #endif -} - -int NXDisplayCongestion(Display *dpy) -{ - #ifdef DEBUG - - int congestion = NXTransCongestion(dpy -> fd); - - fprintf(stderr, "******NXDisplayCongestion: Returning [%d] as congestion level for fd [%d].\n", - congestion, dpy -> fd); - - return congestion; - - #else - - return NXTransCongestion(dpy -> fd); - - #endif -} - -int NXFlushDisplay(Display *dpy, int what) -{ - if (!(dpy -> flags & XlibDisplayWriting) && - dpy -> bufptr - dpy -> buffer > 0) - { - #ifdef DEBUG - fprintf(stderr, "******NXFlushDisplay: Writing with [%d] bytes in the buffer.\n", - (int) (dpy -> bufptr - dpy -> buffer)); - #endif - - XFlush(dpy); - } - - if (what == NXFlushBuffer) - { - return 0; - } - - #ifdef DEBUG - fprintf(stderr, "******NXFlushDisplay: Flushing with [%d] bytes in the NX transport.\n", - NXDisplayFlushable(dpy)); - #endif - - return NXTransFlush(dpy -> fd); -} - -NXDisplayErrorPredicate NXSetDisplayErrorPredicate(NXDisplayErrorPredicate predicate) -{ - NXDisplayErrorPredicate previous = _NXDisplayErrorFunction; - - _NXDisplayErrorFunction = predicate; - - #ifdef TEST - fprintf(stderr, "******NXSetDisplayErrorPredicate: Set the predicate to [%p] with previous value [%p].\n", - predicate, previous); - #endif - - return previous; -} - -NXDisplayBlockHandler NXSetDisplayBlockHandler(NXDisplayBlockHandler handler) -{ - NXDisplayBlockHandler previous = _NXDisplayBlockFunction; - - _NXDisplayBlockFunction = handler; - - #ifdef TEST - fprintf(stderr, "******NXSetDisplayBlockHandler: Set the handler to [%p] with previous value [%p].\n", - handler, previous); - #endif - - return previous; -} - -NXDisplayWriteHandler NXSetDisplayWriteHandler(NXDisplayWriteHandler handler) -{ - NXDisplayWriteHandler previous = _NXDisplayWriteFunction; - - _NXDisplayWriteFunction = handler; - - #ifdef TEST - fprintf(stderr, "******NXSetDisplayWriteHandler: Set the handler to [%p] with previous value [%p].\n", - handler, previous); - #endif - - return previous; -} - -NXDisplayFlushHandler NXSetDisplayFlushHandler(NXDisplayFlushHandler handler, Display *display) -{ - NXDisplayFlushHandler previous = _NXDisplayFlushFunction; - - _NXDisplayFlushFunction = handler; - - NXTransHandler(NX_FD_ANY, NX_HANDLER_FLUSH, - (void (*)(void *, int)) handler, (void *) display); - - #ifdef TEST - fprintf(stderr, "******NXSetDisplayFlushHandler: Set the handler to [%p] with display [%p] " - "and previous value [%p].\n", handler, display, previous); - #endif - - return previous; -} - -NXDisplayStatisticsHandler NXSetDisplayStatisticsHandler(NXDisplayStatisticsHandler handler, char **buffer) -{ - NXDisplayStatisticsHandler previous = _NXDisplayStatisticsFunction; - - _NXDisplayStatisticsFunction = handler; - - /* - * Propagate the handler. - */ - - NXTransHandler(NX_FD_ANY, NX_HANDLER_STATISTICS, - (void (*)(void *, int)) handler, (void *) buffer); - - #ifdef TEST - fprintf(stderr, "******NXSetDisplayStatisticsHandler: Set the handler to [%p] with buffer pointer [%p] " - "and previous value [%p].\n", handler, buffer, previous); - #endif - - return previous; -} - -NXLostSequenceHandler NXSetLostSequenceHandler(NXLostSequenceHandler handler) -{ - NXLostSequenceHandler previous = _NXLostSequenceFunction; - - _NXLostSequenceFunction = handler; - - #ifdef TEST - fprintf(stderr, "******NXSetLostSequenceHandler: Set the handler to [%p] with previous value [%p].\n", - handler, previous); - #endif - - return previous; -} - -int _NXInternalReplyErrorFunction(Display *dpy, XErrorEvent *error) -{ - #ifdef TEST - fprintf(stderr, "******_NXInternalReplyErrorFunction: Internal error handler called.\n"); - #endif - - return 0; -} - -void _NXInternalLostSequenceFunction(Display *dpy, unsigned long newseq, - unsigned long lastseq, unsigned int type) -{ - #ifdef TEST - - fprintf(stderr, "******_NXInternalLostSequenceFunction: WARNING! Sequence lost with new " - "sequence %ld last request %ld.\n", newseq, dpy -> request); - - /* - * TODO: Reply or event info must be implemented. - * - * fprintf(stderr, "******_NXInternalLostSequenceFunction: WARNING! Expected event or reply " - * "was %ld with sequence %ld.\n", (long) rep -> type, (long) rep -> sequenceNumber); - */ - - fprintf(stderr, "******_NXInternalLostSequenceFunction: WARNING! Last sequence read " - "was %ld display request is %ld.\n", lastseq & 0xffff, dpy -> request & 0xffff); - - #endif -} - -Status NXGetControlParameters(Display *dpy, unsigned int *link_type, unsigned int *local_major, - unsigned int *local_minor, unsigned int *local_patch, - unsigned int *remote_major, unsigned int *remote_minor, - unsigned int *remote_patch, int *split_timeout, int *motion_timeout, - int *split_mode, int *split_size, unsigned int *pack_method, - unsigned int *pack_quality, int *data_level, int *stream_level, - int *delta_level, unsigned int *load_cache, - unsigned int *save_cache, unsigned int *startup_cache) -{ - xNXGetControlParametersReply rep; - - register xReq *req; - - LockDisplay(dpy); - - GetEmptyReq(NXGetControlParameters, req); - - #ifdef TEST - fprintf(stderr, "******NXGetControlParameters: Sending message opcode [%d].\n", - X_NXGetControlParameters); - #endif - - if (_XReply(dpy, (xReply *) &rep, 0, xTrue) == xFalse) - { - #ifdef TEST - fprintf(stderr, "******NXGetControlParameters: Error receiving reply.\n"); - #endif - - UnlockDisplay(dpy); - - SyncHandle(); - - return 0; - } - - #ifdef TEST - fprintf(stderr, "******NXGetControlParameters: Got reply with link type [%u].\n", rep.linkType); - - fprintf(stderr, "******NXGetControlParameters: Local protocol major [%u] minor [%u] patch [%u].\n", - rep.localMajor, rep.localMinor, rep.localPatch); - - fprintf(stderr, "******NXGetControlParameters: Remote protocol major [%u] minor [%u] patch [%u].\n", - rep.remoteMajor, rep.remoteMinor, rep.remotePatch); - - fprintf(stderr, "******NXGetControlParameters: Split timeout [%d] motion timeout [%d].\n", - (int) rep.splitTimeout, (int) rep.motionTimeout); - - fprintf(stderr, "******NXGetControlParameters: Split mode [%d] split size [%d].\n", - (int) rep.splitMode, (int) rep.splitSize); - - fprintf(stderr, "******NXGetControlParameters: Preferred pack method [%d] pack quality [%d].\n", - (int) rep.packMethod, (int) rep.packQuality); - - fprintf(stderr, "******NXGetControlParameters: Data level [%d] stream level [%d] delta level [%d].\n", - rep.dataLevel, rep.streamLevel, rep.deltaLevel); - #endif - - *link_type = rep.linkType; - - *local_major = rep.localMajor; - *local_minor = rep.localMinor; - *local_patch = rep.localPatch; - - *remote_major = rep.remoteMajor; - *remote_minor = rep.remoteMinor; - *remote_patch = rep.remotePatch; - - *split_timeout = rep.splitTimeout; - *motion_timeout = rep.motionTimeout; - - *split_mode = rep.splitMode; - *split_size = rep.splitSize; - - *pack_method = rep.packMethod; - *pack_quality = rep.packQuality; - - *data_level = rep.dataLevel; - *stream_level = rep.streamLevel; - *delta_level = rep.deltaLevel; - - *load_cache = rep.loadCache; - *save_cache = rep.saveCache; - *startup_cache = rep.startupCache; - - UnlockDisplay(dpy); - - SyncHandle(); - - /* - * Install our internal out-of-sync handler. - */ - - _NXLostSequenceFunction = _NXInternalLostSequenceFunction; - - return 1; -} - -/* - * Which unpack methods are supported by the - * remote proxy? - */ - -Status NXGetUnpackParameters(Display *dpy, unsigned int *entries, unsigned char supported_methods[]) -{ - register xNXGetUnpackParametersReq *req; - - xNXGetUnpackParametersReply rep; - - register unsigned n; - - #ifdef TEST - register unsigned i; - #endif - - if (*entries < NXNumberOfPackMethods) - { - #ifdef TEST - fprintf(stderr, "******NXGetUnpackParameters: Requested only [%d] entries while they should be [%d].\n", - *entries, NXNumberOfPackMethods); - #endif - - return 0; - } - - LockDisplay(dpy); - - GetReq(NXGetUnpackParameters, req); - - req -> entries = *entries; - - #ifdef TEST - fprintf(stderr, "******NXGetUnpackParameters: Sending message opcode [%d] with [%d] requested entries.\n", - X_NXGetUnpackParameters, *entries); - #endif - - if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == xFalse || rep.length == 0) - { - #ifdef TEST - fprintf(stderr, "******NXGetUnpackParameters: Error receiving reply.\n"); - #endif - - UnlockDisplay(dpy); - - SyncHandle(); - - return 0; - } - - if ((n = rep.length << 2) > *entries) - { - #ifdef TEST - fprintf(stderr, "******NXGetUnpackParameters: Got [%d] bytes of reply data while they should be [%d].\n", - n, *entries); - #endif - - _XEatData(dpy, (unsigned long) n); - - UnlockDisplay(dpy); - - SyncHandle(); - - return 0; - } - - *entries = n; - - #ifdef TEST - fprintf(stderr, "******NXGetUnpackParameters: Reading [%d] bytes of reply data.\n", n); - #endif - - _XReadPad(dpy, (char *) supported_methods, n); - - #ifdef TEST - - fprintf(stderr, "******NXGetUnpackParameters: Got reply with methods: "); - - for (i = 0; i < n; i++) - { - if (supported_methods[i] != 0) - { - fprintf(stderr, "[%d]", i); - } - } - - fprintf(stderr, ".\n"); - - #endif - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -/* - * Query and enable the MIT-SHM support between the - * proxy and the X server. The 'enable' flags must be - * true if shared memory PutImages and PutPackedImages - * are desired. On return the flags will say if support - * has been successfully enabled. - * - * Note that the the client part is not useful and not - * implemented. The size of the segment is chosen by - * the proxy. The main purpose of the message is to - * reserve the XID that will be used by the remote. - */ - -Status NXGetShmemParameters(Display *dpy, unsigned int *enable_client, - unsigned int *enable_server, unsigned int *client_segment, - unsigned int *server_segment, unsigned int *client_size, - unsigned int *server_size) -{ - register xNXGetShmemParametersReq *req; - - register int stage; - - xNXGetShmemParametersReply rep; - - /* - * Save the previous handler. - */ - - int (*handler)(Display *, XErrorEvent *) = _XErrorFunction; - - *client_segment = 0; - *server_segment = 0; - - if (*enable_client) - { - *client_segment = XAllocID(dpy); - } - - if (*enable_server) - { - *server_segment = XAllocID(dpy); - } - - LockDisplay(dpy); - - _XErrorFunction = _NXInternalReplyErrorFunction; - - for (stage = 0; stage < 3; stage++) - { - GetReq(NXGetShmemParameters, req); - - req -> stage = stage; - - req -> enableClient = (*enable_client != 0 ? 1 : 0); - req -> enableServer = (*enable_server != 0 ? 1 : 0); - - req -> clientSegment = *client_segment; - req -> serverSegment = *server_segment; - - #ifdef TEST - fprintf(stderr, "******NXGetShmemParameters: Sending message opcode [%d] at stage [%d].\n", - X_NXGetShmemParameters, stage); - #endif - - #ifdef TEST - - if (stage == 0) - { - fprintf(stderr, "******NXGetShmemParameters: Enable client is [%u] enable server is [%u].\n", - *enable_client, *enable_server); - - fprintf(stderr, "******NXGetShmemParameters: Client segment is [%u] server segment is [%u].\n", - *client_segment, *server_segment); - } - - #endif - - /* - * There isn't X server reply in the second stage. - * The procedure followed at X server side is: - * - * Stage 0: Send X_QueryExtension and masquerade - * the reply. - * - * Stage 1: Allocate the shared memory and send - * X_ShmAttach to the X server. - * - * Stage 2: Send X_GetInputFocus and masquerade - * the reply. - * - * The last message is used to force a reply and - * collect any X error caused by a failure in the - * shared memory initialization. - */ - - if (stage != 1) - { - /* - * We are only interested in the final reply. - */ - - if (_XReply(dpy, (xReply *) &rep, 0, xTrue) == xFalse) - { - #ifdef TEST - fprintf(stderr, "******NXGetShmemParameters: Error receiving reply.\n"); - #endif - - _XErrorFunction = handler; - - UnlockDisplay(dpy); - - SyncHandle(); - - return 0; - } - } - } - - /* - * Return the settings to client. - */ - - *enable_client = rep.clientEnabled; - *enable_server = rep.serverEnabled; - - *client_size = rep.clientSize; - *server_size = rep.serverSize; - - #ifdef TEST - fprintf(stderr, "******NXGetShmemParameters: Got final reply with enabled client [%u] and server [%u].\n", - *enable_client, *enable_server); - - fprintf(stderr, "******NXGetShmemParameters: Client segment size [%u] server segment size [%u].\n", - *client_size, *server_size); - #endif - - _XErrorFunction = handler; - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -/* - * Get the path to the font server that can be used by the X - * server to tunnel the font connections across the NX link. - * The path actually represents the TCP port where the proxy - * on the NX client side is listening. The agent can tempora- - * rily enable the tunneling when it needs a font that is not - * available on the client, for example when the session is - * migrated from a different X server. - * - * Note that it is not advisable to use the font server chan- - * nel for other purposes than restoring a font that is found - * missing at the time the session is migrated to a different - * display. This is because the agent implements a caching of - * the list of fonts supported by the client as it needs to - * advertise only the fonts that can be opened at both sides. - */ - -Status NXGetFontParameters(Display *dpy, unsigned int path_length, char path_data[]) -{ - register xNXGetFontParametersReq *req; - - xNXGetFontParametersReply rep; - - register unsigned n; - - #ifdef TEST - register unsigned i; - #endif - - if (path_length < 1) - { - #ifdef TEST - fprintf(stderr, "******NXGetFontParameters: No room to store the reply.\n"); - #endif - - return 0; - } - - *path_data = '\0'; - - LockDisplay(dpy); - - GetReq(NXGetFontParameters, req); - - #ifdef TEST - fprintf(stderr, "******NXGetFontParameters: Sending message opcode [%d].\n", - X_NXGetFontParameters); - #endif - - if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == xFalse || rep.length == 0) - { - #ifdef TEST - fprintf(stderr, "******NXGetFontParameters: Error receiving reply.\n"); - #endif - - UnlockDisplay(dpy); - - SyncHandle(); - - return 0; - } - - if ((n = rep.length << 2) > path_length) - { - #ifdef TEST - fprintf(stderr, "******NXGetFontParameters: Got [%d] bytes of reply data with only room for [%d].\n", - n, path_length); - #endif - - _XEatData(dpy, (unsigned long) n); - - UnlockDisplay(dpy); - - SyncHandle(); - - return 0; - } - - #ifdef TEST - fprintf(stderr, "******NXGetFontParameters: Reading [%d] bytes of reply data.\n", n); - #endif - - _XReadPad(dpy, (char *) path_data, n); - - /* - * Check if the string can be fully - * contained by the buffer. - */ - - if (*path_data > path_length - 1) - { - #ifdef TEST - fprintf(stderr, "******NXGetFontParameters: Inconsistent length in the returned string.\n"); - #endif - - UnlockDisplay(dpy); - - SyncHandle(); - - return 0; - } - - #ifdef TEST - - fprintf(stderr, "******NXGetFontParameters: Got font path of [%d] bytes and value [", - (int) *path_data); - - for (i = 0; i < *path_data; i++) - { - fprintf(stderr, "%c", *(path_data + i + 1)); - } - - fprintf(stderr, "].\n"); - - #endif - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -unsigned int NXAllocSplit(Display *dpy, unsigned int resource) -{ - if (resource == NXAnyResource) - { - for (resource = 0; resource < NXNumberOfResources; resource++) - { - if (_NXSplitResources[resource] == 0) - { - _NXSplitResources[resource] = 1; - - #ifdef TEST - fprintf(stderr, "******NXAllocSplit: Reserved resource [%u].\n", - resource); - #endif - - return resource; - } - } - - #ifdef TEST - fprintf(stderr, "******NXAllocSplit: WARNING! Resource limit exausted.\n"); - #endif - - return NXNoResource; - } - else if (resource >= 0 && resource < NXNumberOfResources) - { - #ifdef TEST - - if (_NXSplitResources[resource] == 0) - { - fprintf(stderr, "******NXAllocSplit: Reserved requested resource [%u].\n", - resource); - } - else - { - fprintf(stderr, "******NXAllocSplit: Requested resource [%u] already reserved.\n", - resource); - } - - #endif - - _NXSplitResources[resource] = 1; - } - - #ifdef PANIC - fprintf(stderr, "******NXAllocSplit: PANIC! Can't reserve requested resource [%u].\n", - resource); - #endif - - return NXNoResource; -} - -/* - * Tell the proxy to split the next messages. - */ - -int NXStartSplit(Display *dpy, unsigned int resource, unsigned int mode) -{ - register xNXStartSplitReq *req; - - LockDisplay(dpy); - - GetReq(NXStartSplit, req); - - req -> resource = resource; - req -> mode = mode; - - #ifdef TEST - fprintf(stderr, "******NXStartSplit: Sending opcode [%d] with resource [%d] mode [%d].\n", - X_NXStartSplit, resource, mode); - #endif - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -/* - * Send the closure of the split sequence and - * tell the proxy to send the results. - */ - -int NXEndSplit(Display *dpy, unsigned int resource) -{ - register xNXEndSplitReq *req; - - LockDisplay(dpy); - - GetReq(NXEndSplit, req); - - req -> resource = resource; - - #ifdef TEST - fprintf(stderr, "******NXEndSplit: Sending opcode [%d] with resource [%d].\n", - X_NXStartSplit, resource); - #endif - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -/* - * This message must be sent whenever the proxy notifies - * the client of the completion of a split. If the 'pro- - * pagate' field is 0, the proxy will not send the ori- - * ginal request to the X server, but will only free the - * internal state. - */ - -int NXCommitSplit(Display *dpy, unsigned int resource, unsigned int propagate, - unsigned char request, unsigned int position) -{ - register xNXCommitSplitReq *req; - - LockDisplay(dpy); - - GetReq(NXCommitSplit, req); - - req -> resource = resource; - req -> propagate = propagate; - req -> request = request; - req -> position = position; - - #ifdef TEST - fprintf(stderr, "******NXCommitSplit: Sending opcode [%d] with resource [%d] propagate [%d] " - "request [%d] position [%d].\n", X_NXCommitSplit, resource, - propagate, request, position); - #endif - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -int NXAbortSplit(Display *dpy, unsigned int resource) -{ - register xNXAbortSplitReq *req; - - LockDisplay(dpy); - - GetReq(NXAbortSplit, req); - - #ifdef TEST - fprintf(stderr, "******NXAbortSplit: Sending message opcode [%d] with resource [%u].\n", - X_NXAbortSplit, resource); - #endif - - req -> resource = resource; - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -int NXFinishSplit(Display *dpy, unsigned int resource) -{ - register xNXFinishSplitReq *req; - - LockDisplay(dpy); - - GetReq(NXFinishSplit, req); - - #ifdef TEST - fprintf(stderr, "******NXFinishSplit: Sending message opcode [%d] with resource [%u].\n", - X_NXFinishSplit, resource); - #endif - - req -> resource = resource; - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -int NXFreeSplit(Display *dpy, unsigned int resource) -{ - register xNXFreeSplitReq *req; - - if (_NXSplitResources[resource] != 0) - { - LockDisplay(dpy); - - GetReq(NXFreeSplit, req); - - #ifdef TEST - fprintf(stderr, "******NXFreeSplit: Sending message opcode [%d] with resource [%u].\n", - X_NXFreeSplit, resource); - #endif - - req -> resource = resource; - - UnlockDisplay(dpy); - - SyncHandle(); - - #ifdef TEST - fprintf(stderr, "******NXFreeSplit: Making the resource [%u] newly available.\n", - resource); - #endif - - _NXSplitResources[resource] = 0; - } - #ifdef TEST - else - { - fprintf(stderr, "******NXFreeSplit: Nothing to do for resource [%u].\n", - resource); - } - #endif - - return 1; -} - -/* - * Tell to remote proxy to discard expose events - * of one or more types. - */ - -int NXSetExposeParameters(Display *dpy, int expose, int graphics_expose, int no_expose) -{ - register xNXSetExposeParametersReq *req; - - LockDisplay(dpy); - - GetReq(NXSetExposeParameters, req); - - req -> expose = expose; - req -> graphicsExpose = graphics_expose; - req -> noExpose = no_expose; - - #ifdef TEST - fprintf(stderr, "******NXSetExposeParameters: Sending message opcode [%d] with flags [%d][%d][%d].\n", - X_NXSetExposeParameters, req -> expose, req -> graphicsExpose, req -> noExpose); - #endif - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -/* - * Tell to the local proxy how to handle the next requests. - */ - -int NXSetCacheParameters(Display *dpy, int enable_cache, int enable_split, - int enable_save, int enable_load) -{ - register xNXSetCacheParametersReq *req; - - LockDisplay(dpy); - - GetReq(NXSetCacheParameters, req); - - req -> enableCache = enable_cache; - req -> enableSplit = enable_split; - req -> enableSave = enable_save; - req -> enableLoad = enable_load; - - #ifdef TEST - fprintf(stderr, "******NXSetCacheParameters: Sending message opcode [%d] with " - "flags [%d][%d][%d][%d].\n", X_NXSetCacheParameters, req -> enableCache, - req -> enableSplit, req -> enableSave, req -> enableLoad); - #endif - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -unsigned int NXAllocUnpack(Display *dpy, unsigned int resource) -{ - if (resource == NXAnyResource) - { - for (resource = 0; resource < NXNumberOfResources; resource++) - { - if (_NXUnpackResources[resource] == 0) - { - _NXUnpackResources[resource] = 1; - - #ifdef TEST - fprintf(stderr, "******NXAllocUnpack: Reserved resource [%u].\n", - resource); - #endif - - return resource; - } - } - - #ifdef TEST - fprintf(stderr, "******NXAllocUnpack: WARNING! Resource limit exausted.\n"); - #endif - - return NXNoResource; - } - else if (resource >= 0 && resource < NXNumberOfResources) - { - #ifdef TEST - - if (_NXUnpackResources[resource] == 0) - { - fprintf(stderr, "******NXAllocUnpack: Reserved requested resource [%u].\n", - resource); - } - else - { - fprintf(stderr, "******NXAllocUnpack: Requested resource [%u] already reserved.\n", - resource); - } - - #endif - - _NXUnpackResources[resource] = 1; - } - - #ifdef PANIC - fprintf(stderr, "******NXAllocUnpack: PANIC! Can't reserve requested resource [%u].\n", - resource); - #endif - - return NXNoResource; -} - -int NXSetUnpackGeometry(Display *dpy, unsigned int resource, Visual *visual) -{ - register xNXSetUnpackGeometryReq *req; - - LockDisplay(dpy); - - GetReq(NXSetUnpackGeometry, req); - - req -> resource = resource; - - req -> depth1Bpp = _XGetBitsPerPixel(dpy, 1); - req -> depth4Bpp = _XGetBitsPerPixel(dpy, 4); - req -> depth8Bpp = _XGetBitsPerPixel(dpy, 8); - req -> depth16Bpp = _XGetBitsPerPixel(dpy, 16); - req -> depth24Bpp = _XGetBitsPerPixel(dpy, 24); - req -> depth32Bpp = _XGetBitsPerPixel(dpy, 32); - - if (visual != NULL) - { - req -> redMask = visual -> red_mask; - req -> greenMask = visual -> green_mask; - req -> blueMask = visual -> blue_mask; - } - else - { - #ifdef PANIC - fprintf(stderr, "******NXSetUnpackGeometry: PANIC! Can't set the geometry without a visual.\n"); - #endif - - UnGetReq(NXSetUnpackGeometry); - - UnlockDisplay(dpy); - - return -1; - } - - #ifdef TEST - fprintf(stderr, "******NXSetUnpackGeometry: Resource [%u] Depth/Bpp [1/%d][4/%d][8/%d]" - "[16/%d][24/%d][32/%d].\n", resource, req -> depth1Bpp, req -> depth4Bpp, - req -> depth8Bpp, req -> depth16Bpp, req -> depth24Bpp, req -> depth32Bpp); - - fprintf(stderr, "******NXSetUnpackGeometry: red [0x%x] green [0x%x] blue [0x%x].\n", - (unsigned) req -> redMask, (unsigned) req -> greenMask, (unsigned) req -> blueMask); - #endif - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -/* - * Store a colormap table on the remote side. - * The colormap can then be used to unpack - * an image. - */ - -int NXSetUnpackColormap(Display *dpy, unsigned int resource, unsigned int method, - unsigned int entries, const char *data, unsigned int data_length) -{ - register xNXSetUnpackColormapReq *req; - - register int dst_data_length; - - LockDisplay(dpy); - - GetReq(NXSetUnpackColormap, req); - - req -> resource = resource; - req -> method = method; - - req -> srcLength = data_length; - req -> dstLength = entries << 2; - - dst_data_length = ROUNDUP(data_length, 4); - - req -> length += (dst_data_length >> 2); - - #ifdef TEST - fprintf(stderr, "******NXSetUnpackColormap: Resource [%u] data size [%u] destination " - "data size [%u].\n", resource, data_length, dst_data_length); - #endif - - if (data_length > 0) - { - if (dpy -> bufptr + dst_data_length <= dpy -> bufmax) - { - /* - * Clean the padding bytes in the request. - */ - - *((int *) (dpy -> bufptr + dst_data_length - 4)) = 0x0; - - memcpy(dpy -> bufptr, data, data_length); - - dpy -> bufptr += dst_data_length; - } - else - { - /* - * The _XSend() will pad the request for us. - */ - - _XSend(dpy, data, data_length); - } - } - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -/* - * Store data of the alpha blending channel - * that will be combined with the next image - * to be unpacked. - */ - -int NXSetUnpackAlpha(Display *dpy, unsigned int resource, unsigned int method, - unsigned int entries, const char *data, unsigned int data_length) -{ - register xNXSetUnpackAlphaReq *req; - - register unsigned int dst_data_length; - - LockDisplay(dpy); - - GetReq(NXSetUnpackAlpha, req); - - req -> resource = resource; - req -> method = method; - - req -> srcLength = data_length; - req -> dstLength = entries; - - dst_data_length = ROUNDUP(data_length, 4); - - req -> length += (dst_data_length >> 2); - - #ifdef TEST - fprintf(stderr, "******NXSetUnpackAlpha: Resource [%u] data size [%u] destination data size [%u].\n", - resource, data_length, dst_data_length); - #endif - - if (data_length > 0) - { - if (dpy -> bufptr + dst_data_length <= dpy -> bufmax) - { - /* - * Clean the padding bytes in the request. - */ - - *((int *) (dpy -> bufptr + dst_data_length - 4)) = 0x0; - - memcpy(dpy -> bufptr, data, data_length); - - dpy -> bufptr += dst_data_length; - } - else - { - /* - * The _XSend() will pad the request for us. - */ - - _XSend(dpy, data, data_length); - } - } - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -/* - * Compatibility versions to be used when - * connected to a 1.X.X proxy. - */ - -/* - * These are for compatibility with the 1.X.X - * versions. - */ - -#define sz_xNXSetUnpackColormapCompatReq 8 - -typedef struct _NXSetUnpackColormapCompatReq { - CARD8 reqType; - CARD8 resource; - CARD16 length B16; - CARD32 entries B32; -} xNXSetUnpackColormapCompatReq; - -#define X_NXSetUnpackColormapCompat X_NXSetUnpackColormap - -int NXSetUnpackColormapCompat(Display *dpy, unsigned int resource, - unsigned int entries, const char *data) -{ - register xNXSetUnpackColormapCompatReq *req; - - register char *dst_data; - - register int dst_data_length; - - #ifdef DUMP - - int i; - - #endif - - LockDisplay(dpy); - - GetReq(NXSetUnpackColormapCompat, req); - - req -> resource = resource; - req -> entries = entries; - - dst_data_length = entries << 2; - - req -> length += (dst_data_length >> 2); - - #ifdef TEST - fprintf(stderr, "******NXSetUnpackColormapCompat: Resource [%u] number of entries [%u] " - "destination data size [%u].\n", resource, entries, dst_data_length); - #endif - - if (entries > 0) - { - if ((dpy -> bufptr + dst_data_length) <= dpy -> bufmax) - { - dst_data = dpy -> bufptr; - } - else - { - if ((dst_data = _XAllocScratch(dpy, dst_data_length)) == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXSetUnpackColormapCompat: PANIC! Cannot allocate memory.\n"); - #endif - - UnGetReq(NXSetUnpackColormapCompat); - - UnlockDisplay(dpy); - - return -1; - } - } - - memcpy(dst_data, data, entries << 2); - - #ifdef DUMP - - fprintf(stderr, "******NXSetUnpackColormapCompat: Dumping colormap entries:\n"); - - for (i = 0; i < entries; i++) - { - fprintf(stderr, "******NXSetUnpackColormapCompat: [%d] -> [0x%x].\n", - i, *((int *) (dst_data + (i * 4)))); - } - - #endif - - if (dst_data == dpy -> bufptr) - { - dpy -> bufptr += dst_data_length; - } - else - { - _XSend(dpy, dst_data, dst_data_length); - } - } - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -#define sz_xNXSetUnpackAlphaCompatReq 8 - -typedef struct _NXSetUnpackAlphaCompatReq { - CARD8 reqType; - CARD8 resource; - CARD16 length B16; - CARD32 entries B32; -} xNXSetUnpackAlphaCompatReq; - -#define X_NXSetUnpackAlphaCompat X_NXSetUnpackAlpha - -int NXSetUnpackAlphaCompat(Display *dpy, unsigned int resource, - unsigned int entries, const char *data) -{ - register xNXSetUnpackAlphaCompatReq *req; - - register char *dst_data; - - register unsigned int dst_data_length; - - #ifdef DUMP - - int i; - - #endif - - LockDisplay(dpy); - - GetReq(NXSetUnpackAlphaCompat, req); - - req -> resource = resource; - req -> entries = entries; - - dst_data_length = ROUNDUP(entries, 4); - - req -> length += (dst_data_length >> 2); - - #ifdef TEST - fprintf(stderr, "******NXSetUnpackAlphaCompat: Resource [%u] number of entries [%u] " - "destination data size [%u].\n", resource, entries, dst_data_length); - #endif - - if (entries > 0) - { - if ((dpy -> bufptr + dst_data_length) <= dpy -> bufmax) - { - dst_data = dpy -> bufptr; - } - else - { - if ((dst_data = _XAllocScratch(dpy, dst_data_length)) == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXSetUnpackAlphaCompat: PANIC! Cannot allocate memory.\n"); - #endif - - UnGetReq(NXSetUnpackAlphaCompat); - - UnlockDisplay(dpy); - - return -1; - } - } - - memcpy(dst_data, data, entries); - - if (dst_data_length != entries) - { - memset(dst_data + entries, 0, dst_data_length - entries); - } - - #ifdef DUMP - - fprintf(stderr, "******NXSetUnpackAlphaCompat: Dumping alpha channel data:\n"); - - for (i = 0; i < dst_data_length; i++) - { - fprintf(stderr, "******NXSetUnpackAlphaCompat: [%d] -> [0x%02x].\n", - i, ((unsigned int) *(dst_data + i)) & 0xff); - } - - #endif - - if (dst_data == dpy -> bufptr) - { - dpy -> bufptr += dst_data_length; - } - else - { - _XSend(dpy, dst_data, dst_data_length); - } - } - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -/* - * Free any geometry, colormap and alpha channel - * data stored by the remote proxy to unpack the - * image. Resource, as usual, must be a value - * between 0 and 255. - */ - -int NXFreeUnpack(Display *dpy, unsigned int resource) -{ - register xNXFreeUnpackReq *req; - - if (_NXUnpackResources[resource] != 0) - { - LockDisplay(dpy); - - GetReq(NXFreeUnpack, req); - - #ifdef TEST - fprintf(stderr, "******NXFreeUnpack: Sending message opcode [%d] with resource [%u].\n", - X_NXFreeUnpack, resource); - #endif - - req -> resource = resource; - - UnlockDisplay(dpy); - - SyncHandle(); - - #ifdef TEST - fprintf(stderr, "******NXFreeUnpack: Making the resource [%u] newly available.\n", - resource); - #endif - - _NXUnpackResources[resource] = 0; - } - #ifdef TEST - else - { - fprintf(stderr, "******NXFreeUnpack: Nothing to do for resource [%u].\n", - resource); - } - #endif - - return 1; -} - -/* - * Wrapper of XCreateImage(). Note that we use offset - * field of XImage to store size of source image in - * packed format. Note also that method is currently - * not stored in the NXignored. - */ - -NXPackedImage *NXCreatePackedImage(Display *dpy, Visual *visual, unsigned int method, - unsigned int depth, int format, char *data, - int data_length, unsigned int width, - unsigned int height, int bitmap_pad, - int bytes_per_line) -{ - XImage* image; - - image = XCreateImage(dpy, visual, depth, format, 0, data, - width, height, bitmap_pad, bytes_per_line); - - if (image != NULL) - { - image -> xoffset = data_length; - } - - return (NXPackedImage *) image; -} - -/* - * Wrapper of XDestroyImage(). - */ - -int NXDestroyPackedImage(NXPackedImage *image) -{ - return XDestroyImage((XImage *) image); -} - -/* - * Clean the image data directly in the current buffer. - */ - -int NXCleanImage(XImage *image) -{ - #ifdef TEST - fprintf(stderr, "******NXCleanImage: Cleaning image with format [%d] depth [%d] " - "bits per pixel [%d].\n", image -> format, image -> depth, - image -> bits_per_pixel); - #endif - - if (image -> format == ZPixmap) - { - if (image -> depth == 1) - { - return CleanXYImage(image); - } - else - { - return CleanZImage(image); - } - } - else - { - return CleanXYImage(image); - } -} - -NXPackedImage *NXPackImage(Display *dpy, XImage *src_image, unsigned int method) -{ - XImage *dst_image; - - const ColorMask *mask; - - unsigned int dst_data_size; - unsigned int dst_packed_data_size; - - unsigned int dst_bits_per_pixel; - unsigned int dst_packed_bits_per_pixel; - - #ifdef TEST - fprintf(stderr, "******NXPackImage: Going to pack a new image with method [%d].\n", - method); - #endif - - /* - * Get the mask out of the method and - * check if the visual is supported by - * the color reduction algorithm. - */ - - mask = MethodColorMask(method); - - if (mask == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXPackImage: WARNING! No mask to apply for pack method [%d].\n", - method); - #endif - - return NULL; - } - else if (CanMaskImage(src_image, mask) == 0) - { - #ifdef PANIC - fprintf(stderr, "******NXPackImage: PANIC! Invalid source with format [%d] depth [%d] bits per pixel [%d].\n", - src_image -> format, src_image -> depth, src_image -> bits_per_pixel); - - fprintf(stderr, "******NXPackImage: PANIC! Visual colormask is red 0x%lx green 0x%lx blue 0x%lx.\n", - src_image -> red_mask, src_image -> green_mask, src_image -> blue_mask); - #endif - - return NULL; - } - - /* - * Create a destination image from - * source and apply the color mask. - */ - - if ((dst_image = (XImage *) Xmalloc(sizeof(XImage))) == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXPackImage: PANIC! Cannot allocate [%d] bytes for the image.\n", - (int) sizeof(XImage)); - #endif - - return NULL; - } - - *dst_image = *src_image; - - #ifdef TEST - fprintf(stderr, "******NXPackImage: Source width [%d], bytes per line [%d] with depth [%d].\n", - src_image -> width, src_image -> bytes_per_line, src_image -> depth); - #endif - - dst_data_size = src_image -> bytes_per_line * src_image -> height; - - dst_image -> data = Xmalloc(dst_data_size); - - if (dst_image -> data == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXPackImage: PANIC! Cannot allocate [%d] bytes for masked image data.\n", - dst_data_size); - #endif - - Xfree(dst_image); - - return NULL; - } - - /* - * If the pixel resulting from the mask - * needs more bits than available, then - * just clean the padding bits in the - * image. - */ - - dst_bits_per_pixel = dst_image -> bits_per_pixel; - dst_packed_bits_per_pixel = MethodBitsPerPixel(method); - - #ifdef TEST - fprintf(stderr, "******NXPackImage: Destination depth [%d], bits per pixel [%d], packed bits per pixel [%d].\n", - dst_image -> depth, dst_bits_per_pixel, dst_packed_bits_per_pixel); - #endif - - if (dst_packed_bits_per_pixel > dst_bits_per_pixel || - ShouldMaskImage(src_image, mask) == 0) - { - /* - * Should use the same data for source - * and destination to avoid the memcpy. - */ - - if (CopyAndCleanImage(src_image, dst_image) <= 0) - { - #ifdef PANIC - fprintf(stderr, "******NXPackImage: PANIC! Failed to clean the image.\n"); - #endif - - Xfree(dst_image -> data); - - Xfree(dst_image); - - return NULL; - } - } - else if (MaskImage(mask, src_image, dst_image) <= 0) - { - #ifdef PANIC - fprintf(stderr, "******NXPackImage: PANIC! Failed to apply the color mask.\n"); - #endif - - Xfree(dst_image -> data); - - Xfree(dst_image); - - return NULL; - } - - /* - * Let's pack the same pixels in fewer bytes. - * Note that we save a new memory allocation - * by using the same image as source and des- - * tination. This means that PackImage() must - * be able to handle ovelapping areas. - */ - - #ifdef TEST - fprintf(stderr, "******NXPackImage: Plain bits per pixel [%d], data size [%d].\n", - dst_bits_per_pixel, dst_data_size); - #endif - - dst_packed_data_size = dst_data_size * dst_packed_bits_per_pixel / - dst_bits_per_pixel; - - #ifdef TEST - fprintf(stderr, "******NXPackImage: Packed bits per pixel [%d], data size [%d].\n", - dst_packed_bits_per_pixel, dst_packed_data_size); - #endif - - if (PackImage(method, dst_data_size, dst_image, - dst_packed_data_size, dst_image) <= 0) - { - #ifdef PANIC - fprintf(stderr, "******NXPackImage: PANIC! Failed to pack image from [%d] to [%d] bits per pixel.\n", - dst_bits_per_pixel, dst_packed_bits_per_pixel); - #endif - - Xfree(dst_image -> data); - - Xfree(dst_image); - - return NULL; - } - - /* - * Save data size in xoffset field - * to comply with NX packed images. - */ - - dst_image -> xoffset = dst_packed_data_size; - - return dst_image; -} - -/* - * NXInPlacePackImage creates a NXPackedImage - * from a XImage, sharing the same data buffer. - * Is up to the caller to free the data buffer - * only once. - */ - -XImage *NXInPlacePackImage(Display *dpy, XImage *src_image, unsigned int method) -{ - XImage *dst_image; - - const ColorMask *mask; - - unsigned int dst_data_size; - unsigned int dst_packed_data_size; - - unsigned int dst_bits_per_pixel; - unsigned int dst_packed_bits_per_pixel; - - #ifdef TEST - fprintf(stderr, "******NXInPlacePackImage: Going to pack a new image with method [%d].\n", - method); - #endif - - /* - * Get mask out of method and check if - * visual is supported by current color - * reduction algorithm. - */ - - mask = MethodColorMask(method); - - if (mask == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXInPlacePackImage: WARNING! No mask to apply for pack method [%d].\n", - method); - #endif - - return NULL; - } - else if (CanMaskImage(src_image, mask) == 0) - { - #ifdef PANIC - fprintf(stderr, "******NXInPlacePackImage: PANIC! Invalid source with format [%d] depth [%d] bits per pixel [%d].\n", - src_image -> format, src_image -> depth, src_image -> bits_per_pixel); - - fprintf(stderr, "******NXInPlacePackImage: PANIC! Visual colormask is red 0x%lx green 0x%lx blue 0x%lx.\n", - src_image -> red_mask, src_image -> green_mask, src_image -> blue_mask); - #endif - return NULL; - } - - /* - * Create a destination image from - * source and apply the color mask. - */ - - if ((dst_image = (XImage *) Xmalloc(sizeof(XImage))) == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXInPlacePackImage: PANIC! Cannot allocate [%d] bytes for the image.\n", - (int) sizeof(XImage)); - #endif - - return NULL; - } - - *dst_image = *src_image; - - #ifdef TEST - fprintf(stderr, "******NXInPlacePackImage: Source width [%d], bytes per line [%d] with depth [%d].\n", - src_image -> width, src_image -> bytes_per_line, src_image -> depth); - #endif - - dst_data_size = src_image -> bytes_per_line * src_image -> height; - - dst_image -> data = src_image -> data; - - /* - * If pixel resulting from mask needs - * more bits than available, then just - * clean the pad bits in image. - */ - - dst_bits_per_pixel = dst_image -> bits_per_pixel; - dst_packed_bits_per_pixel = MethodBitsPerPixel(method); - - #ifdef TEST - fprintf(stderr, "******NXInPlacePackImage: Destination depth [%d], bits per pixel [%d], packed bits per pixel [%d].\n", - dst_image -> depth, dst_bits_per_pixel, dst_packed_bits_per_pixel); - #endif - - if (dst_packed_bits_per_pixel > dst_bits_per_pixel || - ShouldMaskImage(src_image, mask) == 0) - { - #ifdef TEST - fprintf(stderr, "******NXInPlacePackImage: Just clean image packed_bits_per_pixel[%d], bits_per_pixel[%d].\n", - dst_packed_bits_per_pixel, dst_bits_per_pixel); - #endif - - if (NXCleanImage(dst_image) <= 0) - { - #ifdef PANIC - fprintf(stderr, "******NXInPlacePackImage: PANIC! Failed to clean the image.\n"); - #endif - - Xfree(dst_image); - - return NULL; - } - } - else if (MaskInPlaceImage(mask, dst_image) <= 0) - { - #ifdef PANIC - fprintf(stderr, "******NXInPlacePackImage: PANIC! Failed to apply the color mask.\n"); - #endif - - Xfree(dst_image); - - return NULL; - } - - /* - * Let's pack the same pixels in fewer bytes. - * Note that we save a new memory allocation - * by using the same image as source and des- - * tination. This means that PackImage() must - * be able to handle ovelapping areas. - */ - - #ifdef TEST - fprintf(stderr, "******NXInPlacePackImage: Plain bits per pixel [%d], data size [%d].\n", - dst_bits_per_pixel, dst_data_size); - #endif - - dst_packed_data_size = dst_data_size * dst_packed_bits_per_pixel / - dst_bits_per_pixel; - - #ifdef TEST - fprintf(stderr, "******NXInPlacePackImage: Packed bits per pixel [%d], data size [%d].\n", - dst_packed_bits_per_pixel, dst_packed_data_size); - #endif - - /* - * Save data size in xoffset field - * to comply with NX packed images. - */ - - dst_image -> xoffset = dst_packed_data_size; - - return dst_image; -} - -int NXPutPackedImage(Display *dpy, unsigned int resource, Drawable drawable, - void *gc, NXPackedImage *image, unsigned int method, - unsigned int depth, int src_x, int src_y, int dst_x, - int dst_y, unsigned int width, unsigned int height) -{ - register xNXPutPackedImageReq *req; - - register unsigned int src_data_length; - register unsigned int dst_data_length; - - LockDisplay(dpy); - - FlushGC(dpy, (GC) gc); - - GetReq(NXPutPackedImage, req); - - req -> resource = resource; - req -> drawable = drawable; - req -> gc = ((GC) gc) -> gid; - - #ifdef TEST - fprintf(stderr, "******NXPutPackedImage: Image resource [%d] drawable [%d] gc [%d].\n", - req -> resource, (int) req -> drawable, (int) req -> gc); - #endif - - /* - * There is no leftPad field in request. We only - * support a leftPad of 0. Anyway, X imposes a - * leftPad of 0 in case of ZPixmap format. - */ - - req -> format = image -> format; - - /* - * Source depth, as well as width and height, - * are taken from the image structure. - */ - - req -> srcDepth = image -> depth; - - req -> srcX = src_x; - req -> srcY = src_y; - - req -> srcWidth = image -> width; - req -> srcHeight = image -> height; - - /* - * The destination depth is provided - * by the caller. - */ - - req -> dstDepth = depth; - - req -> dstX = dst_x; - req -> dstY = dst_y; - - req -> dstWidth = width; - req -> dstHeight = height; - - req -> method = method; - - #ifdef TEST - fprintf(stderr, "******NXPutPackedImage: Source image depth [%d] destination depth [%d] " - "method [%d].\n", req -> srcDepth, req -> dstDepth, req -> method); - #endif - - /* - * Source data length is the size of image in packed format, - * as stored in xoffset field of XImage. Destination data - * size is calculated according to bytes per line of target - * image, so the caller must provide the right depth at the - * time XImage structure is created. - */ - - req -> srcLength = image -> xoffset; - - if (image -> width == (int) width && - image -> height == (int) height) - { - req -> dstLength = image -> bytes_per_line * image -> height; - } - else if (image -> format == ZPixmap) - { - req -> dstLength = ROUNDUP((image -> bits_per_pixel * width), - image -> bitmap_pad) * height >> 3; - } - else - { - req -> dstLength = ROUNDUP(width, image -> bitmap_pad) * height >> 3; - } - - src_data_length = image -> xoffset; - - dst_data_length = ROUNDUP(src_data_length, 4); - - #ifdef TEST - fprintf(stderr, "******NXPutPackedImage: Source data length [%d] request data length [%d].\n", - src_data_length, dst_data_length); - #endif - - req -> length += (dst_data_length >> 2); - - if (src_data_length > 0) - { - if (dpy -> bufptr + dst_data_length <= dpy -> bufmax) - { - /* - * Clean the padding bytes in the request. - */ - - *((int *) (dpy -> bufptr + dst_data_length - 4)) = 0x0; - - memcpy(dpy -> bufptr, image -> data, src_data_length); - - dpy -> bufptr += dst_data_length; - } - else - { - /* - * The _XSend() will pad the request for us. - */ - - _XSend(dpy, image -> data, src_data_length); - } - } - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -int NXAllocColors(Display *dpy, Colormap colormap, unsigned int entries, - XColor screens_in_out[], Bool results_in_out[]) -{ - Status result = 0; - xAllocColorReply rep; - register xAllocColorReq *req; - - Bool alloc_error = False; - - register unsigned int i; - - LockDisplay(dpy); - - for (i = 0; i < entries; i++) - { - GetReq(AllocColor, req); - - req -> cmap = colormap; - - req -> red = screens_in_out[i].red; - req -> green = screens_in_out[i].green; - req -> blue = screens_in_out[i].blue; - } - - for (i = 0; i < entries; i++) - { - result = _XReply(dpy, (xReply *) &rep, 0, xTrue); - - if (result) - { - screens_in_out[i].pixel = rep.pixel; - - screens_in_out[i].red = rep.red; - screens_in_out[i].green = rep.green; - screens_in_out[i].blue = rep.blue; - - results_in_out[i] = True; - } - else - { - results_in_out[i] = False; - - alloc_error = True; - } - } - - UnlockDisplay(dpy); - - SyncHandle(); - - return (alloc_error == False); -} - -char *NXEncodeColormap(const char *src_data, unsigned int src_size, unsigned int *dst_size) -{ - return ColormapCompressData(src_data, src_size, dst_size); -} - -char *NXEncodeAlpha(const char *src_data, unsigned int src_size, unsigned int *dst_size) -{ - return AlphaCompressData(src_data, src_size, dst_size); -} - -NXPackedImage *NXEncodeRgb(XImage *src_image, unsigned int method, unsigned int quality) -{ - NXPackedImage *dst_image = NULL; - - unsigned int dst_size; - - /* - * Create a new image structure as a copy - * of the source. - */ - - if ((dst_image = (NXPackedImage *) Xmalloc(sizeof(NXPackedImage))) == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXEncodeRgb: PANIC! Cannot allocate [%d] bytes for the image.\n", - (int) sizeof(XImage)); - #endif - - return NULL; - } - - *dst_image = *src_image; - - dst_image -> data = RgbCompressData(src_image, &dst_size); - - if (dst_image -> data == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXEncodeRgb: PANIC! Rgb compression failed.\n"); - #endif - - Xfree(dst_image); - - return NULL; - } - - /* - * Store the Rgb size in the xoffset field. - */ - - dst_image -> xoffset = dst_size; - - return dst_image; -} - -NXPackedImage *NXEncodeRle(XImage *src_image, unsigned int method, unsigned int quality) -{ - NXPackedImage *dst_image = NULL; - - unsigned int dst_size; - - /* - * Create a new image structure as a copy - * of the source. - */ - - if ((dst_image = (NXPackedImage *) Xmalloc(sizeof(NXPackedImage))) == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXEncodeRle: PANIC! Cannot allocate [%d] bytes for the image.\n", - (int) sizeof(XImage)); - #endif - - return NULL; - } - - *dst_image = *src_image; - - dst_image -> data = RleCompressData(src_image, &dst_size); - - if (dst_image -> data == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXEncodeRle: PANIC! Rle compression failed.\n"); - #endif - - Xfree(dst_image); - - return NULL; - } - - /* - * Store the Rle size in the xoffset field. - */ - - dst_image -> xoffset = dst_size; - - return dst_image; -} - -NXPackedImage *NXEncodeBitmap(XImage *src_image, unsigned int method, unsigned int quality) -{ - NXPackedImage *dst_image = NULL; - - unsigned int dst_size; - - /* - * Create a new image structure as a copy - * of the source. - */ - - if ((dst_image = (NXPackedImage *) Xmalloc(sizeof(NXPackedImage))) == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXEncodeBitmap: PANIC! Cannot allocate [%d] bytes for the image.\n", - (int) sizeof(XImage)); - #endif - - return NULL; - } - - *dst_image = *src_image; - - dst_image -> data = BitmapCompressData(src_image, &dst_size); - - if (dst_image -> data == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXEncodeBitmap: PANIC! Bitmap compression failed.\n"); - #endif - - Xfree(dst_image); - - return NULL; - } - - /* - * Store the bitmap size in the xoffset field. - */ - - dst_image -> xoffset = dst_size; - - return dst_image; -} - -NXPackedImage *NXEncodeJpeg(XImage *src_image, unsigned int method, unsigned int quality) -{ - NXPackedImage *dst_image = NULL; - - int size; - - /* - * Check if the bpp of the image is valid - * for the Jpeg compression. - */ - - if (src_image -> bits_per_pixel < 15) - { - #ifdef PANIC - fprintf(stderr, "******NXEncodeJpeg: PANIC! Invalid bpp for Jpeg compression [%d]\n.", - src_image -> bits_per_pixel); - #endif - - return NULL; - } - - /* - * Create the destination image as a copy - * of the source. - */ - - if ((dst_image = (NXPackedImage *) Xmalloc(sizeof(NXPackedImage))) == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXEncodeJpeg: PANIC! Cannot allocate [%d] bytes for the Jpeg image.\n", - (int) sizeof(NXPackedImage)); - #endif - - return NULL; - } - - *dst_image = *src_image; - - dst_image -> data = JpegCompressData(src_image, quality, &size); - - if (dst_image -> data == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXEncodeJpeg: PANIC! Jpeg compression failed.\n"); - #endif - - Xfree(dst_image); - - return NULL; - } - - /* - * Store the Jpeg size in the xoffset field. - */ - - dst_image -> xoffset = size; - - return dst_image; -} - -NXPackedImage *NXEncodePng(XImage *src_image, unsigned int method, unsigned int quality) -{ - NXPackedImage *dst_image = NULL; - - int size; - - /* - * Check if the bpp of the image is valid - * for png compression. - */ - - if (src_image -> bits_per_pixel < 15) - { - #ifdef PANIC - fprintf(stderr, "******NXEncodePng: PANIC! Invalid bpp for Png compression [%d].\n", - src_image -> bits_per_pixel); - #endif - - return NULL; - } - - if ((dst_image = (NXPackedImage *) Xmalloc(sizeof(NXPackedImage))) == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXEncodePng: PANIC! Cannot allocate [%d] bytes for the Png image.\n", - (int) sizeof(NXPackedImage)); - #endif - - return NULL; - } - - *dst_image = *src_image; - - dst_image -> data = PngCompressData(dst_image, &size); - - if (dst_image -> data == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXEncodePng: PANIC! Png compression failed.\n"); - #endif - - Xfree(dst_image); - - return NULL; - } - - /* - * Store the Png size in the xoffset field. - */ - - dst_image -> xoffset = size; - - return dst_image; -} - -int NXEncodeColors(XImage *src_image, NXColorTable *color_table, int nb_max) -{ - int x, y, t, p; - - long pixel; - - /* - * We need a smarter way to extract - * the colors from the image and - * create a color table. - */ - - memset(color_table, 0, nb_max * sizeof(NXColorTable)); - - for (x = 0, p = 0; x < src_image -> width; x++) - { - for (y = 0; y < src_image -> height; y++) - { - pixel = XGetPixel(src_image, x, y); - - for (t = 0; t < nb_max; t++) - { - if ( color_table[t].found == 0) - { - color_table[t].pixel = pixel; - color_table[t].found = 1; - - p++; - - break; - } - else if ((color_table[t].pixel) == pixel) - { - break; - } - } - - if (p == nb_max) - { - return nb_max + 1; - } - } - } - - return p; -} - -void NXMaskImage(XImage *image, unsigned int method) -{ - unsigned int maskMethod; - - const ColorMask *mask; - - /* - * Choose the correct mask method - */ - - switch(method) - { - case PACK_JPEG_8_COLORS: - case PACK_PNG_8_COLORS: - { - maskMethod = MASK_8_COLORS; - - #ifdef DEBUG - fprintf(stderr, "******NXMaskImage: Method is MASK_8_COLORS\n"); - #endif - - break; - } - case PACK_JPEG_64_COLORS: - case PACK_PNG_64_COLORS: - { - maskMethod = MASK_64_COLORS; - - #ifdef DEBUG - fprintf(stderr, "******NXMaskImage: Method is MASK_64K_COLORS\n"); - #endif - - break; - } - case PACK_JPEG_256_COLORS: - case PACK_PNG_256_COLORS: - { - maskMethod = MASK_256_COLORS; - - #ifdef DEBUG - fprintf(stderr, "******NXMaskImage: Method is MASK_256_COLORS\n"); - #endif - - break; - } - case PACK_JPEG_512_COLORS: - case PACK_PNG_512_COLORS: - { - maskMethod = MASK_512_COLORS; - - #ifdef DEBUG - fprintf(stderr, "******NXMaskImage: Method is MASK_512K_COLORS\n"); - #endif - - break; - } - case PACK_JPEG_4K_COLORS: - case PACK_PNG_4K_COLORS: - { - maskMethod = MASK_4K_COLORS; - - #ifdef DEBUG - fprintf(stderr, "******NXMaskImage: Method is MASK_4K_COLORS\n"); - #endif - - break; - } - case PACK_JPEG_32K_COLORS: - case PACK_PNG_32K_COLORS: - { - maskMethod = MASK_32K_COLORS; - - #ifdef DEBUG - fprintf(stderr, "******NXMaskImage: Method is MASK_32K_COLORS\n"); - #endif - - break; - } - case PACK_JPEG_64K_COLORS: - case PACK_PNG_64K_COLORS: - { - maskMethod = MASK_64K_COLORS; - - #ifdef DEBUG - fprintf(stderr, "******NXMaskImage: Method is MASK_64K_COLORS\n"); - #endif - - break; - } - case PACK_JPEG_256K_COLORS: - case PACK_PNG_256K_COLORS: - { - maskMethod = MASK_256K_COLORS; - - #ifdef DEBUG - fprintf(stderr, "******NXMaskImage: Method is MASK_256K_COLORS\n"); - #endif - - break; - } - case PACK_JPEG_2M_COLORS: - case PACK_PNG_2M_COLORS: - { - maskMethod = MASK_2M_COLORS; - - #ifdef DEBUG - fprintf(stderr, "******NXMaskImage: Method is MASK_2M_COLORS\n"); - #endif - - break; - } - case PACK_JPEG_16M_COLORS: - case PACK_PNG_16M_COLORS: - { - maskMethod = MASK_16M_COLORS; - - #ifdef DEBUG - fprintf(stderr, "******NXMaskImage: Method is MASK_16M_COLORS\n"); - #endif - - break; - } - default: - { - #ifdef PANIC - fprintf(stderr, "******NXMaskImage: PANIC! Cannot find mask method for pack method [%d]\n", - method); - #endif - - return; - } - } - - #ifdef TEST - fprintf(stderr, "******NXMaskImage: packMethod[%d] => maskMethod[%d]\n", - method, maskMethod); - #endif - - /* - * Get mask out of method and check if - * visual is supported by current color - * reduction algorithm. - */ - - mask = MethodColorMask(maskMethod); - - if (mask == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXMaskImage: PANIC! No mask to apply for pack method [%d].\n", - method); - #endif - - return; - } - else if (CanMaskImage(image, mask) == 0) - { - #ifdef PANIC - fprintf(stderr, "******NXMaskImage: PANIC! Invalid source with format [%d] depth [%d] bits per pixel [%d].\n", - image -> format, image -> depth, image -> bits_per_pixel); - - fprintf(stderr, "******NXMaskImage: PANIC! Visual colormask is red 0x%lx green 0x%lx blue 0x%lx.\n", - image -> red_mask, image -> green_mask, image -> blue_mask); - #endif - - return; - } - - /* - * Calling ShouldMaskImage you get 0 in the case - * of MASK_256_COLORS and MASK_64K_COLORS, which - * means that the image should not be masked. - */ - - if (ShouldMaskImage(image, mask) == 0) - { - #ifdef TEST - fprintf(stderr, "******NXMaskImage: the image will not be masked\n"); - #endif - } - else - { - if (MaskInPlaceImage(mask, image) <= 0) - { - #ifdef PANIC - fprintf(stderr, "******NXMaskImage: PANIC! Failed to apply the color mask in place.\n"); - #endif - } - } -} - -/* - * The display parameter is ignored. - */ - -void NXInitCache(Display *dpy, int entries) -{ - if (NXImageCache != NULL && NXImageCacheSize == entries) - { - #ifdef DEBUG - fprintf(stderr, "******NXInitCache: Nothing to do with image cache at [%p] and [%d] entries.\n", - NXImageCache, NXImageCacheSize); - #endif - - return; - } - - #ifdef DEBUG - fprintf(stderr, "******NXInitCache: Initializing the cache with [%d] entries.\n", - entries); - #endif - - NXImageCacheSize = 0; - - if (NXImageCache != NULL) - { - Xfree(NXImageCache); - - NXImageCache = NULL; - } - - if (entries > 0) - { - NXImageCache = Xmalloc(entries * sizeof(_NXImageCacheEntry)); - - if (NXImageCache != NULL) - { - memset(NXImageCache, 0, entries * sizeof(_NXImageCacheEntry)); - - NXImageCacheSize = entries; - - #ifdef DEBUG - fprintf(stderr, "******NXInitCache: Image cache initialized with [%d] entries.\n", entries); - #endif - } - } -} - -#ifdef DUMP - -void _NXCacheDump(const char *label) -{ - char s[MD5_LENGTH * 2 + 1]; - - int i; - int j; - - #ifdef DEBUG - fprintf(stderr, "%s: Dumping the content of image cache:\n", label); - #endif - - for (i = 0; i < NXImageCacheSize; i++) - { - if (NXImageCache[i].image == NULL) - { - break; - } - - for (j = 0; j < MD5_LENGTH; j++) - { - sprintf(s + (j * 2), "%02X", ((unsigned char *) NXImageCache[i].md5)[j]); - } - - #ifdef DEBUG - fprintf(stderr, "%s: [%d][%s].\n", label, i, s); - #endif - } -} - -#endif - -XImage *NXCacheFindImage(NXPackedImage *src_image, unsigned int *method, unsigned char **md5) -{ - md5_state_t new_state; - md5_byte_t *new_md5; - unsigned int data_size, i; - - if (NXImageCache == NULL) - { - return NULL; - } - - /* - * Will return the allocated checksum - * if the image is not found. - */ - - *md5 = NULL; - - if ((new_md5 = Xmalloc(MD5_LENGTH)) == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXCacheFindImage: Can't allocate memory for the checksum.\n"); - #endif - - return NULL; - } - - data_size = (src_image -> bytes_per_line * src_image -> height); - - md5_init(&new_state); - - md5_append(&new_state, (unsigned char *) &src_image -> width, sizeof(int)); - md5_append(&new_state, (unsigned char *) &src_image -> height, sizeof(int)); - - md5_append(&new_state, (unsigned char *) src_image -> data, data_size); - - md5_finish(&new_state, new_md5); - - for (i = 0; i < NXImageCacheSize; i++) - { - if (NXImageCache[i].image != NULL) - { - if (memcmp(NXImageCache[i].md5, new_md5, MD5_LENGTH) == 0) - { - _NXImageCacheEntry found; - - found.image = NXImageCache[i].image; - found.method = NXImageCache[i].method; - found.md5 = NXImageCache[i].md5; - - *method = found.method; - - NXImageCacheHits++; - - #ifdef DEBUG - fprintf(stderr, "******NXCacheFindImage: Found at position [%d] with hits [%d] and [%d] packs.\n", - i, NXImageCacheHits, NXImageCacheOps); - #endif - - Xfree(new_md5); - - /* - * Move the images down one slot, from - * the head of the list, and place the - * image just found at top. - */ - - if (i > 16) - { - #ifdef DEBUG - fprintf(stderr, "******NXCacheFindImage: Moving the image at the head of the list.\n"); - #endif - - memmove(&NXImageCache[1], &NXImageCache[0], (i * sizeof(_NXImageCacheEntry))); - - NXImageCache[0].image = found.image; - NXImageCache[0].method = found.method; - NXImageCache[0].md5 = found.md5; - - #ifdef DUMP - - _NXCacheDump("******NXCacheFindImage"); - - #endif - } - - /* - * Return the checksum and image - * structure allocated in cache. - */ - - *md5 = found.md5; - - return found.image; - } - } - else - { - break; - } - } - - *md5 = new_md5; - - return NULL; -} - -/* - * Add a packed image to the cache. A new image - * structure is allocated and copied, data and - * checksum are inherited from the passed image. - */ - -int NXCacheAddImage(NXPackedImage *image, unsigned int method, unsigned char *md5) -{ - unsigned int i; - - if (image == NULL || image -> data == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXCacheAddImage: PANIC! Invalid image passed to function.\n"); - #endif - - return -1; - } - - i = (NXImageCacheOps < NXImageCacheSize) ? NXImageCacheOps : NXImageCacheSize; - - if (NXImageCacheOps >= NXImageCacheSize) - { - #ifdef DEBUG - fprintf(stderr, "******NXCacheAddImage: Freeing up the oldest entry.\n"); - #endif - - i--; - - Xfree(NXImageCache[NXImageCacheSize - 1].image -> data); - Xfree(NXImageCache[NXImageCacheSize - 1].image); - Xfree(NXImageCache[NXImageCacheSize - 1].md5); - } - - if (i > 0) - { - memmove(&NXImageCache[1], &NXImageCache[0], i * sizeof(_NXImageCacheEntry)); - } - - NXImageCacheOps++; - - #ifdef DEBUG - fprintf(stderr, "******NXCacheAddImage: Going to add new image with data size [%d].\n", - image -> xoffset); - #endif - - NXImageCache[0].image = image; - NXImageCache[0].method = method; - NXImageCache[0].md5 = md5; - - #ifdef DUMP - - _NXCacheDump("******NXCacheAddImage"); - - #endif - - return 1; -} - -/* - * The display parameter is ignored. - */ - -void NXFreeCache(Display *dpy) -{ - int i; - - if (NXImageCache == NULL) - { - #ifdef DEBUG - fprintf(stderr, "******NXFreeCache: Nothing to do with a null image cache.\n"); - #endif - - return; - } - - #ifdef DEBUG - fprintf(stderr, "******NXFreeCache: Freeing the cache with [%d] entries.\n", - NXImageCacheSize); - #endif - - for (i = 0; i < NXImageCacheSize; i++) - { - if (NXImageCache[i].image != NULL) - { - if (NXImageCache[i].image -> data != NULL) - { - Xfree(NXImageCache[i].image -> data); - } - - Xfree(NXImageCache[i].image); - - NXImageCache[i].image = NULL; - } - - if (NXImageCache[i].md5 != NULL) - { - Xfree(NXImageCache[i].md5); - - NXImageCache[i].md5 = NULL; - } - } - - Xfree(NXImageCache); - - NXImageCache = NULL; - - NXImageCacheSize = 0; - NXImageCacheHits = 0; - NXImageCacheOps = 0; -} - -static void _NXNotifyImage(Display *dpy, int resource, Bool success) -{ - XEvent async_event; - - /* - * Enqueue an event to tell client - * the result of GetImage. - */ - - async_event.type = ClientMessage; - - async_event.xclient.serial = _NXCollectedImages[resource] -> sequence; - - async_event.xclient.window = 0; - async_event.xclient.message_type = 0; - async_event.xclient.format = 32; - - async_event.xclient.data.l[0] = NXCollectImageNotify; - async_event.xclient.data.l[1] = resource; - async_event.xclient.data.l[2] = success; - - XPutBackEvent(dpy, &async_event); -} - -static Bool _NXCollectImageHandler(Display *dpy, xReply *rep, char *buf, - int len, XPointer data) -{ - register _NXCollectImageState *state; - - register xGetImageReply *async_rep; - - char *async_head; - char *async_data; - - int async_size; - - state = (_NXCollectImageState *) data; - - if ((rep -> generic.sequenceNumber % 65536) != - ((int)(state -> sequence) % 65536)) - { - #ifdef TEST - fprintf(stderr, "******_NXCollectImageHandler: Unmatched sequence [%d] for opcode [%d] " - "with length [%d].\n", rep -> generic.sequenceNumber, rep -> generic.type, - (int) rep -> generic.length << 2); - #endif - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectImageHandler: Going to handle asynchronous GetImage reply.\n"); - #endif - - /* - * As even reply data is managed asynchronously, - * we can use state to get to vector and vector - * to get to handler. In this way, we can safely - * dequeue and free the handler itself. - */ - - DeqAsyncHandler(dpy, state -> handler); - - Xfree(state -> handler); - - state -> handler = NULL; - - if (rep -> generic.type == X_Error) - { - #ifdef TEST - fprintf(stderr, "******_NXCollectImageHandler: Error received from X server for resource [%d].\n", - state -> resource); - #endif - - _NXNotifyImage(dpy, state -> resource, False); - - _NXCollectedImages[state -> resource] = NULL; - - Xfree(state); - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectImageHandler: Matched request with sequence [%ld].\n", - state -> sequence); - #endif - - async_size = SIZEOF(xGetImageReply); - - async_head = Xmalloc(async_size); - - if (async_head == NULL) - { - #ifdef PANIC - fprintf(stderr, "******_NXCollectImageHandler: PANIC! Failed to allocate memory with resource [%d].\n", - state -> resource); - #endif - - _NXNotifyImage(dpy, state -> resource, False); - - _NXCollectedImages[state -> resource] = NULL; - - Xfree(state); - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectImageHandler: Going to get reply with size [%d].\n", - (int) rep -> generic.length << 2); - #endif - - async_rep = (xGetImageReply *) _XGetAsyncReply(dpy, async_head, rep, buf, len, 0, False); - - if (async_rep == NULL) - { - #ifdef PANIC - fprintf(stderr, "******_NXCollectImageHandler: PANIC! Failed to get reply with resource [%d].\n", - state -> resource); - #endif - - _NXNotifyImage(dpy, state -> resource, False); - - _NXCollectedImages[state -> resource] = NULL; - - Xfree(state); - - Xfree(async_head); - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectImageHandler: Got reply with depth [%d] visual [%d] size [%d].\n", - async_rep -> depth, (int) async_rep -> visual, (int) async_rep -> length << 2); - #endif - - async_size = async_rep -> length << 2; - - if (async_size > 0) - { - async_data = Xmalloc(async_size); - - if (async_data == NULL) - { - #ifdef PANIC - fprintf(stderr, "******_NXCollectImageHandler: PANIC! Failed to allocate memory with resource [%d].\n", - state -> resource); - #endif - - _NXNotifyImage(dpy, state -> resource, False); - - _NXCollectedImages[state -> resource] = NULL; - - Xfree(state); - - Xfree(async_head); - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectImageHandler: Going to get data with size [%d].\n", - async_size); - #endif - - _XGetAsyncData(dpy, async_data, buf, len, SIZEOF(xGetImageReply), async_size, async_size); - - /* - * From now on we can return True, as all - * data has been consumed from buffer. - */ - - if (state -> format == XYPixmap) - { - unsigned long depth = DepthOnes(state -> mask & (((unsigned long)0xFFFFFFFF) >> - (32 - async_rep -> depth))); - - state -> image = XCreateImage(dpy, _XVIDtoVisual(dpy, async_rep -> visual), - depth, XYPixmap, 0, async_data, state -> width, - state -> height, dpy -> bitmap_pad, 0); - } - else - { - state -> image = XCreateImage(dpy, _XVIDtoVisual(dpy, async_rep -> visual), - async_rep -> depth, ZPixmap, 0, async_data, state -> width, - state -> height, _XGetScanlinePad(dpy, async_rep -> depth), 0); - } - - if (state -> image == NULL) - { - #ifdef PANIC - fprintf(stderr, "******_NXCollectImageHandler: PANIC! Failed to create image for resource [%d].\n", - state -> resource); - #endif - - _NXNotifyImage(dpy, state -> resource, False); - - _NXCollectedImages[state -> resource] = NULL; - - Xfree(state); - - Xfree(async_head); - Xfree(async_data); - - return True; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectImageHandler: Successfully stored image data for resource [%d].\n", - state -> resource); - #endif - } - #ifdef WARNING - else - { - fprintf(stderr, "******_NXCollectImageHandler: WARNING! Null image data stored for resource [%d].\n", - state -> resource); - } - #endif - - _NXNotifyImage(dpy, state -> resource, True); - - Xfree(async_head); - - return True; -} - -int NXGetCollectImageResource(Display *dpy) -{ - int i; - - for (i = 0; i < NXNumberOfResources; i++) - { - if (_NXCollectedImages[i] == NULL) - { - return i; - } - } - - return -1; -} - -int NXCollectImage(Display *dpy, unsigned int resource, Drawable drawable, - int src_x, int src_y, unsigned int width, unsigned int height, - unsigned long plane_mask, int format) -{ - register xGetImageReq *req; - - _NXCollectImageState *state; - _XAsyncHandler *handler; - - if (resource >= NXNumberOfResources) - { - #ifdef PANIC - fprintf(stderr, "******NXCollectImage: PANIC! Provided resource [%u] is out of range.\n", - resource); - #endif - - return -1; - } - - state = _NXCollectedImages[resource]; - - if (state != NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXCollectImage: PANIC! Having to remove previous state for resource [%u].\n", - resource); - #endif - - if (state -> handler != NULL) - { - DeqAsyncHandler(dpy, state -> handler); - - Xfree(state -> handler); - } - - if (state -> image != NULL) - { - XDestroyImage(state -> image); - } - - Xfree(state); - - _NXCollectedImages[resource] = NULL; - } - - LockDisplay(dpy); - - GetReq(GetImage, req); - - req -> format = format; - req -> drawable = drawable; - req -> x = src_x; - req -> y = src_y; - req -> width = width; - req -> height = height; - req -> planeMask = plane_mask; - - #ifdef TEST - fprintf(stderr, "******NXCollectImage: Sending message opcode [%d] sequence [%ld] for resource [%d].\n", - X_GetImage, dpy -> request, resource); - - fprintf(stderr, "******NXCollectImage: Format [%d] drawable [%d] src_x [%d] src_y [%d].\n", - req -> format, (int) req -> drawable, req -> x, req -> y); - - fprintf(stderr, "******NXCollectImage: Width [%d] height [%d] plane_mask [%x].\n", - req -> width, req -> height, (int) req -> planeMask); - #endif - - state = Xmalloc(sizeof(_NXCollectImageState)); - handler = Xmalloc(sizeof(_XAsyncHandler)); - - if (state == NULL || handler == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXCollectImage: PANIC! Failed to allocate memory with resource [%d].\n", - resource); - #endif - - UnGetReq(GetImage); - - if (state != NULL) - { - Xfree(state); - } - - if (handler != NULL) - { - Xfree(handler); - } - - UnlockDisplay(dpy); - - return -1; - } - - state -> sequence = dpy -> request; - state -> resource = resource; - state -> mask = plane_mask; - state -> format = format; - state -> width = width; - state -> height = height; - state -> image = NULL; - - state -> handler = handler; - - handler -> next = dpy -> async_handlers; - handler -> handler = _NXCollectImageHandler; - handler -> data = (XPointer) state; - dpy -> async_handlers = handler; - - _NXCollectedImages[resource] = state; - - UnlockDisplay(dpy); - - SyncHandle(); - - return 1; -} - -int NXGetCollectedImage(Display *dpy, unsigned int resource, XImage **image) -{ - register _NXCollectImageState *state; - - state = _NXCollectedImages[resource]; - - if (state == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXGetCollectedImage: PANIC! No image collected for resource [%u].\n", - resource); - #endif - - return 0; - } - - _NXCollectedImages[resource] = NULL; - - *image = state -> image; - - Xfree(state); - - #ifdef TEST - fprintf(stderr, "******NXGetCollectedImage: Returning GetImage data for resource [%u].\n", - resource); - #endif - - return 1; -} - -static void _NXNotifyProperty(Display *dpy, int resource, Bool success) -{ - XEvent async_event; - - /* - * Enqueue an event to tell client - * the result of GetProperty. - */ - - async_event.type = ClientMessage; - - async_event.xclient.serial = _NXCollectedProperties[resource] -> sequence; - - async_event.xclient.window = 0; - async_event.xclient.message_type = 0; - async_event.xclient.format = 32; - - async_event.xclient.data.l[0] = NXCollectPropertyNotify; - async_event.xclient.data.l[1] = resource; - async_event.xclient.data.l[2] = success; - - XPutBackEvent(dpy, &async_event); -} - -static Bool _NXCollectPropertyHandler(Display *dpy, xReply *rep, char *buf, - int len, XPointer data) -{ - register _NXCollectPropertyState *state; - - register xGetPropertyReply *async_rep; - - char *async_head; - char *async_data; - - int async_size; - - state = (_NXCollectPropertyState *) data; - - if ((rep -> generic.sequenceNumber % 65536) != - ((int)(state -> sequence) % 65536)) - { - #ifdef TEST - fprintf(stderr, "******_NXCollectPropertyHandler: Unmatched sequence [%d] for opcode [%d] " - "with length [%d].\n", rep -> generic.sequenceNumber, rep -> generic.type, - (int) rep -> generic.length << 2); - #endif - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectPropertyHandler: Going to handle asynchronous GetProperty reply.\n"); - #endif - - /* - * Reply data is managed asynchronously. We can - * use state to get to vector and vector to get - * to handler. In this way, we can dequeue and - * free the handler itself. - */ - - DeqAsyncHandler(dpy, state -> handler); - - Xfree(state -> handler); - - state -> handler = NULL; - - if (rep -> generic.type == X_Error) - { - #ifdef TEST - fprintf(stderr, "******_NXCollectPropertyHandler: Error received from X server for resource [%d].\n", - state -> resource); - #endif - - _NXNotifyProperty(dpy, state -> resource, False); - - _NXCollectedProperties[state -> resource] = NULL; - - Xfree(state); - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectPropertyHandler: Matched request with sequence [%ld].\n", - state -> sequence); - #endif - - async_size = SIZEOF(xGetPropertyReply); - - async_head = Xmalloc(async_size); - - if (async_head == NULL) - { - #ifdef PANIC - fprintf(stderr, "******_NXCollectPropertyHandler: PANIC! Failed to allocate memory with resource [%d].\n", - state -> resource); - #endif - - _NXNotifyProperty(dpy, state -> resource, False); - - _NXCollectedProperties[state -> resource] = NULL; - - Xfree(state); - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectPropertyHandler: Going to get reply with size [%d].\n", - (int) rep -> generic.length << 2); - #endif - - async_rep = (xGetPropertyReply *) _XGetAsyncReply(dpy, async_head, rep, buf, len, 0, False); - - if (async_rep == NULL) - { - #ifdef PANIC - fprintf(stderr, "******_NXCollectPropertyHandler: PANIC! Failed to get reply with resource [%d].\n", - state -> resource); - #endif - - _NXNotifyProperty(dpy, state -> resource, False); - - _NXCollectedProperties[state -> resource] = NULL; - - Xfree(state); - - Xfree(async_head); - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectPropertyHandler: Got reply with format [%d] type [%d] size [%d].\n", - async_rep -> format, (int) async_rep -> propertyType, (int) async_rep -> length << 2); - - fprintf(stderr, "******_NXCollectPropertyHandler: Bytes after [%d] number of items [%d].\n", - (int) async_rep -> bytesAfter, (int) async_rep -> nItems); - #endif - - state -> format = async_rep -> format; - state -> type = async_rep -> propertyType; - state -> items = async_rep -> nItems; - state -> after = async_rep -> bytesAfter; - - async_size = async_rep -> length << 2; - - if (async_size > 0) - { - async_data = Xmalloc(async_size); - - if (async_data == NULL) - { - #ifdef PANIC - fprintf(stderr, "******_NXCollectPropertyHandler: PANIC! Failed to allocate memory with resource [%d].\n", - state -> resource); - #endif - - _NXNotifyProperty(dpy, state -> resource, False); - - _NXCollectedProperties[state -> resource] = NULL; - - Xfree(state); - - Xfree(async_head); - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectPropertyHandler: Going to get data with size [%d].\n", - async_size); - #endif - - _XGetAsyncData(dpy, async_data, buf, len, SIZEOF(xGetPropertyReply), async_size, async_size); - - /* - * From now on we can return True, as all - * data has been consumed from buffer. - */ - - state -> data = async_data; - - #ifdef TEST - fprintf(stderr, "******_NXCollectPropertyHandler: Successfully stored property data for resource [%d].\n", - state -> resource); - #endif - } - #ifdef TEST - else - { - fprintf(stderr, "******_NXCollectPropertyHandler: WARNING! Null property data stored for resource [%d].\n", - state -> resource); - } - #endif - - _NXNotifyProperty(dpy, state -> resource, True); - - Xfree(async_head); - - return True; -} - -int NXGetCollectPropertyResource(Display *dpy) -{ - int i; - - for (i = 0; i < NXNumberOfResources; i++) - { - if (_NXCollectedProperties[i] == NULL) - { - return i; - } - } - - return -1; -} - -int NXCollectProperty(Display *dpy, unsigned int resource, Window window, Atom property, - long long_offset, long long_length, Bool delete, Atom req_type) -{ - register xGetPropertyReq *req; - - _NXCollectPropertyState *state; - _XAsyncHandler *handler; - - if (resource >= NXNumberOfResources) - { - #ifdef PANIC - fprintf(stderr, "******NXCollectProperty: PANIC! Provided resource [%u] is out of range.\n", - resource); - #endif - - return -1; - } - - state = _NXCollectedProperties[resource]; - - if (state != NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXCollectProperty: PANIC! Having to remove previous state for resource [%u].\n", - resource); - #endif - - if (state -> handler != NULL) - { - DeqAsyncHandler(dpy, state -> handler); - - Xfree(state -> handler); - } - - if (state -> data != NULL) - { - Xfree(state -> data); - } - - Xfree(state); - - _NXCollectedProperties[resource] = NULL; - } - - LockDisplay(dpy); - - GetReq(GetProperty, req); - - req -> delete = delete; - req -> window = window; - req -> property = property; - req -> type = req_type; - req -> longOffset = long_offset; - req -> longLength = long_length; - - #ifdef TEST - fprintf(stderr, "******NXCollectProperty: Sending message opcode [%d] sequence [%ld] for resource [%d].\n", - X_GetProperty, dpy -> request, resource); - - fprintf(stderr, "******NXCollectProperty: Delete [%u] window [%d] property [%d] type [%d].\n", - req -> delete, (int) req -> window, (int) req -> property, (int) req -> type); - - fprintf(stderr, "******NXCollectProperty: Long offset [%d] long length [%d].\n", - (int) req -> longOffset, (int) req -> longLength); - #endif - - state = Xmalloc(sizeof(_NXCollectPropertyState)); - handler = Xmalloc(sizeof(_XAsyncHandler)); - - if (state == NULL || handler == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXCollectProperty: Failed to allocate memory with resource [%d].\n", - resource); - #endif - - if (state != NULL) - { - Xfree(state); - } - - if (handler != NULL) - { - Xfree(handler); - } - - UnGetReq(GetProperty); - - UnlockDisplay(dpy); - - return -1; - } - - state -> sequence = dpy -> request; - state -> resource = resource; - state -> window = window; - state -> property = property; - state -> type = 0; - state -> format = 0; - state -> items = 0; - state -> after = 0; - state -> data = NULL; - - state -> handler = handler; - - handler -> next = dpy -> async_handlers; - handler -> handler = _NXCollectPropertyHandler; - handler -> data = (XPointer) state; - dpy -> async_handlers = handler; - - _NXCollectedProperties[resource] = state; - - UnlockDisplay(dpy); - - SyncHandle(); - - return True; -} - -int NXGetCollectedProperty(Display *dpy, unsigned int resource, Atom *actual_type_return, - int *actual_format_return, unsigned long *nitems_return, - unsigned long *bytes_after_return, unsigned char **data) -{ - register _NXCollectPropertyState *state; - - state = _NXCollectedProperties[resource]; - - if (state == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXGetCollectedProperty: PANIC! No data collected for resource [%u].\n", - resource); - #endif - - return 0; - } - - *actual_type_return = state -> type; - *actual_format_return = state -> format; - *nitems_return = state -> items; - *bytes_after_return = state -> after; - - *data = (unsigned char *) _NXCollectedProperties[resource] -> data; - - Xfree(state); - - _NXCollectedProperties[resource] = NULL; - - #ifdef TEST - fprintf(stderr, "******NXGetCollectedProperty: Returning GetProperty data for resource [%u].\n", - resource); - #endif - - return True; -} - -static void _NXNotifyGrabPointer(Display *dpy, int resource, Bool success) -{ - XEvent async_event; - - async_event.type = ClientMessage; - - async_event.xclient.serial = _NXCollectedGrabPointers[resource] -> sequence; - - async_event.xclient.window = 0; - async_event.xclient.message_type = 0; - async_event.xclient.format = 32; - - async_event.xclient.data.l[0] = NXCollectGrabPointerNotify; - async_event.xclient.data.l[1] = resource; - async_event.xclient.data.l[2] = success; - - XPutBackEvent(dpy, &async_event); -} - -static Bool _NXCollectGrabPointerHandler(Display *dpy, xReply *rep, char *buf, - int len, XPointer data) -{ - register _NXCollectGrabPointerState *state; - - register xGrabPointerReply *async_rep; - - char *async_head; - - int async_size; - - state = (_NXCollectGrabPointerState *) data; - - if ((rep -> generic.sequenceNumber % 65536) != - ((int)(state -> sequence) % 65536)) - { - #ifdef TEST - fprintf(stderr, "******_NXCollectGrabPointerHandler: Unmatched sequence [%d] for opcode [%d] " - "with length [%d].\n", rep -> generic.sequenceNumber, rep -> generic.type, - (int) rep -> generic.length << 2); - #endif - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectGrabPointerHandler: Going to handle asynchronous GrabPointer reply.\n"); - #endif - - DeqAsyncHandler(dpy, state -> handler); - - Xfree(state -> handler); - - state -> handler = NULL; - - if (rep -> generic.type == X_Error) - { - #ifdef TEST - fprintf(stderr, "******_NXCollectGrabPointerHandler: Error received from X server for resource [%d].\n", - state -> resource); - #endif - - _NXNotifyGrabPointer(dpy, state -> resource, False); - - _NXCollectedGrabPointers[state -> resource] = NULL; - - Xfree(state); - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectGrabPointerHandler: Matched request with sequence [%ld].\n", - state -> sequence); - #endif - - async_size = SIZEOF(xGrabPointerReply); - - async_head = Xmalloc(async_size); - - if (async_head == NULL) - { - #ifdef PANIC - fprintf(stderr, "******_NXCollectGrabPointerHandler: PANIC! Failed to allocate memory with resource [%d].\n", - state -> resource); - #endif - - _NXNotifyGrabPointer(dpy, state -> resource, False); - - _NXCollectedGrabPointers[state -> resource] = NULL; - - Xfree(state); - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectGrabPointerHandler: Going to get reply with size [%d].\n", - (int) rep -> generic.length << 2); - #endif - - async_rep = (xGrabPointerReply *) _XGetAsyncReply(dpy, async_head, rep, buf, len, 0, False); - - if (async_rep == NULL) - { - #ifdef PANIC - fprintf(stderr, "******_NXCollectGrabPointerHandler: PANIC! Failed to get reply with resource [%d].\n", - state -> resource); - #endif - - _NXNotifyGrabPointer(dpy, state -> resource, False); - - _NXCollectedGrabPointers[state -> resource] = NULL; - - Xfree(state); - - Xfree(async_head); - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectGrabPointerHandler: Got reply with status [%d] size [%d].\n", - async_rep -> status, (int) async_rep -> length << 2); - #endif - - state -> status = async_rep -> status; - - _NXNotifyGrabPointer(dpy, state -> resource, True); - - Xfree(async_head); - - return True; -} - -int NXGetCollectGrabPointerResource(Display *dpy) -{ - int i; - - for (i = 0; i < NXNumberOfResources; i++) - { - if (_NXCollectedGrabPointers[i] == NULL) - { - return i; - } - } - - return -1; -} - -int NXCollectGrabPointer(Display *dpy, unsigned int resource, Window grab_window, Bool owner_events, - unsigned int event_mask, int pointer_mode, int keyboard_mode, - Window confine_to, Cursor cursor, Time time) -{ - register xGrabPointerReq *req; - - _NXCollectGrabPointerState *state; - _XAsyncHandler *handler; - - if (resource >= NXNumberOfResources) - { - #ifdef PANIC - fprintf(stderr, "******NXCollectGrabPointer: PANIC! Provided resource [%u] is out of range.\n", - resource); - #endif - - return -1; - } - - state = _NXCollectedGrabPointers[resource]; - - if (state != NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXCollectGrabPointer: PANIC! Having to remove previous state for resource [%u].\n", - resource); - #endif - - if (state -> handler != NULL) - { - DeqAsyncHandler(dpy, state -> handler); - - Xfree(state -> handler); - } - - Xfree(state); - - _NXCollectedGrabPointers[resource] = NULL; - } - - LockDisplay(dpy); - - GetReq(GrabPointer, req); - - req -> grabWindow = grab_window; - req -> ownerEvents = owner_events; - req -> eventMask = event_mask; - req -> pointerMode = pointer_mode; - req -> keyboardMode = keyboard_mode; - req -> confineTo = confine_to; - req -> cursor = cursor; - req -> time = time; - - #ifdef TEST - fprintf(stderr, "******NXCollectGrabPointer: Sending message opcode [%d] sequence [%ld] " - "for resource [%d].\n", X_GrabPointer, dpy -> request, resource); - #endif - - state = Xmalloc(sizeof(_NXCollectGrabPointerState)); - handler = Xmalloc(sizeof(_XAsyncHandler)); - - if (state == NULL || handler == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXCollectGrabPointer: Failed to allocate memory with resource [%d].\n", - resource); - #endif - - if (state != NULL) - { - Xfree(state); - } - - if (handler != NULL) - { - Xfree(handler); - } - - UnGetReq(GrabPointer); - - UnlockDisplay(dpy); - - return -1; - } - - state -> sequence = dpy -> request; - state -> resource = resource; - state -> status = 0; - - state -> handler = handler; - - handler -> next = dpy -> async_handlers; - handler -> handler = _NXCollectGrabPointerHandler; - handler -> data = (XPointer) state; - dpy -> async_handlers = handler; - - _NXCollectedGrabPointers[resource] = state; - - UnlockDisplay(dpy); - - SyncHandle(); - - return True; -} - -int NXGetCollectedGrabPointer(Display *dpy, unsigned int resource, int *status) -{ - register _NXCollectGrabPointerState *state; - - state = _NXCollectedGrabPointers[resource]; - - if (state == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXGetCollectedGrabPointer: PANIC! No data collected for resource [%u].\n", - resource); - #endif - - return 0; - } - - *status = state -> status; - - Xfree(state); - - _NXCollectedGrabPointers[resource] = NULL; - - #ifdef TEST - fprintf(stderr, "******NXGetCollectedGrabPointer: Returning GrabPointer data for resource [%u].\n", - resource); - #endif - - return True; -} - -static void _NXNotifyInputFocus(Display *dpy, int resource, Bool success) -{ - XEvent async_event; - - async_event.type = ClientMessage; - - async_event.xclient.serial = _NXCollectedInputFocuses[resource] -> sequence; - - async_event.xclient.window = 0; - async_event.xclient.message_type = 0; - async_event.xclient.format = 32; - - async_event.xclient.data.l[0] = NXCollectInputFocusNotify; - async_event.xclient.data.l[1] = resource; - async_event.xclient.data.l[2] = success; - - XPutBackEvent(dpy, &async_event); -} - -static Bool _NXCollectInputFocusHandler(Display *dpy, xReply *rep, char *buf, - int len, XPointer data) -{ - register _NXCollectInputFocusState *state; - - register xGetInputFocusReply *async_rep; - - char *async_head; - - int async_size; - - state = (_NXCollectInputFocusState *) data; - - if ((rep -> generic.sequenceNumber % 65536) != - ((int)(state -> sequence) % 65536)) - { - #ifdef TEST - fprintf(stderr, "******_NXCollectInputFocusHandler: Unmatched sequence [%d] for opcode [%d] " - "with length [%d].\n", rep -> generic.sequenceNumber, rep -> generic.type, - (int) rep -> generic.length << 2); - #endif - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectInputFocusHandler: Going to handle asynchronous GetInputFocus reply.\n"); - #endif - - DeqAsyncHandler(dpy, state -> handler); - - Xfree(state -> handler); - - state -> handler = NULL; - - if (rep -> generic.type == X_Error) - { - #ifdef TEST - fprintf(stderr, "******_NXCollectInputFocusHandler: Error received from X server for resource [%d].\n", - state -> resource); - #endif - - _NXNotifyInputFocus(dpy, state -> resource, False); - - _NXCollectedInputFocuses[state -> resource] = NULL; - - Xfree(state); - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectInputFocusHandler: Matched request with sequence [%ld].\n", - state -> sequence); - #endif - - async_size = SIZEOF(xGetInputFocusReply); - - async_head = Xmalloc(async_size); - - if (async_head == NULL) - { - #ifdef PANIC - fprintf(stderr, "******_NXCollectInputFocusHandler: PANIC! Failed to allocate memory with resource [%d].\n", - state -> resource); - #endif - - _NXNotifyInputFocus(dpy, state -> resource, False); - - _NXCollectedInputFocuses[state -> resource] = NULL; - - Xfree(state); - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectInputFocusHandler: Going to get reply with size [%d].\n", - (int) rep -> generic.length << 2); - #endif - - async_rep = (xGetInputFocusReply *) _XGetAsyncReply(dpy, async_head, rep, buf, len, 0, False); - - if (async_rep == NULL) - { - #ifdef PANIC - fprintf(stderr, "******_NXCollectInputFocusHandler: PANIC! Failed to get reply with resource [%d].\n", - state -> resource); - #endif - - _NXNotifyInputFocus(dpy, state -> resource, False); - - _NXCollectedInputFocuses[state -> resource] = NULL; - - Xfree(state); - - Xfree(async_head); - - return False; - } - - #ifdef TEST - fprintf(stderr, "******_NXCollectInputFocusHandler: Got reply with focus [%d] revert to [%d] " - "size [%d].\n", (int) async_rep -> focus, (int) async_rep -> revertTo, - (int) async_rep -> length << 2); - #endif - - state -> focus = async_rep -> focus; - state -> revert_to = async_rep -> revertTo; - - _NXNotifyInputFocus(dpy, state -> resource, True); - - Xfree(async_head); - - return True; -} - -int NXGetCollectInputFocusResource(Display *dpy) -{ - int i; - - for (i = 0; i < NXNumberOfResources; i++) - { - if (_NXCollectedInputFocuses[i] == NULL) - { - return i; - } - } - - return -1; -} - -int NXCollectInputFocus(Display *dpy, unsigned int resource) -{ - register xReq *req; - - _NXCollectInputFocusState *state; - _XAsyncHandler *handler; - - if (resource >= NXNumberOfResources) - { - #ifdef PANIC - fprintf(stderr, "******NXCollectInputFocus: PANIC! Provided resource [%u] is out of range.\n", - resource); - #endif - - return -1; - } - - state = _NXCollectedInputFocuses[resource]; - - if (state != NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXCollectInputFocus: PANIC! Having to remove previous state for resource [%u].\n", - resource); - #endif - - if (state -> handler != NULL) - { - DeqAsyncHandler(dpy, state -> handler); - - Xfree(state -> handler); - } - - Xfree(state); - - _NXCollectedInputFocuses[resource] = NULL; - } - - LockDisplay(dpy); - - GetEmptyReq(GetInputFocus, req); - - #ifdef TEST - fprintf(stderr, "******NXCollectInputFocus: Sending message opcode [%d] sequence [%ld] for resource [%d].\n", - X_GetInputFocus, dpy -> request, resource); - #endif - - state = Xmalloc(sizeof(_NXCollectInputFocusState)); - handler = Xmalloc(sizeof(_XAsyncHandler)); - - if (state == NULL || handler == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXCollectInputFocus: Failed to allocate memory with resource [%d].\n", - resource); - #endif - - if (state != NULL) - { - Xfree(state); - } - - if (handler != NULL) - { - Xfree(handler); - } - - UnGetEmptyReq(); - - UnlockDisplay(dpy); - - return -1; - } - - state -> sequence = dpy -> request; - state -> resource = resource; - state -> focus = 0; - state -> revert_to = 0; - - state -> handler = handler; - - handler -> next = dpy -> async_handlers; - handler -> handler = _NXCollectInputFocusHandler; - handler -> data = (XPointer) state; - dpy -> async_handlers = handler; - - _NXCollectedInputFocuses[resource] = state; - - UnlockDisplay(dpy); - - SyncHandle(); - - return True; -} - -int NXGetCollectedInputFocus(Display *dpy, unsigned int resource, - Window *focus_return, int *revert_to_return) -{ - register _NXCollectInputFocusState *state; - - state = _NXCollectedInputFocuses[resource]; - - if (state == NULL) - { - #ifdef PANIC - fprintf(stderr, "******NXGetCollectedInputFocus: PANIC! No data collected for resource [%u].\n", - resource); - #endif - - return 0; - } - - *focus_return = state -> focus; - *revert_to_return = state -> revert_to; - - Xfree(state); - - _NXCollectedInputFocuses[resource] = NULL; - - #ifdef TEST - fprintf(stderr, "******NXGetCollectedInputFocus: Returning GetInputFocus data for resource [%u].\n", - resource); - #endif - - return True; -} - -#ifdef DUMP - -void _NXDumpData(const unsigned char *buffer, unsigned int size) -{ - if (buffer != NULL) - { - unsigned int i = 0; - - unsigned int ii; - - while (i < size) - { - fprintf(stderr, "[%d]\t", i); - - for (ii = 0; i < size && ii < 8; i++, ii++) - { - fprintf(stderr, "%d\t", (unsigned int) (buffer[i])); - } - - fprintf(stderr, "\n"); - } - } -} - -#endif |