Fixed message queue overload in Windows modality code.
This commit is contained in:
parent
b6a5735f89
commit
751180ba20
|
@ -71,6 +71,13 @@ 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)
|
||||||
|
@ -81,6 +88,23 @@ 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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
@ -93,20 +117,27 @@ static LRESULT CALLBACK msgwinproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
|
||||||
case msgRequest:
|
case msgRequest:
|
||||||
// in modal?
|
// in modal?
|
||||||
if (GetWindowLongPtrW(hwnd, GWLP_USERDATA) != 0) {
|
if (GetWindowLongPtrW(hwnd, GWLP_USERDATA) != 0) {
|
||||||
// post again later
|
mq->modals[mq->len] = (void *) lParam;
|
||||||
// TODO this chokes the message queue!
|
mq->len++;
|
||||||
issue((void *) lParam);
|
if (mq->len >= mq->cap) {
|
||||||
return 0;
|
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
|
// nope, we can run now
|
||||||
doissue((void *) lParam);
|
doissue((void *) lParam);
|
||||||
return 0;
|
return 0;
|
||||||
case msgBeginModal:
|
case msgBeginModal:
|
||||||
SetWindowLongPtrW(hwnd, GWLP_USERDATA, 1);
|
mq->inmodal = TRUE;
|
||||||
EnumThreadWindows(GetCurrentThreadId(), beginEndModalAll, msgBeginModal);
|
EnumThreadWindows(GetCurrentThreadId(), beginEndModalAll, msgBeginModal);
|
||||||
return 0;
|
return 0;
|
||||||
case msgEndModal:
|
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);
|
EnumThreadWindows(GetCurrentThreadId(), beginEndModalAll, msgEndModal);
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue