summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-08-19 13:25:52 -0400
committerPietro Gagliardi <[email protected]>2014-08-19 13:25:52 -0400
commita3ff63490b80c9f744978f3cf6e096a066c626e3 (patch)
tree309b82732f09d858beaa7c79fd34410fb3411417
parente5759d80de62958b24d5fe18c7e8b2d4a8241cc0 (diff)
Split the modal queue stuff into its own files.
-rw-r--r--redo/modalqueue.c48
-rw-r--r--redo/modalqueue.h8
-rw-r--r--redo/uitask_darwin.m40
-rw-r--r--redo/uitask_windows.c47
4 files changed, 65 insertions, 78 deletions
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 <stdlib.h>
+#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 <Cocoa/Cocoa.h>
#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: