📄 dixutils.c
字号:
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;}voidRemoveBlockAndWakeupHandlers (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; }}voidInitBlockAndWakeupHandlers (){ 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;voidProcessWorkQueue(){ 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;}voidProcessWorkQueueZombies(){ 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 NeedFunctionPrototypesQueueWorkProc ( Bool (*function)(#if NeedNestedPrototypes ClientPtr /* pClient */, pointer /* closure */#endif ), ClientPtr client, pointer closure)#elseQueueWorkProc (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;BoolClientSleep (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;}BoolClientSignal (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;}voidClientWakeup (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; }}BoolClientIsAsleep (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 ===== */BoolCreateCallbackList(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);}voidDeleteCallbackList(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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -