]> git.sesse.net Git - rdpsrv/blobdiff - Xserver/programs/Xserver/dix/dixutils.c
Removed Xserver/ directory, it does nothing useful ATM.
[rdpsrv] / Xserver / programs / Xserver / dix / dixutils.c
diff --git a/Xserver/programs/Xserver/dix/dixutils.c b/Xserver/programs/Xserver/dix/dixutils.c
deleted file mode 100644 (file)
index edabfd7..0000000
+++ /dev/null
@@ -1,1011 +0,0 @@
-/***********************************************************
-
-Copyright (c) 1987  X Consortium
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the X Consortium shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from the X Consortium.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its 
-documentation for any purpose and without fee is hereby granted, 
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in 
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-/*
-
-(c)Copyright 1988,1991 Adobe Systems Incorporated. All rights reserved.
-
-Permission to use, copy, modify, distribute, and sublicense this software and its
-documentation for any purpose and without fee is hereby granted, provided that
-the above copyright notices appear in all copies and that both those copyright
-notices and this permission notice appear in supporting documentation and that
-the name of Adobe Systems Incorporated not be used in advertising or publicity
-pertaining to distribution of the software without specific, written prior
-permission.  No trademark license to use the Adobe trademarks is hereby
-granted.  If the Adobe trademark "Display PostScript"(tm) is used to describe
-this software, its functionality or for any other purpose, such use shall be
-limited to a statement that this software works in conjunction with the Display
-PostScript system.  Proper trademark attribution to reflect Adobe's ownership
-of the trademark shall be given whenever any such reference to the Display
-PostScript system is made.
-
-ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR ANY
-PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.  ADOBE
-DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
-WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-
-INFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO EVENT SHALL ADOBE BE LIABLE TO YOU
-OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
-DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,NEGLIGENCE, STRICT
-LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.  ADOBE WILL NOT PROVIDE ANY TRAINING OR OTHER
-SUPPORT FOR THE SOFTWARE.
-
-Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
-Incorporated which may be registered in certain jurisdictions.
-
-Author:  Adobe Systems Incorporated
-
-*/
-
-/* $TOG: dixutils.c /main/33 1997/05/22 10:02:20 kaleb $ */
-
-
-
-
-/* $XFree86: xc/programs/Xserver/dix/dixutils.c,v 3.1.2.1 1997/05/23 12:19:35 dawes Exp $ */
-
-#include "X.h"
-#include "Xmd.h"
-#include "misc.h"
-#include "windowstr.h"
-#include "dixstruct.h"
-#include "pixmapstr.h"
-#include "scrnintstr.h"
-#define  XK_LATIN1
-#include "keysymdef.h"
-#ifdef XCSECURITY
-#define _SECURITY_SERVER
-#include "extensions/security.h"
-#endif
-
-/*
- * CompareTimeStamps returns -1, 0, or +1 depending on if the first
- * argument is less than, equal to or greater than the second argument.
- */
-
-int
-CompareTimeStamps(a, b)
-    TimeStamp a, b;
-{
-    if (a.months < b.months)
-       return EARLIER;
-    if (a.months > b.months)
-       return LATER;
-    if (a.milliseconds < b.milliseconds)
-       return EARLIER;
-    if (a.milliseconds > b.milliseconds)
-       return LATER;
-    return SAMETIME;
-}
-
-/*
- * convert client times to server TimeStamps
- */
-
-#define HALFMONTH ((unsigned long) 1<<31)
-TimeStamp
-ClientTimeToServerTime(c)
-     CARD32 c;
-{
-    TimeStamp ts;
-    if (c == CurrentTime)
-       return currentTime;
-    ts.months = currentTime.months;
-    ts.milliseconds = c;
-    if (c > currentTime.milliseconds)
-    {
-       if (((unsigned long) c - currentTime.milliseconds) > HALFMONTH)
-           ts.months -= 1;
-    }
-    else if (c < currentTime.milliseconds)
-    {
-       if (((unsigned long)currentTime.milliseconds - c) > HALFMONTH)
-           ts.months += 1;
-    }
-    return ts;
-}
-
-/*
- * ISO Latin-1 case conversion routine
- *
- * this routine always null-terminates the result, so
- * beware of too-small buffers
- */
-
-void
-CopyISOLatin1Lowered(dest, source, length)
-    register unsigned char *dest, *source;
-    int length;
-{
-    register int i;
-
-    for (i = 0; i < length; i++, source++, dest++)
-    {
-       if ((*source >= XK_A) && (*source <= XK_Z))
-           *dest = *source + (XK_a - XK_A);
-       else if ((*source >= XK_Agrave) && (*source <= XK_Odiaeresis))
-           *dest = *source + (XK_agrave - XK_Agrave);
-       else if ((*source >= XK_Ooblique) && (*source <= XK_Thorn))
-           *dest = *source + (XK_oslash - XK_Ooblique);
-       else
-           *dest = *source;
-    }
-    *dest = '\0';
-}
-
-#ifdef XCSECURITY
-
-/* SecurityLookupWindow and SecurityLookupDrawable:
- * Look up the window/drawable taking into account the client doing
- * the lookup and the type of access desired.  Return the window/drawable
- * if it exists and the client is allowed access, else return NULL.
- * Most Proc* functions should be calling these instead of
- * LookupWindow and LookupDrawable, which do no access checks.
- */
-
-WindowPtr
-SecurityLookupWindow(rid, client, access_mode)
-    XID rid;
-    ClientPtr client;
-    Mask access_mode;
-{
-    WindowPtr  pWin;
-
-    client->errorValue = rid;
-    if(rid == INVALID)
-       return NULL;
-    if (client->trustLevel != XSecurityClientTrusted)
-       return (WindowPtr)SecurityLookupIDByType(client, rid, RT_WINDOW, access_mode);
-    if (client->lastDrawableID == rid)
-    {
-        if (client->lastDrawable->type == DRAWABLE_WINDOW)
-            return ((WindowPtr) client->lastDrawable);
-        return (WindowPtr) NULL;
-    }
-    pWin = (WindowPtr)SecurityLookupIDByType(client, rid, RT_WINDOW, access_mode);
-    if (pWin && pWin->drawable.type == DRAWABLE_WINDOW) {
-       client->lastDrawable = (DrawablePtr) pWin;
-       client->lastDrawableID = rid;
-       client->lastGCID = INVALID;
-       client->lastGC = (GCPtr)NULL;
-    }
-    return pWin;
-}
-
-
-pointer
-SecurityLookupDrawable(rid, client, access_mode)
-    XID rid;
-    ClientPtr client;
-    Mask access_mode;
-{
-    register DrawablePtr pDraw;
-
-    if(rid == INVALID)
-       return (pointer) NULL;
-    if (client->trustLevel != XSecurityClientTrusted)
-       return (DrawablePtr)SecurityLookupIDByClass(client, rid, RC_DRAWABLE,
-                                                   access_mode);
-    if (client->lastDrawableID == rid)
-       return ((pointer) client->lastDrawable);
-    pDraw = (DrawablePtr)SecurityLookupIDByClass(client, rid, RC_DRAWABLE,
-                                                access_mode);
-    if (pDraw && (pDraw->type != UNDRAWABLE_WINDOW))
-        return (pointer)pDraw;         
-    return (pointer)NULL;
-}
-
-/* We can't replace the LookupWindow and LookupDrawable functions with
- * macros because of compatibility with loadable servers.
- */
-
-WindowPtr
-LookupWindow(rid, client)
-    XID rid;
-    ClientPtr client;
-{
-    return SecurityLookupWindow(rid, client, SecurityUnknownAccess);
-}
-
-pointer
-LookupDrawable(rid, client)
-    XID rid;
-    ClientPtr client;
-{
-    return SecurityLookupDrawable(rid, client, SecurityUnknownAccess);
-}
-
-#else /* not XCSECURITY */
-
-WindowPtr
-LookupWindow(rid, client)
-    XID rid;
-    ClientPtr client;
-{
-    WindowPtr  pWin;
-
-    client->errorValue = rid;
-    if(rid == INVALID)
-       return NULL;
-    if (client->lastDrawableID == rid)
-    {
-        if (client->lastDrawable->type == DRAWABLE_WINDOW)
-            return ((WindowPtr) client->lastDrawable);
-        return (WindowPtr) NULL;
-    }
-    pWin = (WindowPtr)LookupIDByType(rid, RT_WINDOW);
-    if (pWin && pWin->drawable.type == DRAWABLE_WINDOW) {
-       client->lastDrawable = (DrawablePtr) pWin;
-       client->lastDrawableID = rid;
-       client->lastGCID = INVALID;
-       client->lastGC = (GCPtr)NULL;
-    }
-    return pWin;
-}
-
-
-pointer
-LookupDrawable(rid, client)
-    XID rid;
-    ClientPtr client;
-{
-    register DrawablePtr pDraw;
-
-    if(rid == INVALID)
-       return (pointer) NULL;
-    if (client->lastDrawableID == rid)
-       return ((pointer) client->lastDrawable);
-    pDraw = (DrawablePtr)LookupIDByClass(rid, RC_DRAWABLE);
-    if (pDraw && (pDraw->type != UNDRAWABLE_WINDOW))
-        return (pointer)pDraw;         
-    return (pointer)NULL;
-}
-
-#endif /* XCSECURITY */
-
-ClientPtr
-LookupClient(rid, client)
-    XID rid;
-    ClientPtr client;
-{
-    pointer pRes = (pointer)SecurityLookupIDByClass(client, rid, RC_ANY,
-                                                   SecurityReadAccess);
-    int clientIndex = CLIENT_ID(rid);
-
-    if (clientIndex && pRes && clients[clientIndex] && !(rid & SERVER_BIT))
-    {
-       return clients[clientIndex];
-    }
-    return (ClientPtr)NULL;
-}
-
-
-int
-AlterSaveSetForClient(client, pWin, mode)
-    ClientPtr client;
-    WindowPtr pWin;
-    unsigned mode;
-{
-    int numnow;
-    pointer *pTmp;
-    int j;
-
-    numnow = client->numSaved;
-    j = 0;
-    if (numnow)
-    {
-       pTmp = client->saveSet;
-       while ((j < numnow) && (pTmp[j] != (pointer)pWin))
-           j++;
-    }
-    if (mode == SetModeInsert)
-    {
-       if (j < numnow)         /* duplicate */
-          return(Success);
-       numnow++;
-       pTmp = (pointer *)xrealloc(client->saveSet, sizeof(pointer) * numnow);
-       if (!pTmp)
-           return(BadAlloc);
-       client->saveSet = pTmp;
-               client->numSaved = numnow;
-       client->saveSet[numnow - 1] = (pointer)pWin;
-       return(Success);
-    }
-    else if ((mode == SetModeDelete) && (j < numnow))
-    {
-       while (j < numnow-1)
-       {
-           pTmp[j] = pTmp[j+1];
-          j++;
-       }
-       numnow--;
-        if (numnow)
-       {
-           pTmp = (pointer *)xrealloc(client->saveSet,
-                                      sizeof(pointer) * numnow);
-           if (pTmp)
-               client->saveSet = pTmp;
-       }
-        else
-        {
-            xfree(client->saveSet);
-           client->saveSet = (pointer *)NULL;
-       }
-       client->numSaved = numnow;
-       return(Success);
-    }
-    return(Success);
-}
-
-void
-DeleteWindowFromAnySaveSet(pWin)
-    WindowPtr pWin;
-{
-    register int i;
-    register ClientPtr client;
-    
-    for (i = 0; i< currentMaxClients; i++)
-    {    
-       client = clients[i];
-       if (client && client->numSaved)
-           (void)AlterSaveSetForClient(client, pWin, SetModeDelete);
-    }
-}
-
-/* No-op Don't Do Anything : sometimes we need to be able to call a procedure
- * that doesn't do anything.  For example, on screen with only static
- * colormaps, if someone calls install colormap, it's easier to have a dummy
- * procedure to call than to check if there's a procedure 
- */
-void
-NoopDDA(
-#if NeedVarargsPrototypes
-    void* f, ...
-#endif
-)
-{
-}
-
-typedef struct _BlockHandler {
-    BlockHandlerProcPtr BlockHandler;
-    WakeupHandlerProcPtr WakeupHandler;
-    pointer blockData;
-    Bool    deleted;
-} BlockHandlerRec, *BlockHandlerPtr;
-
-static BlockHandlerPtr handlers;
-static int             numHandlers;
-static int             sizeHandlers;
-static Bool            inHandler;
-static Bool            handlerDeleted;
-
-/* called from the OS layer */
-void
-BlockHandler(pTimeout, pReadmask)
-pointer        pTimeout;       /* DIX doesn't want to know how OS represents time */
-pointer pReadmask;     /* nor how it represents the set of descriptors */
-{
-    register int i, j;
-    
-    ++inHandler;
-    for (i = 0; i < screenInfo.numScreens; i++)
-       (* screenInfo.screens[i]->BlockHandler)(i, 
-                               screenInfo.screens[i]->blockData,
-                               pTimeout, pReadmask);
-    for (i = 0; i < numHandlers; i++)
-       (*handlers[i].BlockHandler) (handlers[i].blockData,
-                                    pTimeout, pReadmask);
-    if (handlerDeleted)
-    {
-       for (i = 0; i < numHandlers;)
-           if (handlers[i].deleted)
-           {
-               for (j = i; j < numHandlers - 1; j++)
-                   handlers[j] = handlers[j+1];
-               numHandlers--;
-           }
-           else
-               i++;
-       handlerDeleted = FALSE;
-    }
-    --inHandler;
-}
-
-void
-WakeupHandler(result, pReadmask)
-int    result; /* 32 bits of undefined result from the wait */
-pointer pReadmask;     /* the resulting descriptor mask */
-{
-    register int i, j;
-
-    ++inHandler;
-    for (i = numHandlers - 1; i >= 0; i--)
-       (*handlers[i].WakeupHandler) (handlers[i].blockData,
-                                     result, pReadmask);
-    for (i = 0; i < screenInfo.numScreens; i++)
-       (* screenInfo.screens[i]->WakeupHandler)(i, 
-                               screenInfo.screens[i]->wakeupData,
-                               result, pReadmask);
-    if (handlerDeleted)
-    {
-       for (i = 0; i < numHandlers;)
-           if (handlers[i].deleted)
-           {
-               for (j = i; j < numHandlers - 1; j++)
-                   handlers[j] = handlers[j+1];
-               numHandlers--;
-           }
-           else
-               i++;
-       handlerDeleted = FALSE;
-    }
-    --inHandler;
-}
-
-/* Reentrant with BlockHandler and WakeupHandler, except wakeup won't
- * get called until next time
- */
-
-Bool
-RegisterBlockAndWakeupHandlers (blockHandler, wakeupHandler, blockData)
-    BlockHandlerProcPtr blockHandler;
-    WakeupHandlerProcPtr wakeupHandler;
-    pointer blockData;
-{
-    BlockHandlerPtr new;
-
-    if (numHandlers >= sizeHandlers)
-    {
-       new = (BlockHandlerPtr) xrealloc (handlers, (numHandlers + 1) *
-                                         sizeof (BlockHandlerRec));
-       if (!new)
-           return FALSE;
-       handlers = new;
-       sizeHandlers = numHandlers + 1;
-    }
-    handlers[numHandlers].BlockHandler = blockHandler;
-    handlers[numHandlers].WakeupHandler = wakeupHandler;
-    handlers[numHandlers].blockData = blockData;
-    handlers[numHandlers].deleted = FALSE;
-    numHandlers = numHandlers + 1;
-    return TRUE;
-}
-
-void
-RemoveBlockAndWakeupHandlers (blockHandler, wakeupHandler, blockData)
-    BlockHandlerProcPtr blockHandler;
-    WakeupHandlerProcPtr wakeupHandler;
-    pointer blockData;
-{
-    int            i;
-
-    for (i = 0; i < numHandlers; i++)
-       if (handlers[i].BlockHandler == blockHandler &&
-           handlers[i].WakeupHandler == wakeupHandler &&
-           handlers[i].blockData == blockData)
-       {
-           if (inHandler)
-           {
-               handlerDeleted = TRUE;
-               handlers[i].deleted = TRUE;
-           }
-           else
-           {
-               for (; i < numHandlers - 1; i++)
-                   handlers[i] = handlers[i+1];
-               numHandlers--;
-           }
-           break;
-       }
-}
-
-void
-InitBlockAndWakeupHandlers ()
-{
-    xfree (handlers);
-    handlers = (BlockHandlerPtr) 0;
-    numHandlers = 0;
-    sizeHandlers = 0;
-}
-
-/*
- * A general work queue.  Perform some task before the server
- * sleeps for input.
- */
-
-WorkQueuePtr           workQueue;
-static WorkQueuePtr    *workQueueLast = &workQueue;
-
-void
-ProcessWorkQueue()
-{
-    WorkQueuePtr    q, *p;
-
-    p = &workQueue;
-    /*
-     * Scan the work queue once, calling each function.  Those
-     * which return TRUE are removed from the queue, otherwise
-     * they will be called again.  This must be reentrant with
-     * QueueWorkProc.
-     */
-    while (q = *p)
-    {
-       if ((*q->function) (q->client, q->closure))
-       {
-           /* remove q from the list */
-           *p = q->next;    /* don't fetch until after func called */
-           xfree (q);
-       }
-       else
-       {
-           p = &q->next;    /* don't fetch until after func called */
-       }
-    }
-    workQueueLast = p;
-}
-
-void
-ProcessWorkQueueZombies()
-{
-    WorkQueuePtr    q, *p;
-
-    p = &workQueue;
-    while (q = *p)
-    {
-       if (q->client && q->client->clientGone)
-       {
-           (void) (*q->function) (q->client, q->closure);
-           /* remove q from the list */
-           *p = q->next;    /* don't fetch until after func called */
-           xfree (q);
-       }
-       else
-       {
-           p = &q->next;    /* don't fetch until after func called */
-       }
-    }
-    workQueueLast = p;
-}
-
-Bool
-#if NeedFunctionPrototypes
-QueueWorkProc (
-    Bool       (*function)(
-#if NeedNestedPrototypes
-               ClientPtr       /* pClient */,
-               pointer         /* closure */
-#endif
-               ),
-    ClientPtr  client,
-    pointer    closure)
-#else
-QueueWorkProc (function, client, closure)
-    Bool       (*function)();
-    ClientPtr  client;
-    pointer    closure;
-#endif
-{
-    WorkQueuePtr    q;
-
-    q = (WorkQueuePtr) xalloc (sizeof *q);
-    if (!q)
-       return FALSE;
-    q->function = function;
-    q->client = client;
-    q->closure = closure;
-    q->next = NULL;
-    *workQueueLast = q;
-    workQueueLast = &q->next;
-    return TRUE;
-}
-
-/*
- * Manage a queue of sleeping clients, awakening them
- * when requested, by using the OS functions IgnoreClient
- * and AttendClient.  Note that this *ignores* the troubles
- * with request data interleaving itself with events, but
- * we'll leave that until a later time.
- */
-
-typedef struct _SleepQueue {
-    struct _SleepQueue *next;
-    ClientPtr          client;
-    ClientSleepProcPtr  function;
-    pointer            closure;
-} SleepQueueRec, *SleepQueuePtr;
-
-static SleepQueuePtr   sleepQueue = NULL;
-
-Bool
-ClientSleep (client, function, closure)
-    ClientPtr  client;
-    ClientSleepProcPtr function;
-    pointer    closure;
-{
-    SleepQueuePtr   q;
-
-    q = (SleepQueuePtr) xalloc (sizeof *q);
-    if (!q)
-       return FALSE;
-
-    IgnoreClient (client);
-    q->next = sleepQueue;
-    q->client = client;
-    q->function = function;
-    q->closure = closure;
-    sleepQueue = q;
-    return TRUE;
-}
-
-Bool
-ClientSignal (client)
-    ClientPtr  client;
-{
-    SleepQueuePtr   q;
-
-    for (q = sleepQueue; q; q = q->next)
-       if (q->client == client)
-       {
-           return QueueWorkProc (q->function, q->client, q->closure);
-       }
-    return FALSE;
-}
-
-void
-ClientWakeup (client)
-    ClientPtr  client;
-{
-    SleepQueuePtr   q, *prev;
-
-    prev = &sleepQueue;
-    while ( (q = *prev) )
-    {
-       if (q->client == client)
-       {
-           *prev = q->next;
-           xfree (q);
-           if (client->clientGone)
-               CloseDownClient(client);
-           else
-               AttendClient (client);
-           break;
-       }
-       prev = &q->next;
-    }
-}
-
-Bool
-ClientIsAsleep (client)
-    ClientPtr  client;
-{
-    SleepQueuePtr   q;
-
-    for (q = sleepQueue; q; q = q->next)
-       if (q->client == client)
-           return TRUE;
-    return FALSE;
-}
-
-/*
- *  Generic Callback Manager
- */
-
-/* ===== Private Procedures ===== */
-
-static int numCallbackListsToCleanup = 0;
-static CallbackListPtr **listsToCleanup = NULL;
-
-static Bool 
-#if NeedFunctionPrototypes
-_AddCallback(
-    CallbackListPtr *pcbl,
-    CallbackProcPtr callback,
-    pointer         data)
-#else
-_AddCallback(pcbl, callback, data)
-    CallbackListPtr *pcbl;
-    CallbackProcPtr callback;
-    pointer         data;
-#endif
-{
-    CallbackPtr     cbr;
-
-    cbr = (CallbackPtr) xalloc(sizeof(CallbackRec));
-    if (!cbr)
-       return FALSE;
-    cbr->proc = callback;
-    cbr->data = data;
-    cbr->next = (*pcbl)->list;
-    cbr->deleted = FALSE;
-    (*pcbl)->list = cbr;
-    return TRUE;
-}
-
-static Bool 
-#if NeedFunctionPrototypes
-_DeleteCallback(
-    CallbackListPtr *pcbl,
-    CallbackProcPtr callback,
-    pointer         data)
-#else
-_DeleteCallback(pcbl, callback, data)
-    CallbackListPtr *pcbl;
-    CallbackProcPtr callback;
-    pointer         data;
-#endif
-{
-    CallbackListPtr cbl = *pcbl;
-    CallbackPtr     cbr, pcbr;
-
-    for (pcbr = NULL, cbr = cbl->list;
-        cbr != NULL;
-        pcbr = cbr, cbr = cbr->next)
-    {
-       if ((cbr->proc == callback) && (cbr->data == data))
-           break;
-    }
-    if (cbr != NULL)
-    {
-       if (cbl->inCallback)
-       {
-           ++(cbl->numDeleted);
-           cbr->deleted = TRUE;
-       }
-       else
-       {
-           if (pcbr == NULL)
-               cbl->list = cbr->next;
-           else
-               pcbr->next = cbr->next;
-           xfree(cbr);
-       }
-       return TRUE;
-    }
-    return FALSE;
-}
-
-static void 
-#if NeedFunctionPrototypes
-_CallCallbacks(
-    CallbackListPtr    *pcbl,
-    pointer        call_data)
-#else
-_CallCallbacks(pcbl, call_data)
-    CallbackListPtr    *pcbl;
-    pointer        call_data;
-#endif
-{
-    CallbackListPtr cbl = *pcbl;
-    CallbackPtr     cbr, pcbr;
-
-    ++(cbl->inCallback);
-    for (cbr = cbl->list; cbr != NULL; cbr = cbr->next)
-    {
-       (*(cbr->proc)) (pcbl, cbr->data, call_data);
-    }
-    --(cbl->inCallback);
-
-    if (cbl->inCallback) return;
-
-    /* Was the entire list marked for deletion? */
-
-    if (cbl->deleted)
-    {
-       DeleteCallbackList(pcbl);
-       return;
-    }
-
-    /* Were some individual callbacks on the list marked for deletion?
-     * If so, do the deletions.
-     */
-
-    if (cbl->numDeleted)
-    {
-       for (pcbr = NULL, cbr = cbl->list; (cbr != NULL) && cbl->numDeleted; )
-       {
-           if (cbr->deleted)
-           {
-               if (pcbr)
-               {
-                   cbr = cbr->next;
-                   xfree(pcbr->next);
-                   pcbr->next = cbr;
-               } else
-               {
-                   cbr = cbr->next;
-                   xfree(cbl->list);
-                   cbl->list = cbr;
-               }
-               cbl->numDeleted--;
-           }
-           else /* this one wasn't deleted */
-           {
-               pcbr = cbr;
-               cbr = cbr->next;
-           }
-       }
-    }
-}
-
-static void
-#if NeedFunctionPrototypes
-_DeleteCallbackList(
-    CallbackListPtr    *pcbl)
-#else
-_DeleteCallbackList(pcbl)
-    CallbackListPtr    *pcbl;
-#endif
-{
-    CallbackListPtr cbl = *pcbl;
-    CallbackPtr     cbr, nextcbr;
-    int i;
-
-    if (cbl->inCallback)
-    {
-       cbl->deleted = TRUE;
-       return;
-    }
-
-    for (i = 0; i < numCallbackListsToCleanup; i++)
-    {
-       if ((listsToCleanup[i] = pcbl) != 0)
-       {
-           listsToCleanup[i] = NULL;
-           break;
-       }
-    }
-
-    for (cbr = cbl->list; cbr != NULL; cbr = nextcbr)
-    {
-       nextcbr = cbr->next;
-       xfree(cbr);
-    }
-    xfree(cbl);
-    *pcbl = NULL;
-}
-
-static CallbackFuncsRec default_cbfuncs =
-{
-    _AddCallback,
-    _DeleteCallback,
-    _CallCallbacks,
-    _DeleteCallbackList
-};
-
-/* ===== Public Procedures ===== */
-
-Bool
-CreateCallbackList(pcbl, cbfuncs)
-    CallbackListPtr  *pcbl;
-    CallbackFuncsPtr cbfuncs;
-{
-    CallbackListPtr  cbl;
-    int i;
-
-    if (!pcbl) return FALSE;
-    cbl = (CallbackListPtr) xalloc(sizeof(CallbackListRec));
-    if (!cbl) return FALSE;
-    cbl->funcs = cbfuncs ? *cbfuncs : default_cbfuncs;
-    cbl->inCallback = 0;
-    cbl->deleted = FALSE;
-    cbl->numDeleted = 0;
-    cbl->list = NULL;
-    *pcbl = cbl;
-
-    for (i = 0; i < numCallbackListsToCleanup; i++)
-    {
-       if (!listsToCleanup[i])
-       {
-           listsToCleanup[i] = pcbl;
-           return TRUE;
-       }    
-    }
-
-    listsToCleanup = (CallbackListPtr **)xnfrealloc(listsToCleanup,
-               sizeof(CallbackListPtr *) * (numCallbackListsToCleanup+1));
-    listsToCleanup[numCallbackListsToCleanup] = pcbl;
-    numCallbackListsToCleanup++;
-    return TRUE;
-}
-
-Bool 
-AddCallback(pcbl, callback, data)
-    CallbackListPtr *pcbl;
-    CallbackProcPtr callback;
-    pointer         data;
-{
-    if (!pcbl) return FALSE;
-    if (!*pcbl)
-    {  /* list hasn't been created yet; go create it */
-       if (!CreateCallbackList(pcbl, (CallbackFuncsPtr)NULL))
-           return FALSE;
-    }
-    return ((*(*pcbl)->funcs.AddCallback) (pcbl, callback, data));
-}
-
-Bool 
-DeleteCallback(pcbl, callback, data)
-    CallbackListPtr *pcbl;
-    CallbackProcPtr callback;
-    pointer         data;
-{
-    if (!pcbl || !*pcbl) return FALSE;
-    return ((*(*pcbl)->funcs.DeleteCallback) (pcbl, callback, data));
-}
-
-void 
-CallCallbacks(pcbl, call_data)
-    CallbackListPtr    *pcbl;
-    pointer        call_data;
-{
-    if (!pcbl || !*pcbl) return;
-    (*(*pcbl)->funcs.CallCallbacks) (pcbl, call_data);
-}
-
-void
-DeleteCallbackList(pcbl)
-    CallbackListPtr    *pcbl;
-{
-    if (!pcbl || !*pcbl) return;
-    (*(*pcbl)->funcs.DeleteCallbackList) (pcbl);
-}
-
-void 
-InitCallbackManager()
-{
-    int i;
-
-    for (i = 0; i < numCallbackListsToCleanup; i++)
-    {
-       DeleteCallbackList(listsToCleanup[i]);
-    }
-    if (listsToCleanup) xfree(listsToCleanup);
-
-    numCallbackListsToCleanup = 0;
-    listsToCleanup = NULL;
-}