aboutsummaryrefslogtreecommitdiffstats
path: root/src/win.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/win.c')
-rw-r--r--src/win.c186
1 files changed, 72 insertions, 114 deletions
diff --git a/src/win.c b/src/win.c
index 1efc9a2..c98d51b 100644
--- a/src/win.c
+++ b/src/win.c
@@ -4,6 +4,7 @@
#include "win.h"
#include "internal.h"
+#include "macros.h"
#include "platform.h"
#include "pugl/pugl.h"
@@ -269,20 +270,6 @@ puglInitViewInternals(PuglWorld* PUGL_UNUSED(world))
return (PuglInternals*)calloc(1, sizeof(PuglInternals));
}
-static PuglStatus
-puglPollWinEvents(PuglWorld* world, const double timeout)
-{
- (void)world;
-
- if (timeout < 0) {
- WaitMessage();
- } else {
- MsgWaitForMultipleObjects(
- 0, NULL, FALSE, (DWORD)(timeout * 1e3), QS_ALLEVENTS);
- }
- return PUGL_SUCCESS;
-}
-
PuglStatus
puglRealize(PuglView* view)
{
@@ -362,24 +349,22 @@ puglUnrealize(PuglView* const view)
view->backend->destroy(view);
}
+ memset(&view->lastConfigure, 0, sizeof(PuglConfigureEvent));
ReleaseDC(view->impl->hwnd, view->impl->hdc);
view->impl->hdc = NULL;
- DestroyWindow(view->impl->hwnd);
- view->impl->hwnd = NULL;
-
- memset(&view->lastConfigure, 0, sizeof(PuglConfigureEvent));
- return PUGL_SUCCESS;
+ const PuglStatus st = puglWinStatus(DestroyWindow(view->impl->hwnd));
+ view->impl->hwnd = NULL;
+ return st;
}
PuglStatus
puglShow(PuglView* view, const PuglShowCommand command)
{
PuglInternals* impl = view->impl;
-
+ PuglStatus st = PUGL_SUCCESS;
if (!impl->hwnd) {
- const PuglStatus st = puglRealize(view);
- if (st) {
+ if ((st = puglRealize(view))) {
return st;
}
}
@@ -394,19 +379,17 @@ puglShow(PuglView* view, const PuglShowCommand command)
break;
case PUGL_SHOW_FORCE_RAISE:
ShowWindow(impl->hwnd, SW_SHOWNORMAL);
- SetForegroundWindow(impl->hwnd);
+ st = puglWinStatus(!!SetForegroundWindow(impl->hwnd));
break;
}
- return PUGL_SUCCESS;
+ return st;
}
PuglStatus
puglHide(PuglView* view)
{
- PuglInternals* impl = view->impl;
-
- ShowWindow(impl->hwnd, SW_HIDE);
+ ShowWindow(view->impl->hwnd, SW_HIDE);
return PUGL_SUCCESS;
}
@@ -967,8 +950,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
PuglStatus
puglGrabFocus(PuglView* view)
{
- SetFocus(view->impl->hwnd);
- return PUGL_SUCCESS;
+ return puglWinStatus(!!SetFocus(view->impl->hwnd));
}
bool
@@ -1042,7 +1024,7 @@ puglSetViewStyle(PuglView* const view, const PuglViewStyleFlags flags)
const bool newMaximized = styleIsMaximized(flags);
if (oldMaximized != newMaximized) {
ShowWindow(impl->hwnd, newMaximized ? SW_SHOWMAXIMIZED : SW_RESTORE);
- puglPostRedisplay(view);
+ puglObscureView(view);
}
return PUGL_SUCCESS;
@@ -1053,9 +1035,8 @@ puglStartTimer(PuglView* view, uintptr_t id, double timeout)
{
const UINT msec = (UINT)floor(timeout * 1000.0);
- return (SetTimer(view->impl->hwnd, PUGL_USER_TIMER_MIN + id, msec, NULL)
- ? PUGL_SUCCESS
- : PUGL_UNKNOWN_ERROR);
+ SetTimer(view->impl->hwnd, PUGL_USER_TIMER_MIN + id, msec, NULL);
+ return PUGL_SUCCESS;
}
PuglStatus
@@ -1068,17 +1049,14 @@ PuglStatus
puglSendEvent(PuglView* view, const PuglEvent* event)
{
if (event->type == PUGL_CLOSE) {
- PostMessage(view->impl->hwnd, WM_CLOSE, 0, 0);
- return PUGL_SUCCESS;
+ return puglWinStatus(PostMessage(view->impl->hwnd, WM_CLOSE, 0, 0));
}
if (event->type == PUGL_CLIENT) {
- PostMessage(view->impl->hwnd,
- PUGL_LOCAL_CLIENT_MSG,
- (WPARAM)event->client.data1,
- (LPARAM)event->client.data2);
-
- return PUGL_SUCCESS;
+ return puglWinStatus(PostMessage(view->impl->hwnd,
+ PUGL_LOCAL_CLIENT_MSG,
+ (WPARAM)event->client.data1,
+ (LPARAM)event->client.data2));
}
return PUGL_UNSUPPORTED;
@@ -1143,17 +1121,18 @@ puglUpdate(PuglWorld* world, double timeout)
PuglStatus st = PUGL_SUCCESS;
if (timeout < 0.0) {
- st = puglPollWinEvents(world, timeout);
- st = st ? st : puglDispatchWinEvents(world);
+ WaitMessage();
+ st = puglDispatchWinEvents(world);
} else if (timeout < minWaitSeconds) {
st = puglDispatchWinEvents(world);
} else {
const double endTime = startTime + timeout - minWaitSeconds;
- for (double t = startTime; t < endTime; t = puglGetTime(world)) {
- if ((st = puglPollWinEvents(world, endTime - t)) ||
- (st = puglDispatchWinEvents(world))) {
- break;
- }
+ double t = startTime;
+ while (!st && t < endTime) {
+ const DWORD timeoutMs = (DWORD)((endTime - t) * 1e3);
+ MsgWaitForMultipleObjects(0, NULL, FALSE, timeoutMs, QS_ALLEVENTS);
+ st = puglDispatchWinEvents(world);
+ t = puglGetTime(world);
}
}
@@ -1209,23 +1188,29 @@ puglGetTime(const PuglWorld* world)
}
PuglStatus
-puglPostRedisplay(PuglView* view)
+puglObscureView(PuglView* view)
{
- InvalidateRect(view->impl->hwnd, NULL, false);
- return PUGL_SUCCESS;
+ return puglWinStatus(InvalidateRect(view->impl->hwnd, NULL, false));
}
PuglStatus
-puglPostRedisplayRect(PuglView* view, const PuglRect rect)
+puglObscureRegion(PuglView* const view,
+ const int x,
+ const int y,
+ const unsigned width,
+ const unsigned height)
{
- const RECT r = {(long)floor(rect.x),
- (long)floor(rect.y),
- (long)ceil(rect.x + rect.width),
- (long)ceil(rect.y + rect.height)};
+ if (!puglIsValidPosition(x, y) || !puglIsValidSize(width, height)) {
+ return PUGL_BAD_PARAMETER;
+ }
- InvalidateRect(view->impl->hwnd, &r, false);
+ const int cx = MAX(0, x);
+ const int cy = MAX(0, y);
+ const unsigned cw = MIN(view->lastConfigure.width, width);
+ const unsigned ch = MIN(view->lastConfigure.height, height);
- return PUGL_SUCCESS;
+ const RECT r = {cx, cy, cx + (long)cw, cy + (long)ch};
+ return puglWinStatus(InvalidateRect(view->impl->hwnd, &r, false));
}
PuglNativeView
@@ -1239,17 +1224,18 @@ puglViewStringChanged(PuglView* const view,
const PuglStringHint key,
const char* const value)
{
+ PuglStatus st = PUGL_SUCCESS;
if (!view->impl->hwnd) {
- return PUGL_SUCCESS;
+ return st;
}
if (key == PUGL_WINDOW_TITLE) {
ArgStringChar* const titleArg = puglArgStringNew(value);
- SetWindowText(view->impl->hwnd, titleArg);
+ st = puglWinStatus(SetWindowText(view->impl->hwnd, titleArg));
puglArgStringFree(titleArg);
}
- return PUGL_SUCCESS;
+ return st;
}
static RECT
@@ -1414,8 +1400,7 @@ puglAcceptOffer(PuglView* const view,
PuglEvent dataEvent;
dataEvent.data = data;
- puglDispatchEvent(view, &dataEvent);
- return PUGL_SUCCESS;
+ return puglDispatchEvent(view, &dataEvent);
}
const void*
@@ -1507,8 +1492,7 @@ puglPaste(PuglView* const view)
PuglEvent offerEvent;
offerEvent.offer = offer;
- puglDispatchEvent(view, &offerEvent);
- return PUGL_SUCCESS;
+ return puglDispatchEvent(view, &offerEvent);
}
static const TCHAR* const cursor_ids[] = {
@@ -1576,42 +1560,18 @@ puglWinGetPixelFormatDescriptor(const PuglHints hints)
return pfd;
}
-static PuglRect
-getInitialFrame(PuglView* const view)
+PuglPoint
+puglGetAncestorCenter(const PuglView* const view)
{
- if (view->lastConfigure.type == PUGL_CONFIGURE) {
- // Use the last configured frame
- const PuglRect frame = {view->lastConfigure.x,
- view->lastConfigure.y,
- view->lastConfigure.width,
- view->lastConfigure.height};
- return frame;
- }
-
- const PuglSpan defaultWidth = view->sizeHints[PUGL_DEFAULT_SIZE].width;
- const PuglSpan defaultHeight = view->sizeHints[PUGL_DEFAULT_SIZE].height;
- const int x = view->defaultX;
- const int y = view->defaultY;
- if (puglIsValidPosition(x, y)) {
- // Use the default position set with puglSetPosition while unrealized
- const PuglRect frame = {
- (PuglCoord)x, (PuglCoord)y, defaultWidth, defaultHeight};
- return frame;
- }
+ RECT rect = {0, 0, 0, 0};
+ GetWindowRect(view->transientParent ? (HWND)view->transientParent
+ : GetDesktopWindow(),
+ &rect);
- // Get a bounding rect from the "nearest" parent or parent-like window
- const HWND hwnd = puglWinGetWindow(view);
- RECT rect = {0, 0, 0, 0};
- GetWindowRect(hwnd ? hwnd : GetDesktopWindow(), &rect);
-
- // Center the frame around the center of the bounding rectangle
- const LONG centerX = rect.left + (rect.right - rect.left) / 2;
- const LONG centerY = rect.top + (rect.bottom - rect.top) / 2;
- const PuglRect frame = {(PuglCoord)(centerX - (defaultWidth / 2)),
- (PuglCoord)(centerY - (defaultHeight / 2)),
- defaultWidth,
- defaultHeight};
- return frame;
+ const PuglPoint center = {
+ (PuglCoord)(rect.left + (rect.right - rect.left) / 2),
+ (PuglCoord)(rect.top + (rect.bottom - rect.top) / 2)};
+ return center;
}
PuglStatus
@@ -1626,13 +1586,14 @@ puglWinCreateWindow(PuglView* const view,
PuglNativeView parent = view->parent ? view->parent : view->transientParent;
// Calculate initial window rectangle
- const unsigned winFlags = puglWinGetWindowFlags(view);
- const unsigned winExFlags = puglWinGetWindowExFlags(view);
- const PuglRect frame = getInitialFrame(view);
- RECT wr = {(long)frame.x,
- (long)frame.y,
- (long)frame.x + frame.width,
- (long)frame.y + frame.height};
+ const unsigned winFlags = puglWinGetWindowFlags(view);
+ const unsigned winExFlags = puglWinGetWindowExFlags(view);
+ const PuglArea size = puglGetInitialSize(view);
+ const PuglPoint pos = puglGetInitialPosition(view, size);
+ RECT wr = {(long)pos.x,
+ (long)pos.y,
+ (long)pos.x + size.width,
+ (long)pos.y + size.height};
AdjustWindowRectEx(&wr, winFlags, FALSE, winExFlags);
ArgStringChar* const classNameArg = puglArgStringNew(className);
@@ -1679,7 +1640,6 @@ puglWinConfigure(PuglView* view)
{
PuglInternals* const impl = view->impl;
PuglStatus st = PUGL_SUCCESS;
-
if ((st = puglWinCreateWindow(view, "Pugl", &impl->hwnd, &impl->hdc))) {
return st;
}
@@ -1692,20 +1652,18 @@ puglWinConfigure(PuglView* view)
DestroyWindow(impl->hwnd);
impl->hwnd = NULL;
impl->hdc = NULL;
- return PUGL_SET_FORMAT_FAILED;
+ st = PUGL_SET_FORMAT_FAILED;
}
- return PUGL_SUCCESS;
+ return st;
}
PuglStatus
puglWinEnter(PuglView* view, const PuglExposeEvent* expose)
{
- if (expose) {
- BeginPaint(view->impl->hwnd, &view->impl->paint);
- }
-
- return PUGL_SUCCESS;
+ return expose
+ ? puglWinStatus(!!BeginPaint(view->impl->hwnd, &view->impl->paint))
+ : PUGL_SUCCESS;
}
PuglStatus