summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-08-19 03:56:04 -0400
committerPietro Gagliardi <[email protected]>2014-08-19 03:56:04 -0400
commit751180ba20458efbbfc80ab66a8cf4d2d8a713c8 (patch)
tree1364a29530571062e92e62c207b3b0d524960dec
parentb6a5735f8954a22f37da0e4d393ef38ccfb7fba4 (diff)
Fixed message queue overload in Windows modality code.
-rw-r--r--redo/uitask_windows.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/redo/uitask_windows.c b/redo/uitask_windows.c
index 9b38aef..3382d41 100644
--- a/redo/uitask_windows.c
+++ b/redo/uitask_windows.c
@@ -71,6 +71,13 @@ 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)
@@ -81,6 +88,23 @@ 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;
@@ -93,20 +117,27 @@ static LRESULT CALLBACK msgwinproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
case msgRequest:
// in modal?
if (GetWindowLongPtrW(hwnd, GWLP_USERDATA) != 0) {
- // post again later
- // TODO this chokes the message queue!
- issue((void *) lParam);
- return 0;
+ 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());
+ }
}
// nope, we can run now
doissue((void *) lParam);
return 0;
case msgBeginModal:
- SetWindowLongPtrW(hwnd, GWLP_USERDATA, 1);
+ mq->inmodal = TRUE;
EnumThreadWindows(GetCurrentThreadId(), beginEndModalAll, msgBeginModal);
return 0;
case msgEndModal:
- SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0);
+ mq->inmodal = FALSE;
+ for (i = 0; i < mq->len; i++)
+ doissue(mq->modals[i]);
+ mq->len = 0;
EnumThreadWindows(GetCurrentThreadId(), beginEndModalAll, msgEndModal);
return 0;
default: