From a3ff63490b80c9f744978f3cf6e096a066c626e3 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Tue, 19 Aug 2014 13:25:52 -0400 Subject: [PATCH] Split the modal queue stuff into its own files. --- redo/modalqueue.c | 48 +++++++++++++++++++++++++++++++++++++++++++ redo/modalqueue.h | 8 ++++++++ redo/uitask_darwin.m | 40 +++--------------------------------- redo/uitask_windows.c | 47 ++++++------------------------------------ 4 files changed, 65 insertions(+), 78 deletions(-) create mode 100644 redo/modalqueue.c create mode 100644 redo/modalqueue.h diff --git a/redo/modalqueue.c b/redo/modalqueue.c new file mode 100644 index 0000000..7474c95 --- /dev/null +++ b/redo/modalqueue.c @@ -0,0 +1,48 @@ +// 19 august 2014 + +#include +#include "modalqueue.h" + +static struct { + int inmodal; + void **queue; + size_t len; + size_t cap; +} mq = { 0, NULL, 0, 0 }; + +void beginModal(void) +{ + mq.inmodal = 1; + if (mq.queue == NULL) { + mq.cap = 128; + mq.queue = (void **) malloc(mq.cap * sizeof (void *)); + if (mq.queue == NULL) + abort();//TODO + mq.len = 0; + } +} + +void endModal(void) +{ + size_t i; + + mq.inmodal = 0; + for (i = 0; i < mq.len; i++) + doissue(mq.queue[i]); + mq.len = 0; +} + +int queueIfModal(void *what) +{ + if (!mq.inmodal) + return 0; + mq.queue[mq.len] = what; + mq.len++; + if (mq.len >= mq.cap) { + mq.cap *= 2; + mq.queue = (void **) realloc(mq.queue, mq.cap * sizeof (void *)); + if (mq.queue == NULL) + abort();//TODO + } + return 1; +} diff --git a/redo/modalqueue.h b/redo/modalqueue.h new file mode 100644 index 0000000..912ba32 --- /dev/null +++ b/redo/modalqueue.h @@ -0,0 +1,8 @@ +/* 19 august 2014 */ + +extern void beginModal(void); +extern void endModal(void); +extern int queueIfModal(void *); + +/* needed by the above */ +extern void doissue(void *); diff --git a/redo/uitask_darwin.m b/redo/uitask_darwin.m index 9d25a61..86de4ce 100644 --- a/redo/uitask_darwin.m +++ b/redo/uitask_darwin.m @@ -2,6 +2,7 @@ #import "objc_darwin.h" #import "_cgo_export.h" +#import "modalqueue.h" #import #define toNSWindow(x) ((NSWindow *) (x)) @@ -129,48 +130,13 @@ void uistop(void) [NSApp postEvent:e atStart:NO]; // let pending events take priority } -// because dispatch_suspend()/dispatch_resume() can't be used with the main queue -static BOOL inmodal = NO; -static void **modalqueue = NULL; -static size_t mqlen = 0; -static size_t mqcap = 0; - -void beginModal(void) -{ - inmodal = YES; - if (modalqueue == NULL) { - mqcap = 128; - modalqueue = (void **) malloc(mqcap * sizeof (void *)); - if (modalqueue == NULL) - abort();//TODO - mqlen = 0; - } -} - -void endModal(void) -{ - size_t i; - - inmodal = NO; - for (i = 0; i < mqlen; i++) - doissue(modalqueue[i]); - mqlen = 0; -} +// we use the modal queue because dispatch_suspend()/dispatch_resume() can't be used with the main queue // thanks to mikeash in irc.freenode.net/#macdev for suggesting the use of Grand Central Dispatch and blocks for this void issue(void *what) { - if (inmodal) { - modalqueue[mqlen] = what; - mqlen++; - if (mqlen >= mqcap) { - mqcap *= 2; - modalqueue = (void **) realloc(modalqueue, mqcap * sizeof (void *)); - if (modalqueue == NULL) - abort();//TODO - } + if (queueIfModal(what)) return; - } dispatch_async(dispatch_get_main_queue(), ^{ doissue(what); }); diff --git a/redo/uitask_windows.c b/redo/uitask_windows.c index 3732270..ac8141b 100644 --- a/redo/uitask_windows.c +++ b/redo/uitask_windows.c @@ -2,6 +2,7 @@ #include "winapi_windows.h" #include "_cgo_export.h" +#include "modalqueue.h" // note that this includes the terminating '\0' // this also assumes WC_TABCONTROL is longer than areaWindowClass @@ -71,13 +72,6 @@ HWND msgwin; #define msgwinclass L"gouimsgwin" -struct modalqueue { - BOOL inmodal; - void **modals; - size_t len; - size_t cap; -}; - static BOOL CALLBACK beginEndModalAll(HWND hwnd, LPARAM lParam) { if (hwnd != msgwin) @@ -88,24 +82,8 @@ static BOOL CALLBACK beginEndModalAll(HWND hwnd, LPARAM lParam) static LRESULT CALLBACK msgwinproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT shared; - struct modalqueue *mq; size_t i; - mq = (struct modalqueue *) GetWindowLongPtrW(hwnd, GWLP_USERDATA); - if (mq == NULL) { - mq = (struct modalqueue *) malloc(sizeof (struct modalqueue)); - if (mq == NULL) - xpanic("error allocating modal queue structure", GetLastError()); - ZeroMemory(mq, sizeof (struct modalqueue)); - mq->inmodal = FALSE; - mq->len = 0; - mq->cap = 128; - mq->modals = (void **) malloc(mq->cap * sizeof (void *)); - if (mq->modals == NULL) - xpanic("error allocating modal quque", GetLastError()); - SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) mq); - } - if (sharedWndProc(hwnd, uMsg, wParam, lParam, &shared)) return shared; switch (uMsg) { @@ -116,29 +94,16 @@ static LRESULT CALLBACK msgwinproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l // TODO respond to WM_THEMECHANGED case msgRequest: // in modal? - if (mq->inmodal) { - mq->modals[mq->len] = (void *) lParam; - mq->len++; - if (mq->len >= mq->cap) { - mq->cap *= 2; - mq->modals = (void **) realloc(mq->modals, mq->cap * sizeof (void *)); - if (mq->modals == NULL) - xpanic("error growing modal queue", GetLastError()); - } - return; - } - // nope, we can run now - doissue((void *) lParam); + if (!queueIfModal((void *) lParam)) + // nope, we can run now + doissue((void *) lParam); return 0; case msgBeginModal: - mq->inmodal = TRUE; + beginModal(); EnumThreadWindows(GetCurrentThreadId(), beginEndModalAll, msgBeginModal); return 0; case msgEndModal: - mq->inmodal = FALSE; - for (i = 0; i < mq->len; i++) - doissue(mq->modals[i]); - mq->len = 0; + endModal(); EnumThreadWindows(GetCurrentThreadId(), beginEndModalAll, msgEndModal); return 0; default: