Split the modal queue stuff into its own files.
This commit is contained in:
parent
e5759d80de
commit
a3ff63490b
|
@ -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;
|
||||||
|
}
|
|
@ -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 *);
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#import "objc_darwin.h"
|
#import "objc_darwin.h"
|
||||||
#import "_cgo_export.h"
|
#import "_cgo_export.h"
|
||||||
|
#import "modalqueue.h"
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
#define toNSWindow(x) ((NSWindow *) (x))
|
#define toNSWindow(x) ((NSWindow *) (x))
|
||||||
|
@ -129,48 +130,13 @@ void uistop(void)
|
||||||
[NSApp postEvent:e atStart:NO]; // let pending events take priority
|
[NSApp postEvent:e atStart:NO]; // let pending events take priority
|
||||||
}
|
}
|
||||||
|
|
||||||
// because dispatch_suspend()/dispatch_resume() can't be used with the main queue
|
// we use the modal queue 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// thanks to mikeash in irc.freenode.net/#macdev for suggesting the use of Grand Central Dispatch and blocks for this
|
// thanks to mikeash in irc.freenode.net/#macdev for suggesting the use of Grand Central Dispatch and blocks for this
|
||||||
void issue(void *what)
|
void issue(void *what)
|
||||||
{
|
{
|
||||||
if (inmodal) {
|
if (queueIfModal(what))
|
||||||
modalqueue[mqlen] = what;
|
|
||||||
mqlen++;
|
|
||||||
if (mqlen >= mqcap) {
|
|
||||||
mqcap *= 2;
|
|
||||||
modalqueue = (void **) realloc(modalqueue, mqcap * sizeof (void *));
|
|
||||||
if (modalqueue == NULL)
|
|
||||||
abort();//TODO
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
doissue(what);
|
doissue(what);
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "winapi_windows.h"
|
#include "winapi_windows.h"
|
||||||
#include "_cgo_export.h"
|
#include "_cgo_export.h"
|
||||||
|
#include "modalqueue.h"
|
||||||
|
|
||||||
// note that this includes the terminating '\0'
|
// note that this includes the terminating '\0'
|
||||||
// this also assumes WC_TABCONTROL is longer than areaWindowClass
|
// this also assumes WC_TABCONTROL is longer than areaWindowClass
|
||||||
|
@ -71,13 +72,6 @@ HWND msgwin;
|
||||||
|
|
||||||
#define msgwinclass L"gouimsgwin"
|
#define msgwinclass L"gouimsgwin"
|
||||||
|
|
||||||
struct modalqueue {
|
|
||||||
BOOL inmodal;
|
|
||||||
void **modals;
|
|
||||||
size_t len;
|
|
||||||
size_t cap;
|
|
||||||
};
|
|
||||||
|
|
||||||
static BOOL CALLBACK beginEndModalAll(HWND hwnd, LPARAM lParam)
|
static BOOL CALLBACK beginEndModalAll(HWND hwnd, LPARAM lParam)
|
||||||
{
|
{
|
||||||
if (hwnd != msgwin)
|
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)
|
static LRESULT CALLBACK msgwinproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
LRESULT shared;
|
LRESULT shared;
|
||||||
struct modalqueue *mq;
|
|
||||||
size_t i;
|
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))
|
if (sharedWndProc(hwnd, uMsg, wParam, lParam, &shared))
|
||||||
return shared;
|
return shared;
|
||||||
switch (uMsg) {
|
switch (uMsg) {
|
||||||
|
@ -116,29 +94,16 @@ static LRESULT CALLBACK msgwinproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
|
||||||
// TODO respond to WM_THEMECHANGED
|
// TODO respond to WM_THEMECHANGED
|
||||||
case msgRequest:
|
case msgRequest:
|
||||||
// in modal?
|
// in modal?
|
||||||
if (mq->inmodal) {
|
if (!queueIfModal((void *) lParam))
|
||||||
mq->modals[mq->len] = (void *) lParam;
|
// nope, we can run now
|
||||||
mq->len++;
|
doissue((void *) lParam);
|
||||||
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);
|
|
||||||
return 0;
|
return 0;
|
||||||
case msgBeginModal:
|
case msgBeginModal:
|
||||||
mq->inmodal = TRUE;
|
beginModal();
|
||||||
EnumThreadWindows(GetCurrentThreadId(), beginEndModalAll, msgBeginModal);
|
EnumThreadWindows(GetCurrentThreadId(), beginEndModalAll, msgBeginModal);
|
||||||
return 0;
|
return 0;
|
||||||
case msgEndModal:
|
case msgEndModal:
|
||||||
mq->inmodal = FALSE;
|
endModal();
|
||||||
for (i = 0; i < mq->len; i++)
|
|
||||||
doissue(mq->modals[i]);
|
|
||||||
mq->len = 0;
|
|
||||||
EnumThreadWindows(GetCurrentThreadId(), beginEndModalAll, msgEndModal);
|
EnumThreadWindows(GetCurrentThreadId(), beginEndModalAll, msgEndModal);
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue