aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.clang-tidy1
-rw-r--r--src/common.c114
-rw-r--r--src/internal.c84
-rw-r--r--src/internal.h37
-rw-r--r--src/mac.h2
-rw-r--r--src/mac.m316
-rw-r--r--src/mac_cairo.m2
-rw-r--r--src/mac_gl.m2
-rw-r--r--src/mac_stub.m2
-rw-r--r--src/mac_vulkan.m6
-rw-r--r--src/platform.h8
-rw-r--r--src/stub.h2
-rw-r--r--src/types.h33
-rw-r--r--src/win.c499
-rw-r--r--src/win.h21
-rw-r--r--src/win_cairo.c2
-rw-r--r--src/win_gl.c62
-rw-r--r--src/win_stub.c2
-rw-r--r--src/win_vulkan.c2
-rw-r--r--src/x11.c306
-rw-r--r--src/x11.h8
-rw-r--r--src/x11_cairo.c18
-rw-r--r--src/x11_gl.c10
-rw-r--r--src/x11_stub.c4
-rw-r--r--src/x11_vulkan.c4
25 files changed, 734 insertions, 813 deletions
diff --git a/src/.clang-tidy b/src/.clang-tidy
index 6d51f06..cfc824d 100644
--- a/src/.clang-tidy
+++ b/src/.clang-tidy
@@ -4,7 +4,6 @@
Checks: >
-bugprone-easily-swappable-parameters,
-bugprone-multi-level-implicit-pointer-conversion,
- -clang-analyzer-optin.core.EnumCastOutOfRange,
-hicpp-multiway-paths-covered,
-hicpp-signed-bitwise,
-llvm-header-guard,
diff --git a/src/common.c b/src/common.c
index 46b2f3d..c8ac3d4 100644
--- a/src/common.c
+++ b/src/common.c
@@ -4,13 +4,11 @@
// Common implementations of public API functions in the core library
#include "internal.h"
-
#include "platform.h"
#include "types.h"
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
-#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -106,27 +104,37 @@ puglGetWorldString(const PuglWorld* const world, const PuglStringHint key)
}
static void
-puglSetDefaultHints(PuglHints hints)
+puglSetDefaultHints(PuglView* const view)
{
- hints[PUGL_CONTEXT_API] = PUGL_OPENGL_API;
- hints[PUGL_CONTEXT_VERSION_MAJOR] = 2;
- hints[PUGL_CONTEXT_VERSION_MINOR] = 0;
- hints[PUGL_CONTEXT_PROFILE] = PUGL_OPENGL_CORE_PROFILE;
- hints[PUGL_CONTEXT_DEBUG] = PUGL_FALSE;
- hints[PUGL_RED_BITS] = 8;
- hints[PUGL_GREEN_BITS] = 8;
- hints[PUGL_BLUE_BITS] = 8;
- hints[PUGL_ALPHA_BITS] = 8;
- hints[PUGL_DEPTH_BITS] = 0;
- hints[PUGL_STENCIL_BITS] = 0;
- hints[PUGL_SAMPLE_BUFFERS] = PUGL_DONT_CARE;
- hints[PUGL_SAMPLES] = 0;
- hints[PUGL_DOUBLE_BUFFER] = PUGL_TRUE;
- hints[PUGL_SWAP_INTERVAL] = PUGL_DONT_CARE;
- hints[PUGL_RESIZABLE] = PUGL_FALSE;
- hints[PUGL_IGNORE_KEY_REPEAT] = PUGL_FALSE;
- hints[PUGL_REFRESH_RATE] = PUGL_DONT_CARE;
- hints[PUGL_VIEW_TYPE] = PUGL_DONT_CARE;
+ view->hints[PUGL_CONTEXT_API] = PUGL_OPENGL_API;
+ view->hints[PUGL_CONTEXT_VERSION_MAJOR] = 2;
+ view->hints[PUGL_CONTEXT_VERSION_MINOR] = 0;
+ view->hints[PUGL_CONTEXT_PROFILE] = PUGL_OPENGL_CORE_PROFILE;
+ view->hints[PUGL_CONTEXT_DEBUG] = PUGL_FALSE;
+ view->hints[PUGL_RED_BITS] = 8;
+ view->hints[PUGL_GREEN_BITS] = 8;
+ view->hints[PUGL_BLUE_BITS] = 8;
+ view->hints[PUGL_ALPHA_BITS] = 8;
+ view->hints[PUGL_DEPTH_BITS] = 0;
+ view->hints[PUGL_STENCIL_BITS] = 0;
+ view->hints[PUGL_SAMPLE_BUFFERS] = PUGL_DONT_CARE;
+ view->hints[PUGL_SAMPLES] = 0;
+ view->hints[PUGL_DOUBLE_BUFFER] = PUGL_TRUE;
+ view->hints[PUGL_SWAP_INTERVAL] = PUGL_DONT_CARE;
+ view->hints[PUGL_RESIZABLE] = PUGL_FALSE;
+ view->hints[PUGL_IGNORE_KEY_REPEAT] = PUGL_FALSE;
+ view->hints[PUGL_REFRESH_RATE] = PUGL_DONT_CARE;
+ view->hints[PUGL_VIEW_TYPE] = PUGL_DONT_CARE;
+
+ for (unsigned i = 0U; i < PUGL_NUM_POSITION_HINTS; ++i) {
+ view->positionHints[i].x = INT16_MIN;
+ view->positionHints[i].y = INT16_MIN;
+ }
+
+ for (unsigned i = 0U; i < PUGL_NUM_SIZE_HINTS; ++i) {
+ view->sizeHints[i].width = 0U;
+ view->sizeHints[i].height = 0U;
+ }
}
PuglView*
@@ -138,13 +146,8 @@ puglNewView(PuglWorld* const world)
return NULL;
}
- view->world = world;
- view->sizeHints[PUGL_MIN_SIZE].width = 1;
- view->sizeHints[PUGL_MIN_SIZE].height = 1;
- view->defaultX = INT_MIN;
- view->defaultY = INT_MIN;
-
- puglSetDefaultHints(view->hints);
+ view->world = world;
+ puglSetDefaultHints(view);
// Enlarge world view list
const size_t newNumViews = world->numViews + 1U;
@@ -287,43 +290,48 @@ puglGetViewString(const PuglView* const view, const PuglStringHint key)
return view->strings[key];
}
-PuglRect
-puglGetFrame(const PuglView* view)
+PuglPoint
+puglGetPositionHint(const PuglView* const view, const PuglPositionHint hint)
{
- if (view->lastConfigure.type == PUGL_CONFIGURE) {
- // Return the last configured frame
- const PuglRect frame = {view->lastConfigure.x,
- view->lastConfigure.y,
- view->lastConfigure.width,
- view->lastConfigure.height};
- return frame;
+ if (hint == PUGL_CURRENT_POSITION) {
+ PuglPoint pos = {0, 0};
+ if (view->lastConfigure.type == PUGL_CONFIGURE) {
+ pos.x = view->lastConfigure.x;
+ pos.y = view->lastConfigure.y;
+ } else {
+ const PuglPoint defaultPos = view->positionHints[PUGL_DEFAULT_POSITION];
+ if (puglIsValidPosition(defaultPos.x, defaultPos.y)) {
+ pos.x = defaultPos.x;
+ pos.y = defaultPos.y;
+ }
+ }
+ return pos;
}
- // Get the default position if set, or fallback to (0, 0)
- int x = view->defaultX;
- int y = view->defaultY;
- if (x < INT16_MIN || x > INT16_MAX || y < INT16_MIN || y > INT16_MAX) {
- x = 0;
- y = 0;
+ return view->positionHints[hint];
+}
+
+PuglArea
+puglGetSizeHint(const PuglView* const view, const PuglSizeHint hint)
+{
+ if (hint == PUGL_CURRENT_SIZE && view->lastConfigure.type == PUGL_CONFIGURE) {
+ const PuglArea area = {view->lastConfigure.width,
+ view->lastConfigure.height};
+ return area;
}
- // Return the default frame, sanitized if necessary
- const PuglRect frame = {(PuglCoord)x,
- (PuglCoord)y,
- view->sizeHints[PUGL_DEFAULT_SIZE].width,
- view->sizeHints[PUGL_DEFAULT_SIZE].height};
- return frame;
+ return view->sizeHints[hint];
}
PuglStatus
-puglSetParentWindow(PuglView* view, PuglNativeView parent)
+puglSetParent(PuglView* view, PuglNativeView parent)
{
view->parent = parent;
return PUGL_SUCCESS;
}
PuglNativeView
-puglGetParentWindow(const PuglView* const view)
+puglGetParent(const PuglView* const view)
{
return view->parent;
}
diff --git a/src/internal.c b/src/internal.c
index 3c4d304..ca84ed1 100644
--- a/src/internal.c
+++ b/src/internal.c
@@ -5,19 +5,80 @@
#include "types.h"
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#include <assert.h>
#include <stdbool.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+static PuglPoint
+make_point(const PuglCoord x, const PuglCoord y)
+{
+ const PuglPoint point = {x, y};
+ return point;
+}
+
+bool
+puglIsValidPosition(const int x, const int y)
+{
+ // INT16_MIN is a sentinel, INT16_MAX is impossible with non-zero size
+ return x > INT16_MIN && x < INT16_MAX && y > INT16_MIN && y < INT16_MAX;
+}
+
+bool
+puglIsValidSize(const unsigned width, const unsigned height)
+{
+ return width && height && width <= INT16_MAX && height <= INT16_MAX;
+}
+
bool
-puglIsValidSize(const PuglViewSize size)
+puglIsValidArea(const PuglArea size)
{
return size.width && size.height;
}
+PuglArea
+puglGetInitialSize(const PuglView* const view)
+{
+ if (view->lastConfigure.type == PUGL_CONFIGURE) {
+ // Use the last configured size
+ const PuglConfigureEvent config = view->lastConfigure;
+ const PuglArea size = {config.width, config.height};
+ return size;
+ }
+
+ // Use the default size hint set by the application
+ return view->sizeHints[PUGL_DEFAULT_SIZE];
+}
+
+PuglPoint
+puglGetInitialPosition(const PuglView* const view, const PuglArea size)
+{
+ if (view->lastConfigure.type == PUGL_CONFIGURE) {
+ // Use the last configured frame
+ return make_point(view->lastConfigure.x, view->lastConfigure.y);
+ }
+
+ const PuglPoint defaultPos = view->positionHints[PUGL_DEFAULT_POSITION];
+ if (puglIsValidPosition(defaultPos.x, defaultPos.y)) {
+ // Use the default position hint set by the application
+ return make_point(defaultPos.x, defaultPos.y);
+ }
+
+ if (view->parent) {
+ // Default to the top/left origin of the parent
+ return make_point(0, 0);
+ }
+
+ // Center frame on a transient ancestor, or failing that, the screen
+ const PuglPoint center = puglGetAncestorCenter(view);
+ const PuglPoint pos = {(PuglCoord)(center.x - (size.width / 2)),
+ (PuglCoord)(center.y - (size.height / 2))};
+ return pos;
+}
+
void
puglEnsureHint(PuglView* const view, const PuglViewHint hint, const int value)
{
@@ -68,6 +129,21 @@ puglSetString(char** dest, const char* string)
}
}
+PuglStatus
+puglStoreSizeHint(PuglView* const view,
+ const PuglSizeHint hint,
+ const unsigned width,
+ const unsigned height)
+{
+ if (!puglIsValidSize(width, height)) {
+ return PUGL_BAD_PARAMETER;
+ }
+
+ view->sizeHints[hint].width = (PuglSpan)width;
+ view->sizeHints[hint].height = (PuglSpan)height;
+ return PUGL_SUCCESS;
+}
+
uint32_t
puglDecodeUTF8(const uint8_t* buf)
{
@@ -159,7 +235,7 @@ puglPreRealize(PuglView* const view)
}
// Ensure that the default size is set to a valid size
- if (!puglIsValidSize(view->sizeHints[PUGL_DEFAULT_SIZE])) {
+ if (!puglIsValidArea(view->sizeHints[PUGL_DEFAULT_SIZE])) {
return PUGL_BAD_CONFIGURATION;
}
@@ -173,7 +249,7 @@ puglDispatchSimpleEvent(PuglView* view, const PuglEventType type)
type == PUGL_UPDATE || type == PUGL_CLOSE || type == PUGL_LOOP_ENTER ||
type == PUGL_LOOP_LEAVE);
- const PuglEvent event = {{type, 0}};
+ const PuglEvent event = {{type, 0U}};
return puglDispatchEvent(view, &event);
}
diff --git a/src/internal.h b/src/internal.h
index 3721c10..8678982 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -9,8 +9,8 @@
#include "attributes.h"
#include "types.h"
-#include "pugl/attributes.h"
-#include "pugl/pugl.h"
+#include <pugl/attributes.h>
+#include <pugl/pugl.h>
#include <stdbool.h>
#include <stddef.h>
@@ -18,9 +18,29 @@
PUGL_BEGIN_DECLS
+/// Return true if `x`,`y` is a valid position
+bool
+puglIsValidPosition(int x, int y);
+
+/// Return true if `width`,`height` is a valid position
+bool
+puglIsValidSize(unsigned x, unsigned y);
+
/// Return true if `size` is a valid view size
bool
-puglIsValidSize(PuglViewSize size);
+puglIsValidArea(PuglArea size);
+
+/// Return the center point of some "soft" ancestor (parent window or screen)
+PuglPoint
+puglGetAncestorCenter(const PuglView* view);
+
+/// Return the initial size of a view
+PuglArea
+puglGetInitialSize(const PuglView* view);
+
+/// Return the initial position of a view if known, or an invalid position
+PuglPoint
+puglGetInitialPosition(const PuglView* view, PuglArea size);
/// Set hint to a default value if it is unset (PUGL_DONT_CARE)
void
@@ -34,8 +54,14 @@ puglSetBlob(PuglBlob* dest, const void* data, size_t len);
void
puglSetString(char** dest, const char* string);
+/// Store `width` and `height` as the current value of a size `hint`
+PuglStatus
+puglStoreSizeHint(PuglView* view,
+ PuglSizeHint hint,
+ unsigned width,
+ unsigned height);
+
/// Handle a changed string property
-PUGL_API
PuglStatus
puglViewStringChanged(PuglView* view, PuglStringHint key, const char* value);
@@ -56,8 +82,7 @@ PuglStatus
puglDispatchSimpleEvent(PuglView* view, PuglEventType type);
/// Process configure event while already in the graphics context
-PUGL_WARN_UNUSED_RESULT
-PuglStatus
+PUGL_WARN_UNUSED_RESULT PuglStatus
puglConfigure(PuglView* view, const PuglEvent* event);
/// Dispatch `event` to `view`, entering graphics context if necessary
diff --git a/src/mac.h b/src/mac.h
index 119e7c8..305cf30 100644
--- a/src/mac.h
+++ b/src/mac.h
@@ -5,7 +5,7 @@
#ifndef PUGL_SRC_MAC_H
#define PUGL_SRC_MAC_H
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#import <Cocoa/Cocoa.h>
diff --git a/src/mac.m b/src/mac.m
index 727f142..41d358a 100644
--- a/src/mac.m
+++ b/src/mac.m
@@ -7,9 +7,10 @@
#include "mac.h"
#include "internal.h"
+#include "macros.h"
#include "platform.h"
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#import <Cocoa/Cocoa.h>
@@ -121,7 +122,7 @@ viewScreen(const PuglView* view)
}
static NSRect
-nsRectToPoints(PuglView* view, const NSRect rect)
+nsRectToPoints(const PuglView* view, const NSRect rect)
{
const double scaleFactor = [viewScreen(view) backingScaleFactor];
@@ -132,7 +133,7 @@ nsRectToPoints(PuglView* view, const NSRect rect)
}
static NSRect
-nsRectFromPoints(PuglView* view, const NSRect rect)
+nsRectFromPoints(const PuglView* view, const NSRect rect)
{
const double scaleFactor = [viewScreen(view) backingScaleFactor];
@@ -143,21 +144,15 @@ nsRectFromPoints(PuglView* view, const NSRect rect)
}
static NSPoint
-nsPointFromPoints(PuglView* view, const NSPoint point)
+nsPointFromPoints(const PuglView* view, const NSPoint point)
{
const double scaleFactor = [viewScreen(view) backingScaleFactor];
return NSMakePoint(point.x * scaleFactor, point.y * scaleFactor);
}
-static NSRect
-rectToNsRect(const PuglRect rect)
-{
- return NSMakeRect(rect.x, rect.y, rect.width, rect.height);
-}
-
static NSSize
-sizePoints(PuglView* view, const double width, const double height)
+sizePoints(PuglView* view, const PuglSpan width, const PuglSpan height)
{
const double scaleFactor = [viewScreen(view) backingScaleFactor];
@@ -199,7 +194,7 @@ dispatchCurrentChildViewConfiguration(PuglView* const view)
const PuglConfigureEvent ev = {
PUGL_CONFIGURE,
- 0,
+ 0U,
(PuglCoord)framePx.origin.x,
(PuglCoord)framePx.origin.y,
(PuglSpan)framePx.size.width,
@@ -249,7 +244,7 @@ dispatchCurrentChildViewConfiguration(PuglView* const view)
const PuglConfigureEvent ev = {
PUGL_CONFIGURE,
- 0,
+ 0U,
(PuglCoord)contentPx.origin.x,
(PuglCoord)(screenHeight - contentPx.origin.y - contentPx.size.height),
(PuglSpan)contentPx.size.width,
@@ -331,7 +326,7 @@ dispatchCurrentChildViewConfiguration(PuglView* const view)
const PuglExposeEvent ev = {
PUGL_EXPOSE,
- 0,
+ 0U,
(PuglCoord)(rect.origin.x * scaleFactor),
(PuglCoord)viewY,
(PuglSpan)(rect.size.width * scaleFactor),
@@ -345,9 +340,9 @@ dispatchCurrentChildViewConfiguration(PuglView* const view)
- (NSSize)intrinsicContentSize
{
- const PuglViewSize defaultSize = puglview->sizeHints[PUGL_DEFAULT_SIZE];
+ const PuglArea defaultSize = puglview->sizeHints[PUGL_DEFAULT_SIZE];
- return puglIsValidSize(defaultSize)
+ return puglIsValidArea(defaultSize)
? sizePoints(puglview, defaultSize.width, defaultSize.height)
: NSMakeSize(NSViewNoInstrinsicMetric, NSViewNoInstrinsicMetric);
}
@@ -463,7 +458,7 @@ keySymToSpecial(const NSEvent* const ev)
return PUGL_KEY_PAD_9;
}
- return (PuglKey)0;
+ return PUGL_KEY_NONE;
}
- (void)updateTrackingAreas
@@ -496,7 +491,7 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
const NSPoint rloc = [NSEvent mouseLocation];
const PuglCrossingEvent ev = {
type,
- 0,
+ 0U,
[event timestamp],
wloc.x,
wloc.y,
@@ -537,7 +532,7 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
const NSPoint rloc = [NSEvent mouseLocation];
const PuglMotionEvent ev = {
PUGL_MOTION,
- 0,
+ 0U,
[event timestamp],
wloc.x,
wloc.y,
@@ -572,7 +567,7 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
const NSPoint rloc = [NSEvent mouseLocation];
const PuglButtonEvent ev = {
PUGL_BUTTON_PRESS,
- 0,
+ 0U,
[event timestamp],
wloc.x,
wloc.y,
@@ -593,7 +588,7 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
const NSPoint rloc = [NSEvent mouseLocation];
const PuglButtonEvent ev = {
PUGL_BUTTON_RELEASE,
- 0,
+ 0U,
[event timestamp],
wloc.x,
wloc.y,
@@ -635,9 +630,9 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
double dx = -[event scrollingDeltaX];
double dy = [event scrollingDeltaY];
- if (![event hasPreciseScrollingDeltas]) {
- dx *= 10.0;
- dy *= 10.0;
+ if ([event hasPreciseScrollingDeltas]) {
+ dx /= 20.0;
+ dy /= 20.0;
}
const PuglScrollDirection dir =
@@ -652,7 +647,7 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
const PuglScrollEvent ev = {
PUGL_SCROLL,
- 0,
+ 0U,
[event timestamp],
wloc.x,
wloc.y,
@@ -684,7 +679,7 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
const PuglKeyEvent ev = {
PUGL_KEY_PRESS,
- 0,
+ 0U,
[event timestamp],
wloc.x,
wloc.y,
@@ -715,7 +710,7 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
const PuglKeyEvent ev = {
PUGL_KEY_RELEASE,
- 0,
+ 0U,
[event timestamp],
wloc.x,
wloc.y,
@@ -827,7 +822,7 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
PuglTextEvent ev = {
PUGL_TEXT,
- 0,
+ 0U,
[event timestamp],
wloc.x,
wloc.y,
@@ -856,7 +851,7 @@ flagDiffers(const uint32_t lhs, const uint32_t rhs, const uint32_t mask)
- (void)flagsChanged:(NSEvent*)event
{
const uint32_t mods = getModifiers(event);
- PuglKey special = (PuglKey)0;
+ PuglKey special = PUGL_KEY_NONE;
const uint16_t keyCode = [event keyCode];
if (flagDiffers(mods, puglview->impl->mods, PUGL_MOD_SHIFT)) {
@@ -877,7 +872,7 @@ flagDiffers(const uint32_t lhs, const uint32_t rhs, const uint32_t mask)
const bool release = [event type] == NSEventTypeKeyUp;
const PuglKeyEvent ev = {release ? PUGL_KEY_RELEASE : PUGL_KEY_PRESS,
- 0,
+ 0U,
[event timestamp],
wloc.x,
wloc.y,
@@ -919,7 +914,7 @@ flagDiffers(const uint32_t lhs, const uint32_t rhs, const uint32_t mask)
- (void)timerTick:(NSTimer*)userTimer
{
const NSNumber* userInfo = userTimer.userInfo;
- const PuglTimerEvent ev = {PUGL_TIMER, 0, userInfo.unsignedLongValue};
+ const PuglTimerEvent ev = {PUGL_TIMER, 0U, userInfo.unsignedLongValue};
PuglEvent timerEvent;
timerEvent.timer = ev;
@@ -984,7 +979,7 @@ flagDiffers(const uint32_t lhs, const uint32_t rhs, const uint32_t mask)
{
(void)notification;
- PuglEvent ev = {{PUGL_FOCUS_IN, 0}};
+ PuglEvent ev = {{PUGL_FOCUS_IN, 0U}};
ev.focus.mode = PUGL_CROSSING_NORMAL;
puglDispatchEvent(window->puglview, &ev);
}
@@ -993,7 +988,7 @@ flagDiffers(const uint32_t lhs, const uint32_t rhs, const uint32_t mask)
{
(void)notification;
- PuglEvent ev = {{PUGL_FOCUS_OUT, 0}};
+ PuglEvent ev = {{PUGL_FOCUS_OUT, 0U}};
ev.focus.mode = PUGL_CROSSING_NORMAL;
puglDispatchEvent(window->puglview, &ev);
}
@@ -1117,12 +1112,13 @@ updateSizeHint(PuglView* const view, const PuglSizeHint hint)
{
const PuglSpan width = view->sizeHints[hint].width;
const PuglSpan height = view->sizeHints[hint].height;
- if (!puglIsValidSize(view->sizeHints[hint])) {
+ if (!puglIsValidArea(view->sizeHints[hint])) {
return PUGL_FAILURE;
}
switch (hint) {
case PUGL_DEFAULT_SIZE:
+ case PUGL_CURRENT_SIZE:
break;
case PUGL_MIN_SIZE:
@@ -1153,30 +1149,9 @@ updateSizeHints(PuglView* const view)
}
}
-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 int x = view->defaultX;
- const int y = view->defaultY;
- if (x >= INT16_MIN && x <= INT16_MAX && y >= INT16_MIN && y <= INT16_MAX) {
- // Use the default position set with puglSetPosition while unrealized
- const PuglRect frame = {(PuglCoord)x,
- (PuglCoord)y,
- view->sizeHints[PUGL_DEFAULT_SIZE].width,
- view->sizeHints[PUGL_DEFAULT_SIZE].height};
- return frame;
- }
-
- // Get a bounding rect from the transient parent or the screen
const NSScreen* const screen = viewScreen(view);
const NSRect boundsPt =
rectFromScreen(screen,
@@ -1184,17 +1159,11 @@ getInitialFrame(PuglView* const view)
? [[(const NSView*)view->transientParent window] frame]
: [screen frame]);
- // Center the frame around the center of the bounding rectangle
- const PuglViewSize defaultSize = view->sizeHints[PUGL_DEFAULT_SIZE];
- const NSRect boundsPx = nsRectFromPoints(view, boundsPt);
- const double centerX = boundsPx.origin.x + boundsPx.size.width / 2;
- const double centerY = boundsPx.origin.y + boundsPx.size.height / 2;
-
- const PuglRect frame = {(PuglCoord)(centerX - (defaultSize.width / 2U)),
- (PuglCoord)(centerY - (defaultSize.height / 2U)),
- view->sizeHints[PUGL_DEFAULT_SIZE].width,
- view->sizeHints[PUGL_DEFAULT_SIZE].height};
- return frame;
+ const NSRect boundsPx = nsRectFromPoints(view, boundsPt);
+ const PuglPoint center = {
+ (PuglCoord)(boundsPx.origin.x + (boundsPx.size.width / 2.0)),
+ (PuglCoord)(boundsPx.origin.y + (boundsPx.size.height / 2.0))};
+ return center;
}
PuglStatus
@@ -1242,11 +1211,12 @@ puglRealize(PuglView* view)
CVDisplayLinkRelease(link);
}
- // Get the initial frame to use from the defaults or last configuration
- const PuglRect initialFrame = getInitialFrame(view);
+ // Get the initial size and position from the defaults or last configuration
+ const PuglArea size = puglGetInitialSize(view);
+ const PuglPoint pos = puglGetInitialPosition(view, size);
// Convert frame to points
- const NSRect framePx = rectToNsRect(initialFrame);
+ const NSRect framePx = NSMakeRect(pos.x, pos.y, size.width, size.height);
const NSRect framePt = NSMakeRect(framePx.origin.x / scaleFactor,
framePx.origin.y / scaleFactor,
framePx.size.width / scaleFactor,
@@ -1272,7 +1242,7 @@ puglRealize(PuglView* view)
NSLayoutRelationGreaterThanOrEqual,
view->sizeHints[PUGL_MIN_SIZE].height)];
- if (puglIsValidSize(view->sizeHints[PUGL_MAX_SIZE])) {
+ if (puglIsValidArea(view->sizeHints[PUGL_MAX_SIZE])) {
[impl->wrapperView
addConstraint:puglConstraint(impl->wrapperView,
NSLayoutAttributeWidth,
@@ -1332,8 +1302,17 @@ puglRealize(PuglView* view)
((NSWindow*)window).delegate =
[[PuglWindowDelegate alloc] initWithPuglWindow:window];
- // Set basic window hints and attributes
- puglSetFrame(view, initialFrame);
+ // Set window frame
+ const NSRect screenPt = rectToScreen(screen, framePt);
+ const NSRect winFrame = [impl->window frameRectForContentRect:screenPt];
+ [impl->window setFrame:winFrame display:NO];
+
+ // Resize views and move them to (0, 0)
+ const NSRect sizePx = {{0, 0}, {framePx.size.width, framePx.size.height}};
+ const NSRect sizePt = [impl->drawView convertRectFromBacking:sizePx];
+ [impl->wrapperView setFrame:sizePt];
+ [impl->drawView setFrame:sizePt];
+
puglSetTransientParent(view, view->transientParent);
updateSizeHints(view);
@@ -1605,14 +1584,6 @@ puglSendEvent(PuglView* view, const PuglEvent* event)
return PUGL_UNSUPPORTED;
}
-#ifndef PUGL_DISABLE_DEPRECATED
-PuglStatus
-puglWaitForEvent(PuglView* view)
-{
- return puglPollEvents(view->world, -1.0);
-}
-#endif
-
PuglStatus
puglUpdate(PuglWorld* world, const double timeout)
{
@@ -1650,14 +1621,6 @@ puglUpdate(PuglWorld* world, const double timeout)
return PUGL_SUCCESS;
}
-#ifndef PUGL_DISABLE_DEPRECATED
-PuglStatus
-puglProcessEvents(PuglView* view)
-{
- return puglDispatchEvents(view->world);
-}
-#endif
-
double
puglGetTime(const PuglWorld* world)
{
@@ -1669,22 +1632,37 @@ puglGetTime(const PuglWorld* world)
}
PuglStatus
-puglPostRedisplay(PuglView* view)
+puglObscureView(PuglView* view)
{
[view->impl->drawView setNeedsDisplay:YES];
return PUGL_SUCCESS;
}
PuglStatus
-puglPostRedisplayRect(PuglView* view, const PuglRect rect)
+puglObscureRegion(PuglView* view,
+ const int x,
+ const int y,
+ const unsigned width,
+ const unsigned height)
{
- const NSRect rectPx = {
- {(double)rect.x,
- (double)view->lastConfigure.height - (rect.y + rect.height)},
- {(double)rect.width, (double)rect.height},
- };
+ if (!puglIsValidPosition(x, y) || !puglIsValidSize(width, height)) {
+ return PUGL_BAD_PARAMETER;
+ }
+
+ const PuglSpan viewHeight = view->lastConfigure.height;
- [view->impl->drawView setNeedsDisplayInRect:nsRectToPoints(view, rectPx)];
+ const int cx = MAX(0, x);
+ const int cy = MAX(0, viewHeight - y - (int)height);
+ const unsigned cw = MIN(view->lastConfigure.width, width);
+ const unsigned ch = MIN(view->lastConfigure.height, height);
+
+ if (cw == view->lastConfigure.width && ch == view->lastConfigure.height) {
+ [view->impl->drawView setNeedsDisplay:YES];
+ } else {
+ const NSRect rectPx = NSMakeRect(cx, cy, cw, ch);
+
+ [view->impl->drawView setNeedsDisplayInRect:nsRectToPoints(view, rectPx)];
+ }
return PUGL_SUCCESS;
}
@@ -1729,108 +1707,36 @@ puglGetScaleFactor(const PuglView* const view)
return [viewScreen(view) backingScaleFactor];
}
-PuglStatus
-puglSetFrame(PuglView* view, const PuglRect frame)
-{
- PuglInternals* const impl = view->impl;
- const NSRect framePx = rectToNsRect(frame);
- const NSRect framePt = nsRectToPoints(view, framePx);
-
- if (!impl->wrapperView) {
- // Set defaults to be used when realized
- view->defaultX = frame.x;
- view->defaultY = frame.y;
- view->sizeHints[PUGL_DEFAULT_SIZE].width = (PuglSpan)frame.width;
- view->sizeHints[PUGL_DEFAULT_SIZE].height = (PuglSpan)frame.height;
- return PUGL_SUCCESS;
- }
-
- if (impl->window) {
- const NSRect screenPt = rectToScreen(viewScreen(view), framePt);
-
- // Move and resize window to fit new content rect
- const NSRect winFrame = [impl->window frameRectForContentRect:screenPt];
- [impl->window setFrame:winFrame display:NO];
-
- // Resize views
- const NSRect sizePx = NSMakeRect(0, 0, frame.width, frame.height);
- const NSRect sizePt = [impl->drawView convertRectFromBacking:sizePx];
- [impl->wrapperView setFrame:sizePt];
- [impl->drawView setFrame:sizePt];
- [impl->window dispatchCurrentConfiguration];
- return PUGL_SUCCESS;
- }
-
- // Resize view
- const NSRect sizePx = NSMakeRect(0, 0, frame.width, frame.height);
- const NSRect sizePt = [impl->drawView convertRectFromBacking:sizePx];
-
- [impl->wrapperView setFrame:framePt];
- [impl->drawView setFrame:sizePt];
- return dispatchCurrentChildViewConfiguration(view);
-}
-
-PuglStatus
-puglSetPosition(PuglView* const view, const int x, const int y)
+static PuglStatus
+puglSetWindowPosition(PuglView* const view, const int x, const int y)
{
- if (x < INT16_MIN || x > INT16_MAX || y < INT16_MIN || y > INT16_MAX) {
- return PUGL_BAD_PARAMETER;
- }
-
PuglInternals* const impl = view->impl;
- if (!impl->wrapperView) {
- // Set defaults to be used when realized
- view->defaultX = x;
- view->defaultY = y;
- return PUGL_SUCCESS;
- }
- const PuglRect frame = {(PuglCoord)x,
- (PuglCoord)y,
- view->lastConfigure.width,
- view->lastConfigure.height};
+ const NSRect framePx =
+ NSMakeRect(x, y, view->lastConfigure.width, view->lastConfigure.height);
+
+ const NSRect framePt = nsRectToPoints(view, framePx);
if (impl->window) {
// Adjust top-level window frame
- return puglSetFrame(view, frame);
+ const NSRect screenPt = rectToScreen(viewScreen(view), framePt);
+ [impl->window setFrameOrigin:screenPt.origin];
+ return PUGL_SUCCESS;
}
// Set wrapper view origin
- const NSRect framePx = rectToNsRect(frame);
- const NSRect framePt = nsRectToPoints(view, framePx);
[impl->wrapperView setFrameOrigin:framePt.origin];
- // Set draw view origin
- const NSRect drawPx = NSMakeRect(0, 0, frame.width, frame.height);
- const NSRect drawPt = [impl->drawView convertRectFromBacking:drawPx];
- [impl->drawView setFrameOrigin:drawPt.origin];
-
// Dispatch new configuration
return dispatchCurrentChildViewConfiguration(view);
}
-PuglStatus
-puglSetSize(PuglView* const view, const unsigned width, const unsigned height)
+static PuglStatus
+puglSetWindowSize(PuglView* const view,
+ const unsigned width,
+ const unsigned height)
{
- if (width > INT16_MAX || height > INT16_MAX) {
- return PUGL_BAD_PARAMETER;
- }
-
PuglInternals* const impl = view->impl;
- if (!impl->wrapperView) {
- // Set defaults to be used when realized
- view->sizeHints[PUGL_DEFAULT_SIZE].width = (PuglSpan)width;
- view->sizeHints[PUGL_DEFAULT_SIZE].height = (PuglSpan)height;
- return PUGL_SUCCESS;
- }
-
- if (impl->window) {
- // Adjust top-level window frame
- PuglRect frame = puglGetFrame(view);
- frame.width = (PuglSpan)width;
- frame.height = (PuglSpan)height;
- return puglSetFrame(view, frame);
- }
// Set wrapper view size
const double scaleFactor = [viewScreen(view) backingScaleFactor];
@@ -1842,24 +1748,50 @@ puglSetSize(PuglView* const view, const unsigned width, const unsigned height)
const NSRect drawPt = [impl->drawView convertRectFromBacking:drawPx];
[impl->drawView setFrameSize:drawPt.size];
+ if (impl->window) {
+ const NSRect framePx =
+ NSMakeRect(view->lastConfigure.x, view->lastConfigure.y, width, height);
+ const NSRect framePt = nsRectToPoints(view, framePx);
+ const NSRect screenPt = rectToScreen(viewScreen(view), framePt);
+
+ // Resize window to fit new content rect
+ const NSRect winFrame = [impl->window frameRectForContentRect:screenPt];
+ [impl->window setFrame:winFrame display:NO];
+ [impl->window dispatchCurrentConfiguration];
+ }
+
// Dispatch new configuration
return dispatchCurrentChildViewConfiguration(view);
}
PuglStatus
-puglSetSizeHint(PuglView* const view,
- const PuglSizeHint hint,
- const PuglSpan width,
- const PuglSpan height)
+puglSetPositionHint(PuglView* const view,
+ const PuglPositionHint hint,
+ const int x,
+ const int y)
{
- if ((unsigned)hint >= PUGL_NUM_SIZE_HINTS) {
+ if (x <= INT16_MIN || x > INT16_MAX || y <= INT16_MIN || y > INT16_MAX) {
return PUGL_BAD_PARAMETER;
}
- view->sizeHints[hint].width = width;
- view->sizeHints[hint].height = height;
+ view->positionHints[hint].x = (PuglCoord)x;
+ view->positionHints[hint].y = (PuglCoord)y;
+
+ return (hint == PUGL_CURRENT_POSITION) ? puglSetWindowPosition(view, x, y)
+ : PUGL_SUCCESS;
+}
+
+PuglStatus
+puglSetSizeHint(PuglView* const view,
+ const PuglSizeHint hint,
+ const unsigned width,
+ const unsigned height)
+{
+ const PuglStatus st = puglStoreSizeHint(view, hint, width, height);
- return view->impl->window ? updateSizeHint(view, hint) : PUGL_SUCCESS;
+ return st ? st
+ : (hint == PUGL_CURRENT_SIZE) ? puglSetWindowSize(view, width, height)
+ : updateSizeHint(view, hint);
}
PuglStatus
@@ -1887,7 +1819,7 @@ puglPaste(PuglView* const view)
{
const PuglDataOfferEvent offer = {
PUGL_DATA_OFFER,
- 0,
+ 0U,
puglGetTime(view->world),
};
diff --git a/src/mac_cairo.m b/src/mac_cairo.m
index e4d2f5f..112b727 100644
--- a/src/mac_cairo.m
+++ b/src/mac_cairo.m
@@ -5,7 +5,7 @@
#include "mac.h"
#include "stub.h"
-#include "pugl/cairo.h"
+#include <pugl/cairo.h>
#include <cairo-quartz.h>
diff --git a/src/mac_gl.m b/src/mac_gl.m
index f177bf9..57dfc41 100644
--- a/src/mac_gl.m
+++ b/src/mac_gl.m
@@ -5,7 +5,7 @@
#include "mac.h"
#include "stub.h"
-#include "pugl/gl.h"
+#include <pugl/gl.h>
#ifndef __MAC_10_10
# define NSOpenGLProfileVersion4_1Core NSOpenGLProfileVersion3_2Core
diff --git a/src/mac_stub.m b/src/mac_stub.m
index 9ebedca..c7e4512 100644
--- a/src/mac_stub.m
+++ b/src/mac_stub.m
@@ -5,7 +5,7 @@
#include "mac.h"
#include "stub.h"
-#include "pugl/stub.h"
+#include <pugl/stub.h>
#import <Cocoa/Cocoa.h>
diff --git a/src/mac_vulkan.m b/src/mac_vulkan.m
index 4fdbaf6..f3563e2 100644
--- a/src/mac_vulkan.m
+++ b/src/mac_vulkan.m
@@ -8,9 +8,9 @@
#include "stub.h"
#include "types.h"
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
-#include "pugl/vulkan.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
+#include <pugl/vulkan.h>
#include <vulkan/vulkan_core.h>
#include <vulkan/vulkan_macos.h>
diff --git a/src/platform.h b/src/platform.h
index cfdb1b7..e43a58e 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -8,13 +8,12 @@
#include "types.h"
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
PUGL_BEGIN_DECLS
/// Allocate and initialise world internals (implemented once per platform)
-PUGL_MALLOC_FUNC
-PuglWorldInternals*
+PUGL_MALLOC_FUNC PuglWorldInternals*
puglInitWorldInternals(PuglWorldType type, PuglWorldFlags flags);
/// Destroy and free world internals (implemented once per platform)
@@ -22,8 +21,7 @@ void
puglFreeWorldInternals(PuglWorld* world);
/// Allocate and initialise view internals (implemented once per platform)
-PUGL_MALLOC_FUNC
-PuglInternals*
+PUGL_MALLOC_FUNC PuglInternals*
puglInitViewInternals(PuglWorld* world);
/// Destroy and free view internals (implemented once per platform)
diff --git a/src/stub.h b/src/stub.h
index 699bbb9..476aa1a 100644
--- a/src/stub.h
+++ b/src/stub.h
@@ -4,7 +4,7 @@
#ifndef PUGL_SRC_STUB_H
#define PUGL_SRC_STUB_H
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#include <stddef.h>
diff --git a/src/types.h b/src/types.h
index 9817474..b453f11 100644
--- a/src/types.h
+++ b/src/types.h
@@ -6,7 +6,7 @@
#include "attributes.h"
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#include <stdbool.h>
#include <stddef.h>
@@ -21,18 +21,6 @@ typedef struct PuglInternalsImpl PuglInternals;
/// View hints
typedef int PuglHints[PUGL_NUM_VIEW_HINTS];
-/// View position (both X and Y coordinates) or general point
-typedef struct {
- PuglCoord x;
- PuglCoord y;
-} PuglPoint;
-
-/// View size (both X and Y coordinates)
-typedef struct {
- PuglSpan width;
- PuglSpan height;
-} PuglViewSize;
-
/// Blob of arbitrary data
typedef struct {
void* data; ///< Dynamically allocated data
@@ -57,10 +45,9 @@ struct PuglViewImpl {
uintptr_t transientParent;
PuglConfigureEvent lastConfigure;
PuglHints hints;
- PuglViewSize sizeHints[PUGL_NUM_SIZE_HINTS];
+ PuglPoint positionHints[PUGL_NUM_POSITION_HINTS];
+ PuglArea sizeHints[PUGL_NUM_SIZE_HINTS];
char* strings[PUGL_NUM_STRING_HINTS];
- int defaultX;
- int defaultY;
PuglViewStage stage;
bool resizing;
};
@@ -82,23 +69,21 @@ typedef void PuglSurface;
/// Graphics backend interface
struct PuglBackendImpl {
/// Get visual information from display and setup view as necessary
- PUGL_WARN_UNUSED_RESULT
- PuglStatus (*configure)(PuglView*);
+ PUGL_WARN_UNUSED_RESULT PuglStatus (*configure)(PuglView*);
/// Create surface and drawing context
- PUGL_WARN_UNUSED_RESULT
- PuglStatus (*create)(PuglView*);
+ PUGL_WARN_UNUSED_RESULT PuglStatus (*create)(PuglView*);
/// Destroy surface and drawing context
void (*destroy)(PuglView*);
/// Enter drawing context, for drawing if expose is non-null
- PUGL_WARN_UNUSED_RESULT
- PuglStatus (*enter)(PuglView*, const PuglExposeEvent*);
+ PUGL_WARN_UNUSED_RESULT PuglStatus (*enter)(PuglView*,
+ const PuglExposeEvent*);
/// Leave drawing context, after drawing if expose is non-null
- PUGL_WARN_UNUSED_RESULT
- PuglStatus (*leave)(PuglView*, const PuglExposeEvent*);
+ PUGL_WARN_UNUSED_RESULT PuglStatus (*leave)(PuglView*,
+ const PuglExposeEvent*);
/// Return the puglGetContext() handle for the application, if any
void* (*getContext)(PuglView*);
diff --git a/src/win.c b/src/win.c
index 73c8583..a8cd841 100644
--- a/src/win.c
+++ b/src/win.c
@@ -4,9 +4,10 @@
#include "win.h"
#include "internal.h"
+#include "macros.h"
#include "platform.h"
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#include <dwmapi.h>
#include <windows.h>
@@ -43,12 +44,10 @@
#ifdef __cplusplus
# define PUGL_INIT_STRUCT \
- {}
-#else
-# define PUGL_INIT_STRUCT \
{ \
- 0 \
}
+#else
+# define PUGL_INIT_STRUCT {0}
#endif
typedef BOOL(WINAPI* PFN_SetProcessDPIAware)(void);
@@ -58,8 +57,12 @@ typedef HRESULT(WINAPI* PFN_GetScaleFactorForMonitor)(HMONITOR, DWORD*);
LRESULT CALLBACK
wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
-static wchar_t*
-puglUtf8ToWideChar(const char* const utf8)
+#ifdef UNICODE
+
+typedef wchar_t ArgStringChar;
+
+static ArgStringChar*
+puglArgStringNew(const char* const utf8)
{
const int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
if (len > 0) {
@@ -71,6 +74,30 @@ puglUtf8ToWideChar(const char* const utf8)
return NULL;
}
+static void
+puglArgStringFree(ArgStringChar* const utf8)
+{
+ free(utf8);
+}
+
+#else // !defined(UNICODE)
+
+typedef const char ArgStringChar;
+
+static ArgStringChar*
+puglArgStringNew(const char* const utf8)
+{
+ return utf8;
+}
+
+static void
+puglArgStringFree(ArgStringChar* const utf8)
+{
+ (void)utf8;
+}
+
+#endif
+
static char*
puglWideCharToUtf8(const wchar_t* const wstr, size_t* len)
{
@@ -94,11 +121,7 @@ puglWinStatus(const BOOL success)
static bool
puglRegisterWindowClass(const char* name)
{
-#ifdef UNICODE
- wchar_t* const wname = puglUtf8ToWideChar(name);
-#else
- const char* const wname = name;
-#endif
+ ArgStringChar* const nameArg = puglArgStringNew(name);
HMODULE module = NULL;
if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
@@ -109,7 +132,7 @@ puglRegisterWindowClass(const char* name)
}
WNDCLASSEX wc = PUGL_INIT_STRUCT;
- if (GetClassInfoEx(module, wname, &wc)) {
+ if (GetClassInfoEx(module, nameArg, &wc)) {
return true; // Already registered
}
@@ -120,12 +143,10 @@ puglRegisterWindowClass(const char* name)
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wc.lpszClassName = wname;
+ wc.lpszClassName = nameArg;
const bool success = !!RegisterClassEx(&wc);
-#ifdef UNICODE
- free(wname);
-#endif
+ puglArgStringFree(nameArg);
return success;
}
@@ -184,7 +205,7 @@ static double
puglWinGetViewScaleFactor(const PuglView* const view)
{
const HMODULE shcore =
- LoadLibraryExA("Shcore.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ LoadLibraryEx(TEXT("Shcore.dll"), NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!shcore) {
return 1.0;
}
@@ -219,7 +240,7 @@ puglInitWorldInternals(PuglWorldType type, PuglWorldFlags PUGL_UNUSED(flags))
if (type == PUGL_PROGRAM) {
HMODULE user32 =
- LoadLibraryExA("user32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ LoadLibraryEx(TEXT("user32.dll"), NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (user32) {
PFN_SetProcessDPIAware SetProcessDPIAware =
(PFN_SetProcessDPIAware)GetProcAddress(user32, "SetProcessDPIAware");
@@ -250,20 +271,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)
{
@@ -287,9 +294,9 @@ puglRealize(PuglView* view)
puglEnsureHint(view, PUGL_ALPHA_BITS, 8);
// Get refresh rate for resize draw timer
- DEVMODEA devMode;
+ DEVMODE devMode;
memset(&devMode, 0, sizeof(devMode));
- EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &devMode);
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode);
view->hints[PUGL_REFRESH_RATE] = (int)devMode.dmDisplayFrequency;
// Register window class if necessary
@@ -308,16 +315,16 @@ puglRealize(PuglView* view)
puglSetViewString(view, PUGL_WINDOW_TITLE, view->strings[PUGL_WINDOW_TITLE]);
puglSetTransientParent(view, view->transientParent);
- view->impl->scaleFactor = puglWinGetViewScaleFactor(view);
- view->impl->cursor = LoadCursor(NULL, IDC_ARROW);
+ impl->scaleFactor = puglWinGetViewScaleFactor(view);
+ impl->cursor = LoadCursor(NULL, IDC_ARROW);
if (view->hints[PUGL_DARK_FRAME]) {
const BOOL useDarkMode = TRUE;
- if ((DwmSetWindowAttribute(view->impl->hwnd,
+ if ((DwmSetWindowAttribute(impl->hwnd,
DWMWA_USE_IMMERSIVE_DARK_MODE,
&useDarkMode,
sizeof(useDarkMode)) != S_OK)) {
- DwmSetWindowAttribute(view->impl->hwnd,
+ DwmSetWindowAttribute(impl->hwnd,
PRE_20H1_DWMWA_USE_IMMERSIVE_DARK_MODE,
&useDarkMode,
sizeof(useDarkMode));
@@ -343,24 +350,22 @@ puglUnrealize(PuglView* const view)
view->backend->destroy(view);
}
- 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;
+ ReleaseDC(impl->hwnd, impl->hdc);
+ impl->hdc = NULL;
+
+ const PuglStatus st = puglWinStatus(DestroyWindow(impl->hwnd));
+ 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;
}
}
@@ -379,15 +384,13 @@ puglShow(PuglView* view, const PuglShowCommand command)
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;
}
@@ -408,14 +411,11 @@ puglFreeViewInternals(PuglView* view)
void
puglFreeWorldInternals(PuglWorld* world)
{
-#ifdef UNICODE
- wchar_t* const wname = puglUtf8ToWideChar(world->strings[PUGL_CLASS_NAME]);
- UnregisterClass(wname, NULL);
- free(wname);
-#else
- UnregisterClass(world->strings[PUGL_CLASS_NAME], NULL);
-#endif
+ const char* const className = world->strings[PUGL_CLASS_NAME];
+ ArgStringChar* const classNameArg = puglArgStringNew(className);
+ UnregisterClass(classNameArg, NULL);
+ puglArgStringFree(classNameArg);
free(world->impl);
}
@@ -426,14 +426,14 @@ keyInRange(const WPARAM winSym,
const PuglKey puglMin)
{
return (winSym >= winMin && winSym <= winMax)
- ? (PuglKey)(puglMin + (winSym - winMin))
- : (PuglKey)0;
+ ? (PuglKey)((WPARAM)puglMin + (winSym - winMin))
+ : PUGL_KEY_NONE;
}
static PuglKey
keySymToSpecial(const WPARAM sym, const bool ext)
{
- PuglKey key = (PuglKey)0;
+ PuglKey key = PUGL_KEY_NONE;
if ((key = keyInRange(sym, VK_F1, VK_F12, PUGL_KEY_F1)) ||
(key = keyInRange(sym,
VK_PRIOR,
@@ -482,23 +482,26 @@ keySymToSpecial(const WPARAM sym, const bool ext)
// clang-format on
}
- return (PuglKey)0;
+ return PUGL_KEY_NONE;
+}
+
+static bool
+is_toggled(int vkey)
+{
+ return (unsigned)GetKeyState(vkey) & 1U;
}
static uint32_t
getModifiers(void)
{
- // clang-format off
- return (
- ((GetKeyState(VK_SHIFT) < 0) ? (uint32_t)PUGL_MOD_SHIFT : 0U) |
- ((GetKeyState(VK_CONTROL) < 0) ? (uint32_t)PUGL_MOD_CTRL : 0U) |
- ((GetKeyState(VK_MENU) < 0) ? (uint32_t)PUGL_MOD_ALT : 0U) |
- ((GetKeyState(VK_LWIN) < 0) ? (uint32_t)PUGL_MOD_SUPER : 0U) |
- ((GetKeyState(VK_RWIN) < 0) ? (uint32_t)PUGL_MOD_SUPER : 0U) |
- ((GetKeyState(VK_NUMLOCK) & 1U) ? (uint32_t)PUGL_MOD_NUM_LOCK : 0U) |
- ((GetKeyState(VK_SCROLL) & 1U) ? (uint32_t)PUGL_MOD_SCROLL_LOCK : 0U) |
- ((GetKeyState(VK_CAPITAL) & 1U) ? (uint32_t)PUGL_MOD_CAPS_LOCK : 0U));
- // clang-format on
+ return ((uint32_t)(((GetKeyState(VK_SHIFT) < 0) ? PUGL_MOD_SHIFT : 0) |
+ ((GetKeyState(VK_CONTROL) < 0) ? PUGL_MOD_CTRL : 0) |
+ ((GetKeyState(VK_MENU) < 0) ? PUGL_MOD_ALT : 0) |
+ ((GetKeyState(VK_LWIN) < 0) ? PUGL_MOD_SUPER : 0) |
+ ((GetKeyState(VK_RWIN) < 0) ? PUGL_MOD_SUPER : 0) |
+ (is_toggled(VK_NUMLOCK) ? PUGL_MOD_NUM_LOCK : 0) |
+ (is_toggled(VK_SCROLL) ? PUGL_MOD_SCROLL_LOCK : 0) |
+ (is_toggled(VK_CAPITAL) ? PUGL_MOD_CAPS_LOCK : 0)));
}
static void
@@ -673,7 +676,7 @@ handleCrossing(PuglView* view, const PuglEventType type, POINT pos)
const PuglCrossingEvent ev = {
type,
- 0,
+ 0U,
GetMessageTime() / 1e3,
(double)pos.x,
(double)pos.y,
@@ -683,7 +686,7 @@ handleCrossing(PuglView* view, const PuglEventType type, POINT pos)
PUGL_CROSSING_NORMAL,
};
- PuglEvent crossingEvent = {{type, 0}};
+ PuglEvent crossingEvent = {{type, 0U}};
crossingEvent.crossing = ev;
puglDispatchEvent(view, &crossingEvent);
}
@@ -693,8 +696,8 @@ constrainAspect(const PuglView* const view,
RECT* const size,
const WPARAM wParam)
{
- const PuglViewSize minAspect = view->sizeHints[PUGL_MIN_ASPECT];
- const PuglViewSize maxAspect = view->sizeHints[PUGL_MAX_ASPECT];
+ const PuglArea minAspect = view->sizeHints[PUGL_MIN_ASPECT];
+ const PuglArea maxAspect = view->sizeHints[PUGL_MAX_ASPECT];
const float minA = (float)minAspect.width / (float)minAspect.height;
const float maxA = (float)maxAspect.width / (float)maxAspect.height;
@@ -733,7 +736,7 @@ constrainAspect(const PuglView* const view,
static LRESULT
handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
{
- PuglEvent event = {{PUGL_NOTHING, 0}};
+ PuglEvent event = {{PUGL_NOTHING, 0U}};
RECT rect = {0, 0, 0, 0};
POINT pt = {0, 0};
MINMAXINFO* mmi = NULL;
@@ -779,8 +782,8 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
handleConfigure(view, &event);
break;
case WM_SIZING:
- if (puglIsValidSize(view->sizeHints[PUGL_MIN_ASPECT]) &&
- puglIsValidSize(view->sizeHints[PUGL_MAX_ASPECT])) {
+ if (puglIsValidArea(view->sizeHints[PUGL_MIN_ASPECT]) &&
+ puglIsValidArea(view->sizeHints[PUGL_MAX_ASPECT])) {
constrainAspect(view, (RECT*)lParam, wParam);
return TRUE;
}
@@ -795,7 +798,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_TIMER:
if (wParam >= PUGL_USER_TIMER_MIN) {
- PuglEvent ev = {{PUGL_TIMER, 0}};
+ PuglEvent ev = {{PUGL_TIMER, 0U}};
ev.timer.id = wParam - PUGL_USER_TIMER_MIN;
puglDispatchEvent(view, &ev);
}
@@ -812,7 +815,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
mmi = (MINMAXINFO*)lParam;
mmi->ptMinTrackSize.x = view->sizeHints[PUGL_MIN_SIZE].width;
mmi->ptMinTrackSize.y = view->sizeHints[PUGL_MIN_SIZE].height;
- if (puglIsValidSize(view->sizeHints[PUGL_MAX_SIZE])) {
+ if (puglIsValidArea(view->sizeHints[PUGL_MAX_SIZE])) {
mmi->ptMaxTrackSize.x = view->sizeHints[PUGL_MAX_SIZE].width;
mmi->ptMaxTrackSize.y = view->sizeHints[PUGL_MAX_SIZE].height;
}
@@ -948,8 +951,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
@@ -1023,7 +1025,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;
@@ -1034,9 +1036,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
@@ -1049,31 +1050,19 @@ 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;
}
-#ifndef PUGL_DISABLE_DEPRECATED
-PuglStatus
-puglWaitForEvent(PuglView* PUGL_UNUSED(view))
-{
- WaitMessage();
- return PUGL_SUCCESS;
-}
-#endif
-
static PuglStatus
puglDispatchViewEvents(PuglView* view)
{
@@ -1118,21 +1107,24 @@ puglDispatchWinEvents(PuglWorld* world)
PuglStatus
puglUpdate(PuglWorld* world, double timeout)
{
+ static const double minWaitSeconds = 0.002;
+
const double startTime = puglGetTime(world);
PuglStatus st = PUGL_SUCCESS;
if (timeout < 0.0) {
- st = puglPollWinEvents(world, timeout);
- st = st ? st : puglDispatchWinEvents(world);
- } else if (timeout <= 0.001) {
+ WaitMessage();
+ st = puglDispatchWinEvents(world);
+ } else if (timeout < minWaitSeconds) {
st = puglDispatchWinEvents(world);
} else {
- const double endTime = startTime + timeout - 0.001;
- for (double t = startTime; t < endTime; t = puglGetTime(world)) {
- if ((st = puglPollWinEvents(world, endTime - t)) ||
- (st = puglDispatchWinEvents(world))) {
- break;
- }
+ const double endTime = startTime + timeout - minWaitSeconds;
+ 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);
}
}
@@ -1147,14 +1139,6 @@ puglUpdate(PuglWorld* world, double timeout)
return st;
}
-#ifndef PUGL_DISABLE_DEPRECATED
-PuglStatus
-puglProcessEvents(PuglView* view)
-{
- return puglUpdate(view->world, 0.0);
-}
-#endif
-
LRESULT CALLBACK
wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
@@ -1188,23 +1172,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
@@ -1218,19 +1208,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) {
- wchar_t* const wtitle = puglUtf8ToWideChar(value);
- if (wtitle) {
- SetWindowTextW(view->impl->hwnd, wtitle);
- free(wtitle);
- }
+ ArgStringChar* const titleArg = puglArgStringNew(value);
+ st = puglWinStatus(SetWindowText(view->impl->hwnd, titleArg));
+ puglArgStringFree(titleArg);
}
- return PUGL_SUCCESS;
+ return st;
}
static RECT
@@ -1255,45 +1244,9 @@ puglGetScaleFactor(const PuglView* const view)
: puglWinGetViewScaleFactor(view);
}
-PuglStatus
-puglSetFrame(PuglView* view, const PuglRect frame)
-{
- if (!view->impl->hwnd) {
- // Set defaults to be used when realized
- view->defaultX = frame.x;
- view->defaultY = frame.y;
- view->sizeHints[PUGL_DEFAULT_SIZE].width = frame.width;
- view->sizeHints[PUGL_DEFAULT_SIZE].height = frame.height;
- return PUGL_SUCCESS;
- }
-
- const RECT rect =
- adjustedWindowRect(view, frame.x, frame.y, frame.width, frame.height);
-
- return puglWinStatus(
- SetWindowPos(view->impl->hwnd,
- HWND_TOP,
- rect.left,
- rect.top,
- rect.right - rect.left,
- rect.bottom - rect.top,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER));
-}
-
-PuglStatus
-puglSetPosition(PuglView* const view, const int x, const int y)
+static PuglStatus
+puglSetWindowPosition(PuglView* const view, const int x, const int y)
{
- if (x < INT16_MIN || x > INT16_MAX || y < INT16_MIN || y > INT16_MAX) {
- return PUGL_BAD_PARAMETER;
- }
-
- if (!view->impl->hwnd) {
- // Set defaults to be used when realized
- view->defaultX = x;
- view->defaultY = y;
- return PUGL_SUCCESS;
- }
-
const RECT rect = adjustedWindowRect(
view, x, y, view->lastConfigure.width, view->lastConfigure.height);
@@ -1304,20 +1257,11 @@ puglSetPosition(PuglView* const view, const int x, const int y)
SetWindowPos(view->impl->hwnd, HWND_TOP, rect.left, rect.top, 0, 0, flags));
}
-PuglStatus
-puglSetSize(PuglView* const view, const unsigned width, const unsigned height)
+static PuglStatus
+puglSetWindowSize(PuglView* const view,
+ const unsigned width,
+ const unsigned height)
{
- if (width > INT16_MAX || height > INT16_MAX) {
- return PUGL_BAD_PARAMETER;
- }
-
- if (!view->impl->hwnd) {
- // Set defaults to be used when realized
- view->sizeHints[PUGL_DEFAULT_SIZE].width = (PuglSpan)width;
- view->sizeHints[PUGL_DEFAULT_SIZE].height = (PuglSpan)height;
- return PUGL_SUCCESS;
- }
-
const RECT rect = adjustedWindowRect(view,
view->lastConfigure.x,
view->lastConfigure.y,
@@ -1337,18 +1281,33 @@ puglSetSize(PuglView* const view, const unsigned width, const unsigned height)
}
PuglStatus
-puglSetSizeHint(PuglView* const view,
- const PuglSizeHint hint,
- const PuglSpan width,
- const PuglSpan height)
+puglSetPositionHint(PuglView* const view,
+ const PuglPositionHint hint,
+ const int x,
+ const int y)
{
- if ((unsigned)hint >= PUGL_NUM_SIZE_HINTS) {
+ if (x <= INT16_MIN || x > INT16_MAX || y <= INT16_MIN || y > INT16_MAX) {
return PUGL_BAD_PARAMETER;
}
- view->sizeHints[hint].width = width;
- view->sizeHints[hint].height = height;
- return PUGL_SUCCESS;
+ view->positionHints[hint].x = (PuglCoord)x;
+ view->positionHints[hint].y = (PuglCoord)y;
+
+ return (hint == PUGL_CURRENT_POSITION) ? puglSetWindowPosition(view, x, y)
+ : PUGL_SUCCESS;
+}
+
+PuglStatus
+puglSetSizeHint(PuglView* const view,
+ const PuglSizeHint hint,
+ const unsigned width,
+ const unsigned height)
+{
+ const PuglStatus st = puglStoreSizeHint(view, hint, width, height);
+
+ return (!st && hint == PUGL_CURRENT_SIZE)
+ ? puglSetWindowSize(view, width, height)
+ : st;
}
PuglStatus
@@ -1394,15 +1353,14 @@ puglAcceptOffer(PuglView* const view,
const PuglDataEvent data = {
PUGL_DATA,
- 0,
+ 0U,
GetMessageTime() / 1e3,
0,
};
PuglEvent dataEvent;
dataEvent.data = data;
- puglDispatchEvent(view, &dataEvent);
- return PUGL_SUCCESS;
+ return puglDispatchEvent(view, &dataEvent);
}
const void*
@@ -1412,8 +1370,21 @@ puglGetClipboard(PuglView* const view,
{
PuglInternals* const impl = view->impl;
- if (typeIndex > 0U || !IsClipboardFormatAvailable(CF_UNICODETEXT) ||
- !OpenClipboard(impl->hwnd)) {
+ if (typeIndex > 0U || !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
+ return NULL;
+ }
+
+ // Try to open the clipboard several times since others may have locked it
+ BOOL opened = FALSE;
+ static const unsigned max_tries = 16U;
+ for (unsigned i = 0U; !opened && i < max_tries; ++i) {
+ opened = OpenClipboard(impl->hwnd);
+ if (!opened) {
+ Sleep(0);
+ }
+ }
+
+ if (!opened) {
return NULL;
}
@@ -1424,15 +1395,14 @@ puglGetClipboard(PuglView* const view,
return NULL;
}
- free(view->impl->clipboard.data);
- view->impl->clipboard.data =
- puglWideCharToUtf8(wstr, &view->impl->clipboard.len);
+ free(impl->clipboard.data);
+ impl->clipboard.data = puglWideCharToUtf8(wstr, &impl->clipboard.len);
GlobalUnlock(mem);
CloseClipboard();
- *len = view->impl->clipboard.len;
- return view->impl->clipboard.data;
+ *len = impl->clipboard.len;
+ return impl->clipboard.data;
}
PuglStatus
@@ -1443,7 +1413,7 @@ puglSetClipboard(PuglView* const view,
{
PuglInternals* const impl = view->impl;
- PuglStatus st = puglSetBlob(&view->impl->clipboard, data, len);
+ PuglStatus st = puglSetBlob(&impl->clipboard, data, len);
if (st) {
return st;
}
@@ -1488,14 +1458,13 @@ puglPaste(PuglView* const view)
{
const PuglDataOfferEvent offer = {
PUGL_DATA_OFFER,
- 0,
+ 0U,
GetMessageTime() / 1e3,
};
PuglEvent offerEvent;
offerEvent.offer = offer;
- puglDispatchEvent(view, &offerEvent);
- return PUGL_SUCCESS;
+ return puglDispatchEvent(view, &offerEvent);
}
static const TCHAR* const cursor_ids[] = {
@@ -1563,42 +1532,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 (x >= INT16_MIN && x <= INT16_MAX && y >= INT16_MIN && y <= INT16_MAX) {
- // Use the default position set with puglSetPosition while unrealized
- const PuglRect frame = {
- (PuglCoord)x, (PuglCoord)y, defaultWidth, defaultHeight};
- return frame;
- }
-
- // 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);
+ RECT rect = {0, 0, 0, 0};
+ GetWindowRect(view->transientParent ? (HWND)view->transientParent
+ : 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
@@ -1613,28 +1558,35 @@ 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);
+ ArgStringChar* const titleArg = puglArgStringNew(title);
+
// Create window and get drawing context
- if (!(*hwnd = CreateWindowExA(winExFlags,
- className,
- title,
- winFlags,
- wr.left,
- wr.right,
- wr.right - wr.left,
- wr.bottom - wr.top,
- (HWND)parent,
- NULL,
- NULL,
- NULL))) {
+ *hwnd = CreateWindowEx(winExFlags,
+ classNameArg,
+ titleArg,
+ winFlags,
+ wr.left,
+ wr.right,
+ wr.right - wr.left,
+ wr.bottom - wr.top,
+ (HWND)parent,
+ NULL,
+ NULL,
+ NULL);
+ puglArgStringFree(titleArg);
+ puglArgStringFree(classNameArg);
+ if (!*hwnd) {
return PUGL_REALIZE_FAILED;
}
@@ -1660,7 +1612,6 @@ puglWinConfigure(PuglView* view)
{
PuglInternals* const impl = view->impl;
PuglStatus st = PUGL_SUCCESS;
-
if ((st = puglWinCreateWindow(view, "Pugl", &impl->hwnd, &impl->hdc))) {
return st;
}
@@ -1673,20 +1624,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
diff --git a/src/win.h b/src/win.h
index 84f1d4e..b37db3f 100644
--- a/src/win.h
+++ b/src/win.h
@@ -6,7 +6,7 @@
#include "internal.h"
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#include <windows.h>
@@ -37,28 +37,19 @@ struct PuglInternalsImpl {
bool fullscreen;
};
-PUGL_API
-PuglWinPFD
+PUGL_API PuglWinPFD
puglWinGetPixelFormatDescriptor(const PuglHints hints);
-PUGL_WARN_UNUSED_RESULT
-PUGL_API
-PuglStatus
+PUGL_WARN_UNUSED_RESULT PUGL_API PuglStatus
puglWinCreateWindow(PuglView* view, const char* title, HWND* hwnd, HDC* hdc);
-PUGL_WARN_UNUSED_RESULT
-PUGL_API
-PuglStatus
+PUGL_WARN_UNUSED_RESULT PUGL_API PuglStatus
puglWinConfigure(PuglView* view);
-PUGL_WARN_UNUSED_RESULT
-PUGL_API
-PuglStatus
+PUGL_WARN_UNUSED_RESULT PUGL_API PuglStatus
puglWinEnter(PuglView* view, const PuglExposeEvent* expose);
-PUGL_WARN_UNUSED_RESULT
-PUGL_API
-PuglStatus
+PUGL_WARN_UNUSED_RESULT PUGL_API PuglStatus
puglWinLeave(PuglView* view, const PuglExposeEvent* expose);
#endif // PUGL_SRC_WIN_H
diff --git a/src/win_cairo.c b/src/win_cairo.c
index 0aab254..873d395 100644
--- a/src/win_cairo.c
+++ b/src/win_cairo.c
@@ -5,7 +5,7 @@
#include "types.h"
#include "win.h"
-#include "pugl/cairo.h"
+#include <pugl/cairo.h>
#include <cairo-win32.h>
#include <cairo.h>
diff --git a/src/win_gl.c b/src/win_gl.c
index 01321d4..4f33e36 100644
--- a/src/win_gl.c
+++ b/src/win_gl.c
@@ -5,7 +5,7 @@
#include "types.h"
#include "win.h"
-#include "pugl/gl.h"
+#include <pugl/gl.h>
#include <windows.h>
@@ -14,30 +14,42 @@
#include <stdbool.h>
#include <stdlib.h>
-#define WGL_DRAW_TO_WINDOW_ARB 0x2001
-#define WGL_ACCELERATION_ARB 0x2003
-#define WGL_SUPPORT_OPENGL_ARB 0x2010
-#define WGL_DOUBLE_BUFFER_ARB 0x2011
-#define WGL_PIXEL_TYPE_ARB 0x2013
-#define WGL_RED_BITS_ARB 0x2015
-#define WGL_GREEN_BITS_ARB 0x2017
-#define WGL_BLUE_BITS_ARB 0x2019
-#define WGL_ALPHA_BITS_ARB 0x201b
-#define WGL_DEPTH_BITS_ARB 0x2022
-#define WGL_STENCIL_BITS_ARB 0x2023
-#define WGL_FULL_ACCELERATION_ARB 0x2027
-#define WGL_TYPE_RGBA_ARB 0x202b
-#define WGL_SAMPLE_BUFFERS_ARB 0x2041
-#define WGL_SAMPLES_ARB 0x2042
-
-#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
-#define WGL_CONTEXT_FLAGS_ARB 0x2094
-#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
-
-#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
-#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
-#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
+typedef enum {
+ WGL_DRAW_TO_WINDOW_ARB = 0x2001,
+ WGL_ACCELERATION_ARB = 0x2003,
+ WGL_SUPPORT_OPENGL_ARB = 0x2010,
+ WGL_DOUBLE_BUFFER_ARB = 0x2011,
+ WGL_PIXEL_TYPE_ARB = 0x2013,
+ WGL_RED_BITS_ARB = 0x2015,
+ WGL_GREEN_BITS_ARB = 0x2017,
+ WGL_BLUE_BITS_ARB = 0x2019,
+ WGL_ALPHA_BITS_ARB = 0x201B,
+ WGL_DEPTH_BITS_ARB = 0x2022,
+ WGL_STENCIL_BITS_ARB = 0x2023,
+ WGL_SAMPLE_BUFFERS_ARB = 0x2041,
+ WGL_SAMPLES_ARB = 0x2042,
+} PuglWinGlHintName;
+
+typedef enum {
+ WGL_FULL_ACCELERATION_ARB = 0x2027,
+ WGL_TYPE_RGBA_ARB = 0x202B,
+} PuglWinGlHintValue;
+
+typedef enum {
+ WGL_CONTEXT_MAJOR_VERSION_ARB = 0x2091,
+ WGL_CONTEXT_MINOR_VERSION_ARB = 0x2092,
+ WGL_CONTEXT_FLAGS_ARB = 0x2094,
+ WGL_CONTEXT_PROFILE_MASK_ARB = 0x9126,
+} PuglWinGlContextAttribName;
+
+typedef enum {
+ WGL_CONTEXT_CORE_PROFILE_BIT_ARB = 0x00000001,
+ WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = 0x00000002,
+} PuglWinGlContextProfileBit;
+
+typedef enum {
+ WGL_CONTEXT_DEBUG_BIT_ARB = 0x00000001,
+} PuglWinGlContextDebugBit;
typedef HGLRC(WINAPI* WglCreateContextAttribs)(HDC, HGLRC, const int*);
diff --git a/src/win_stub.c b/src/win_stub.c
index e98357c..d2dc3f3 100644
--- a/src/win_stub.c
+++ b/src/win_stub.c
@@ -5,7 +5,7 @@
#include "types.h"
#include "win.h"
-#include "pugl/stub.h"
+#include <pugl/stub.h>
static PuglStatus
puglWinStubConfigure(PuglView* view)
diff --git a/src/win_vulkan.c b/src/win_vulkan.c
index 2927447..bd3bf45 100644
--- a/src/win_vulkan.c
+++ b/src/win_vulkan.c
@@ -7,7 +7,7 @@
#include "types.h"
#include "win.h"
-#include "pugl/vulkan.h"
+#include <pugl/vulkan.h>
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_win32.h>
diff --git a/src/x11.c b/src/x11.c
index 217838f..3d2e080 100644
--- a/src/x11.c
+++ b/src/x11.c
@@ -11,7 +11,7 @@
#include "platform.h"
#include "types.h"
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#include <X11/X.h>
#include <X11/Xatom.h>
@@ -70,12 +70,10 @@
#ifdef __cplusplus
# define PUGL_INIT_STRUCT \
- {}
-#else
-# define PUGL_INIT_STRUCT \
{ \
- 0 \
}
+#else
+# define PUGL_INIT_STRUCT {0}
#endif
enum WmClientStateMessageAction {
@@ -407,40 +405,44 @@ updateSizeHints(const PuglView* const view)
XSizeHints sizeHints = PUGL_INIT_STRUCT;
if (!view->hints[PUGL_RESIZABLE]) {
- const PuglRect frame = puglGetFrame(view);
+ PuglArea size = puglGetSizeHint(view, PUGL_CURRENT_SIZE);
+ if (!puglIsValidSize(size.width, size.height)) {
+ size = puglGetSizeHint(view, PUGL_DEFAULT_SIZE);
+ }
+
sizeHints.flags = PBaseSize | PMinSize | PMaxSize;
- sizeHints.base_width = (int)frame.width;
- sizeHints.base_height = (int)frame.height;
- sizeHints.min_width = (int)frame.width;
- sizeHints.min_height = (int)frame.height;
- sizeHints.max_width = (int)frame.width;
- sizeHints.max_height = (int)frame.height;
+ sizeHints.base_width = (int)size.width;
+ sizeHints.base_height = (int)size.height;
+ sizeHints.min_width = (int)size.width;
+ sizeHints.min_height = (int)size.height;
+ sizeHints.max_width = (int)size.width;
+ sizeHints.max_height = (int)size.height;
} else {
// Avoid setting PBaseSize for top level views to avoid window manager bugs
- const PuglViewSize defaultSize = view->sizeHints[PUGL_DEFAULT_SIZE];
- if (puglIsValidSize(defaultSize) && view->parent) {
+ const PuglArea defaultSize = view->sizeHints[PUGL_DEFAULT_SIZE];
+ if (puglIsValidArea(defaultSize) && view->parent) {
sizeHints.flags |= PBaseSize;
sizeHints.base_width = defaultSize.width;
sizeHints.base_height = defaultSize.height;
}
- const PuglViewSize minSize = view->sizeHints[PUGL_MIN_SIZE];
- if (puglIsValidSize(minSize)) {
+ const PuglArea minSize = view->sizeHints[PUGL_MIN_SIZE];
+ if (puglIsValidArea(minSize)) {
sizeHints.flags |= PMinSize;
sizeHints.min_width = minSize.width;
sizeHints.min_height = minSize.height;
}
- const PuglViewSize maxSize = view->sizeHints[PUGL_MAX_SIZE];
- if (puglIsValidSize(maxSize)) {
+ const PuglArea maxSize = view->sizeHints[PUGL_MAX_SIZE];
+ if (puglIsValidArea(maxSize)) {
sizeHints.flags |= PMaxSize;
sizeHints.max_width = maxSize.width;
sizeHints.max_height = maxSize.height;
}
- const PuglViewSize minAspect = view->sizeHints[PUGL_MIN_ASPECT];
- const PuglViewSize maxAspect = view->sizeHints[PUGL_MAX_ASPECT];
- if (puglIsValidSize(minAspect) && puglIsValidSize(maxAspect)) {
+ const PuglArea minAspect = view->sizeHints[PUGL_MIN_ASPECT];
+ const PuglArea maxAspect = view->sizeHints[PUGL_MAX_ASPECT];
+ if (puglIsValidArea(minAspect) && puglIsValidArea(maxAspect)) {
sizeHints.flags |= PAspect;
sizeHints.min_aspect.x = minAspect.width;
sizeHints.min_aspect.y = minAspect.height;
@@ -448,8 +450,8 @@ updateSizeHints(const PuglView* const view)
sizeHints.max_aspect.y = maxAspect.height;
}
- const PuglViewSize fixedAspect = view->sizeHints[PUGL_FIXED_ASPECT];
- if (puglIsValidSize(fixedAspect)) {
+ const PuglArea fixedAspect = view->sizeHints[PUGL_FIXED_ASPECT];
+ if (puglIsValidArea(fixedAspect)) {
sizeHints.flags |= PAspect;
sizeHints.min_aspect.x = fixedAspect.width;
sizeHints.min_aspect.y = fixedAspect.height;
@@ -513,48 +515,21 @@ clearX11Clipboard(PuglX11Clipboard* const board)
board->data.len = 0;
}
-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 (x >= INT16_MIN && x <= INT16_MAX && y >= INT16_MIN && y <= INT16_MAX) {
- // Use the default position set with puglSetPosition while unrealized
- const PuglRect frame = {
- (PuglCoord)x, (PuglCoord)y, defaultWidth, defaultHeight};
- return frame;
- }
+ Display* const display = view->world->impl->display;
+ const int screen = view->impl->screen;
+ XWindowAttributes ancestorAttrs = PUGL_INIT_STRUCT;
+ XGetWindowAttributes(display,
+ view->transientParent ? (Window)view->transientParent
+ : RootWindow(display, screen),
+ &ancestorAttrs);
- // Get the best "parentish" window to position the window in
- Display* const display = view->world->impl->display;
- const Window parent =
- (view->parent ? (Window)view->parent
- : view->transientParent ? (Window)view->transientParent
- : RootWindow(display, view->impl->screen));
-
- // Get the position/size of the parent as bounds for the new window
- XWindowAttributes parentAttrs = PUGL_INIT_STRUCT;
- XGetWindowAttributes(display, parent, &parentAttrs);
-
- // Center the frame within the parent bounds
- const int centerX = parentAttrs.x + parentAttrs.width / 2;
- const int centerY = parentAttrs.y + parentAttrs.height / 2;
- const PuglRect frame = {(PuglCoord)(centerX - (defaultWidth / 2)),
- (PuglCoord)(centerY - (defaultHeight / 2)),
- defaultWidth,
- defaultHeight};
- return frame;
+ const PuglPoint center = {
+ (PuglCoord)(ancestorAttrs.x + (ancestorAttrs.width / 2)),
+ (PuglCoord)(ancestorAttrs.y + (ancestorAttrs.height / 2))};
+ return center;
}
PuglStatus
@@ -609,16 +584,17 @@ puglRealize(PuglView* const view)
attr.event_mask |= StructureNotifyMask;
attr.event_mask |= VisibilityChangeMask;
- // Calculate the initial window rectangle
- const PuglRect initialFrame = getInitialFrame(view);
+ // Calculate the initial window frame
+ const PuglArea initialSize = puglGetInitialSize(view);
+ const PuglPoint initialPos = puglGetInitialPosition(view, initialSize);
// Create the window
impl->win = XCreateWindow(display,
parent,
- initialFrame.x,
- initialFrame.y,
- initialFrame.width,
- initialFrame.height,
+ initialPos.x,
+ initialPos.y,
+ initialSize.width,
+ initialSize.height,
0,
impl->vi->depth,
InputOutput,
@@ -650,7 +626,7 @@ puglRealize(PuglView* const view)
if (XRRQueryExtension(display, &ignored, &ignored)) {
// Set refresh rate hint to the real refresh rate
XRRScreenConfiguration* conf = XRRGetScreenInfo(display, parent);
- short current_rate = XRRConfigCurrentRate(conf);
+ const short current_rate = XRRConfigCurrentRate(conf);
view->hints[PUGL_REFRESH_RATE] = current_rate;
XRRFreeScreenConfigInfo(conf);
@@ -773,7 +749,7 @@ puglShow(PuglView* const view, const PuglShowCommand command)
}
if (view->stage == PUGL_VIEW_STAGE_CONFIGURED) {
- st = puglPostRedisplay(view);
+ st = puglObscureView(view);
}
}
@@ -817,13 +793,13 @@ keyInRange(const KeySym xSym,
const PuglKey puglMin)
{
return (xSym >= xMin && xSym <= xMax) ? (PuglKey)(puglMin + (xSym - xMin))
- : (PuglKey)0;
+ : PUGL_KEY_NONE;
}
static PuglKey
keySymToSpecial(const KeySym sym)
{
- PuglKey key = (PuglKey)0;
+ PuglKey key = PUGL_KEY_NONE;
if ((key = keyInRange(sym, XK_F1, XK_F12, PUGL_KEY_F1)) ||
(key = keyInRange(sym, XK_Page_Up, XK_End, PUGL_KEY_PAGE_UP)) ||
(key = keyInRange(sym, XK_Home, XK_Down, PUGL_KEY_HOME)) ||
@@ -856,7 +832,7 @@ keySymToSpecial(const KeySym sym)
}
// clang-format on
- return (PuglKey)0;
+ return PUGL_KEY_NONE;
}
static int
@@ -897,7 +873,8 @@ translateKey(PuglView* const view, XEvent* const xevent, PuglEvent* const event)
event->key.key = (PuglKey)puglDecodeUTF8((const uint8_t*)ustr);
}
- if (xevent->type == KeyPress && !filter && !special && view->impl->xic) {
+ if (xevent->type == KeyPress && !filter && !(special && ufound <= 0) &&
+ view->impl->xic) {
// Lookup shifted key for possible text event
xevent->xkey.state = state;
@@ -1028,7 +1005,7 @@ translateClientMessage(PuglView* const view, XClientMessageEvent message)
{
Display* const display = view->world->impl->display;
const PuglX11Atoms* const atoms = &view->world->impl->atoms;
- PuglEvent event = {{PUGL_NOTHING, 0}};
+ PuglEvent event = {{PUGL_NOTHING, 0U}};
if (message.message_type == atoms->WM_PROTOCOLS) {
const Atom protocol = (Atom)message.data.l[0];
@@ -1101,17 +1078,19 @@ getCurrentConfiguration(PuglView* const view)
XWindowAttributes attrs;
XGetWindowAttributes(display, view->impl->win, &attrs);
- // Get window position relative to the root window
+ // Get window position (relative to the root window if not a child)
Window ignoredChild = 0;
- int rootX = 0;
- int rootY = 0;
- XTranslateCoordinates(
- display, view->impl->win, attrs.root, 0, 0, &rootX, &rootY, &ignoredChild);
+ int x = attrs.x;
+ int y = attrs.y;
+ if (!view->parent) {
+ XTranslateCoordinates(
+ display, view->impl->win, attrs.root, 0, 0, &x, &y, &ignoredChild);
+ }
// Build a configure event based on the current window configuration
- PuglEvent configureEvent = {{PUGL_CONFIGURE, 0}};
- configureEvent.configure.x = (PuglCoord)rootX;
- configureEvent.configure.y = (PuglCoord)rootY;
+ PuglEvent configureEvent = {{PUGL_CONFIGURE, 0U}};
+ configureEvent.configure.x = (PuglCoord)x;
+ configureEvent.configure.y = (PuglCoord)y;
configureEvent.configure.width = (PuglSpan)attrs.width;
configureEvent.configure.height = (PuglSpan)attrs.height;
configureEvent.configure.style = getCurrentViewStyleFlags(view);
@@ -1140,7 +1119,7 @@ translatePropertyNotify(PuglView* const view, XPropertyEvent message)
{
const PuglInternals* const impl = view->impl;
const PuglX11Atoms* const atoms = &view->world->impl->atoms;
- PuglEvent event = {{PUGL_NOTHING, 0}};
+ PuglEvent event = {{PUGL_NOTHING, 0U}};
if (message.atom == atoms->NET_WM_STATE) {
// Get all the current states set in the window hints
@@ -1190,7 +1169,7 @@ translatePropertyNotify(PuglView* const view, XPropertyEvent message)
static PuglEvent
translateEvent(PuglView* const view, XEvent xevent)
{
- PuglEvent event = {{PUGL_NOTHING, 0}};
+ PuglEvent event = {{PUGL_NOTHING, 0U}};
event.any.flags = xevent.xany.send_event ? PUGL_IS_SEND_EVENT : 0;
switch (xevent.type) {
@@ -1211,6 +1190,9 @@ translateEvent(PuglView* const view, XEvent xevent)
view->impl->mapped = false;
event = makeConfigureEvent(view);
break;
+ case DestroyNotify:
+ view->impl->win = None;
+ break;
case ConfigureNotify:
event = makeConfigureEvent(view);
event.configure.width = (PuglSpan)xevent.xconfigure.width;
@@ -1534,21 +1516,11 @@ puglSendEvent(PuglView* const view, const PuglEvent* const event)
return PUGL_UNSUPPORTED;
}
-#ifndef PUGL_DISABLE_DEPRECATED
-PuglStatus
-puglWaitForEvent(PuglView* const view)
-{
- XEvent xevent;
- XPeekEvent(view->world->impl->display, &xevent);
- return PUGL_SUCCESS;
-}
-#endif
-
static void
mergeExposeEvents(PuglExposeEvent* const dst, const PuglExposeEvent* const src)
{
if (!dst->type) {
- if (src->width > 0.0 && src->height > 0.0) {
+ if (src->width && src->height) {
*dst = *src;
}
} else {
@@ -1612,7 +1584,7 @@ handleSelectionNotify(const PuglWorld* const world,
Display* const display = view->world->impl->display;
const Atom selection = event->selection;
PuglX11Clipboard* const board = getX11SelectionClipboard(view, selection);
- PuglEvent puglEvent = {{PUGL_NOTHING, 0}};
+ PuglEvent puglEvent = {{PUGL_NOTHING, 0U}};
if (event->target == atoms->TARGETS) {
// Notification of available datatypes
@@ -1622,7 +1594,7 @@ handleSelectionNotify(const PuglWorld* const world,
view, event->requestor, event->property, &numFormats, &formats) &&
!setClipboardFormats(view, board, numFormats, formats)) {
const PuglDataOfferEvent offer = {
- PUGL_DATA_OFFER, 0, (double)event->time / 1e3};
+ PUGL_DATA_OFFER, 0U, (double)event->time / 1e3};
puglEvent.offer = offer;
board->acceptedFormatIndex = UINT32_MAX;
@@ -1699,8 +1671,7 @@ handleSelectionRequest(const PuglWorld* const world,
}
/// Flush pending configure and expose events for all views
-PUGL_WARN_UNUSED_RESULT
-static PuglStatus
+PUGL_WARN_UNUSED_RESULT static PuglStatus
flushExposures(PuglWorld* const world)
{
PuglStatus st0 = PUGL_SUCCESS;
@@ -1753,7 +1724,7 @@ handleTimerEvent(PuglWorld* const world, const XEvent xevent)
for (size_t i = 0; i < world->impl->numTimers; ++i) {
if (world->impl->timers[i].alarm == notify->alarm) {
- PuglEvent event = {{PUGL_TIMER, 0}};
+ PuglEvent event = {{PUGL_TIMER, 0U}};
event.timer.id = world->impl->timers[i].id;
puglDispatchEvent(world->impl->timers[i].view, &event);
}
@@ -1851,14 +1822,6 @@ dispatchX11Events(PuglWorld* const world)
return st;
}
-#ifndef PUGL_DISABLE_DEPRECATED
-PuglStatus
-puglProcessEvents(PuglView* const view)
-{
- return puglUpdate(view->world, 0.0);
-}
-#endif
-
PuglStatus
puglUpdate(PuglWorld* const world, const double timeout)
{
@@ -1869,8 +1832,9 @@ puglUpdate(PuglWorld* const world, const double timeout)
world->impl->dispatchingEvents = true;
if (timeout < 0.0) {
- st0 = pollX11Socket(world, timeout);
- st0 = st0 ? st0 : dispatchX11Events(world);
+ if (!(st0 = pollX11Socket(world, timeout))) {
+ st0 = dispatchX11Events(world);
+ }
} else if (timeout <= 0.001) {
st0 = dispatchX11Events(world);
} else {
@@ -1896,33 +1860,45 @@ double
puglGetTime(const PuglWorld* const world)
{
struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
+ if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
+ return 0.0;
+ }
+
return ((double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0) -
world->startTime;
}
PuglStatus
-puglPostRedisplay(PuglView* const view)
+puglObscureView(PuglView* const view)
{
- PuglRect rect = puglGetFrame(view);
- rect.x = 0;
- rect.y = 0;
-
- return puglPostRedisplayRect(view, rect);
+ return puglObscureRegion(
+ view, 0, 0, view->lastConfigure.width, view->lastConfigure.height);
}
PuglStatus
-puglPostRedisplayRect(PuglView* const view, const PuglRect rect)
+puglObscureRegion(PuglView* const view,
+ const int x,
+ const int y,
+ const unsigned width,
+ const unsigned height)
{
- const PuglExposeEvent event = {
- PUGL_EXPOSE, 0, rect.x, rect.y, rect.width, rect.height};
+ if (!puglIsValidPosition(x, y) || !puglIsValidSize(width, height)) {
+ return PUGL_BAD_PARAMETER;
+ }
+
+ const PuglCoord cx = MAX((PuglCoord)0, (PuglCoord)x);
+ const PuglCoord cy = MAX((PuglCoord)0, (PuglCoord)y);
+ const PuglSpan cw = MIN(view->lastConfigure.width, (PuglSpan)width);
+ const PuglSpan ch = MIN(view->lastConfigure.height, (PuglSpan)height);
+
+ const PuglExposeEvent event = {PUGL_EXPOSE, 0U, cx, cy, cw, ch};
if (view->world->impl->dispatchingEvents) {
// Currently dispatching events, add/expand expose for the loop end
mergeExposeEvents(&view->impl->pendingExpose.expose, &event);
} else if (view->impl->win) {
// Not dispatching events, send an X expose so we wake up next time
- PuglEvent exposeEvent = {{PUGL_EXPOSE, 0}};
+ PuglEvent exposeEvent = {{PUGL_EXPOSE, 0U}};
exposeEvent.expose = event;
return puglSendEvent(view, &exposeEvent);
}
@@ -1976,80 +1952,54 @@ puglGetScaleFactor(const PuglView* const view)
return view->world->impl->scaleFactor;
}
-PuglStatus
-puglSetFrame(PuglView* const view, const PuglRect frame)
-{
- if (!view->impl->win) {
- // Set defaults to be used when realized
- view->defaultX = frame.x;
- view->defaultY = frame.y;
- view->sizeHints[PUGL_DEFAULT_SIZE].width = frame.width;
- view->sizeHints[PUGL_DEFAULT_SIZE].height = frame.height;
- return PUGL_SUCCESS;
- }
-
- return puglX11Status(XMoveResizeWindow(view->world->impl->display,
- view->impl->win,
- frame.x,
- frame.y,
- frame.width,
- frame.height));
-}
-
-PuglStatus
-puglSetPosition(PuglView* const view, const int x, const int y)
+static PuglStatus
+puglSetWindowPosition(PuglView* const view, const int x, const int y)
{
- Display* const display = view->world->impl->display;
-
- if (x < INT16_MIN || x > INT16_MAX || y < INT16_MIN || y > INT16_MAX) {
- return PUGL_BAD_PARAMETER;
- }
-
- if (!view->impl->win) {
- // Set defaults to be used when realized
- view->defaultX = x;
- view->defaultY = y;
- return PUGL_SUCCESS;
- }
-
- return puglX11Status(XMoveWindow(display,
+ return puglX11Status(XMoveWindow(view->world->impl->display,
view->impl->win,
(int)(x - view->impl->frameExtentLeft),
(int)(y - view->impl->frameExtentTop)));
}
-PuglStatus
-puglSetSize(PuglView* const view, const unsigned width, const unsigned height)
+static PuglStatus
+puglSetWindowSize(PuglView* const view,
+ const unsigned width,
+ const unsigned height)
{
- Display* const display = view->world->impl->display;
+ return !view->impl->win
+ ? PUGL_SUCCESS
+ : puglX11Status(XResizeWindow(
+ view->world->impl->display, view->impl->win, width, height));
+}
- if (width > INT16_MAX || height > INT16_MAX) {
+PuglStatus
+puglSetPositionHint(PuglView* const view,
+ const PuglPositionHint hint,
+ const int x,
+ const int y)
+{
+ if (x <= INT16_MIN || x > INT16_MAX || y <= INT16_MIN || y > INT16_MAX) {
return PUGL_BAD_PARAMETER;
}
- if (!view->impl->win) {
- // Set defaults to be used when realized
- view->sizeHints[PUGL_DEFAULT_SIZE].width = (PuglSpan)width;
- view->sizeHints[PUGL_DEFAULT_SIZE].height = (PuglSpan)height;
- return PUGL_SUCCESS;
- }
+ view->positionHints[hint].x = (PuglCoord)x;
+ view->positionHints[hint].y = (PuglCoord)y;
- return puglX11Status(XResizeWindow(display, view->impl->win, width, height));
+ return (hint == PUGL_CURRENT_POSITION) ? puglSetWindowPosition(view, x, y)
+ : PUGL_SUCCESS;
}
PuglStatus
puglSetSizeHint(PuglView* const view,
const PuglSizeHint hint,
- const PuglSpan width,
- const PuglSpan height)
+ const unsigned width,
+ const unsigned height)
{
- if ((unsigned)hint >= PUGL_NUM_SIZE_HINTS) {
- return PUGL_BAD_PARAMETER;
- }
+ const PuglStatus st = puglStoreSizeHint(view, hint, width, height);
- view->sizeHints[hint].width = width;
- view->sizeHints[hint].height = height;
- return updateSizeHints(view);
+ return st ? st
+ : (hint == PUGL_CURRENT_SIZE) ? puglSetWindowSize(view, width, height)
+ : updateSizeHints(view);
}
PuglStatus
diff --git a/src/x11.h b/src/x11.h
index bc93630..da9b4f6 100644
--- a/src/x11.h
+++ b/src/x11.h
@@ -7,8 +7,8 @@
#include "attributes.h"
#include "types.h"
-#include "pugl/attributes.h"
-#include "pugl/pugl.h"
+#include <pugl/attributes.h>
+#include <pugl/pugl.h>
#include <X11/X.h>
#include <X11/Xlib.h>
@@ -93,9 +93,7 @@ struct PuglInternalsImpl {
bool mapped;
};
-PUGL_WARN_UNUSED_RESULT
-PUGL_API
-PuglStatus
+PUGL_WARN_UNUSED_RESULT PUGL_API PuglStatus
puglX11Configure(PuglView* view);
#endif // PUGL_SRC_X11_H
diff --git a/src/x11_cairo.c b/src/x11_cairo.c
index d6fbaec..bc7b133 100644
--- a/src/x11_cairo.c
+++ b/src/x11_cairo.c
@@ -5,8 +5,8 @@
#include "types.h"
#include "x11.h"
-#include "pugl/cairo.h"
-#include "pugl/pugl.h"
+#include <pugl/cairo.h>
+#include <pugl/pugl.h>
#include <cairo-xlib.h>
#include <cairo.h>
@@ -19,10 +19,10 @@ typedef struct {
cairo_t* cr;
} PuglX11CairoSurface;
-static PuglViewSize
+static PuglArea
puglX11CairoGetViewSize(const PuglView* const view)
{
- PuglViewSize size = {0U, 0U};
+ PuglArea size = {0U, 0U};
if (view->lastConfigure.type == PUGL_CONFIGURE) {
// Use the size of the last configured frame
@@ -97,11 +97,11 @@ puglX11CairoEnter(PuglView* view, const PuglExposeEvent* expose)
PuglStatus st = PUGL_SUCCESS;
if (expose) {
- const PuglViewSize viewSize = puglX11CairoGetViewSize(view);
- const PuglSpan right = (PuglSpan)(expose->x + expose->width);
- const PuglSpan bottom = (PuglSpan)(expose->y + expose->height);
- const PuglSpan surfaceWidth = MAX(right, viewSize.width);
- const PuglSpan surfaceHeight = MAX(bottom, viewSize.height);
+ const PuglArea viewSize = puglX11CairoGetViewSize(view);
+ const PuglSpan right = (PuglSpan)(expose->x + expose->width);
+ const PuglSpan bottom = (PuglSpan)(expose->y + expose->height);
+ const PuglSpan surfaceWidth = MAX(right, viewSize.width);
+ const PuglSpan surfaceHeight = MAX(bottom, viewSize.height);
if (!(st = puglX11CairoOpen(view, surfaceWidth, surfaceHeight))) {
surface->cr = cairo_create(surface->front);
if (cairo_status(surface->cr)) {
diff --git a/src/x11_gl.c b/src/x11_gl.c
index de22b34..527335b 100644
--- a/src/x11_gl.c
+++ b/src/x11_gl.c
@@ -6,8 +6,8 @@
#include "types.h"
#include "x11.h"
-#include "pugl/gl.h"
-#include "pugl/pugl.h"
+#include <pugl/gl.h>
+#include <pugl/pugl.h>
#include <GL/glx.h>
#include <X11/X.h>
@@ -101,8 +101,7 @@ puglX11GlConfigure(PuglView* view)
return PUGL_SUCCESS;
}
-PUGL_WARN_UNUSED_RESULT
-static PuglStatus
+PUGL_WARN_UNUSED_RESULT static PuglStatus
puglX11GlEnter(PuglView* view, const PuglExposeEvent* PUGL_UNUSED(expose))
{
PuglX11GlSurface* surface = (PuglX11GlSurface*)view->impl->surface;
@@ -115,8 +114,7 @@ puglX11GlEnter(PuglView* view, const PuglExposeEvent* PUGL_UNUSED(expose))
: PUGL_FAILURE;
}
-PUGL_WARN_UNUSED_RESULT
-static PuglStatus
+PUGL_WARN_UNUSED_RESULT static PuglStatus
puglX11GlLeave(PuglView* view, const PuglExposeEvent* expose)
{
Display* const display = view->world->impl->display;
diff --git a/src/x11_stub.c b/src/x11_stub.c
index 844b4db..11143fe 100644
--- a/src/x11_stub.c
+++ b/src/x11_stub.c
@@ -1,13 +1,13 @@
// Copyright 2012-2021 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
-#include "pugl/stub.h"
+#include <pugl/stub.h>
#include "stub.h"
#include "types.h"
#include "x11.h"
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
const PuglBackend*
puglStubBackend(void)
diff --git a/src/x11_vulkan.c b/src/x11_vulkan.c
index 834ac37..078e524 100644
--- a/src/x11_vulkan.c
+++ b/src/x11_vulkan.c
@@ -8,8 +8,8 @@
#include "types.h"
#include "x11.h"
-#include "pugl/pugl.h"
-#include "pugl/vulkan.h"
+#include <pugl/pugl.h>
+#include <pugl/vulkan.h>
#include <vulkan/vulkan_core.h>
#include <vulkan/vulkan_xlib.h>