aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-format17
-rw-r--r--README.md6
-rw-r--r--bindings/cpp/include/pugl/cairo.hpp4
-rw-r--r--bindings/cpp/include/pugl/gl.hpp6
-rw-r--r--bindings/cpp/include/pugl/pugl.hpp48
-rw-r--r--bindings/cpp/include/pugl/stub.hpp4
-rw-r--r--bindings/cpp/include/pugl/vulkan.hpp6
-rw-r--r--bindings/cpp/meson.build2
-rw-r--r--bindings/cpp/test/headers/meson.build1
-rw-r--r--doc/c/Doxyfile.in1
-rw-r--r--doc/cpp/Doxyfile.in1
-rw-r--r--examples/.clang-tidy1
-rw-r--r--examples/cube_view.h4
-rw-r--r--examples/demo_utils.h2
-rw-r--r--examples/glad/.clang-format6
-rw-r--r--examples/meson.build33
-rw-r--r--examples/pugl_cairo_demo.app/MacOS/meson.build4
-rw-r--r--examples/pugl_cairo_demo.c19
-rw-r--r--examples/pugl_clipboard_demo.app/MacOS/meson.build4
-rw-r--r--examples/pugl_clipboard_demo.c11
-rw-r--r--examples/pugl_cpp_demo.app/MacOS/meson.build4
-rw-r--r--examples/pugl_cpp_demo.cpp12
-rw-r--r--examples/pugl_cursor_demo.app/MacOS/meson.build4
-rw-r--r--examples/pugl_cursor_demo.c16
-rw-r--r--examples/pugl_embed_demo.app/MacOS/meson.build4
-rw-r--r--examples/pugl_embed_demo.c61
-rw-r--r--examples/pugl_management_demo.app/MacOS/meson.build4
-rw-r--r--examples/pugl_management_demo.c39
-rw-r--r--examples/pugl_print_events.c6
-rw-r--r--examples/pugl_shader_demo.app/MacOS/meson.build4
-rw-r--r--examples/pugl_shader_demo.c39
-rw-r--r--examples/pugl_vulkan_cpp_demo.app/MacOS/meson.build4
-rw-r--r--examples/pugl_vulkan_cpp_demo.cpp20
-rw-r--r--examples/pugl_vulkan_demo.app/MacOS/meson.build4
-rw-r--r--examples/pugl_vulkan_demo.c7
-rw-r--r--examples/pugl_window_demo.app/MacOS/meson.build4
-rw-r--r--examples/pugl_window_demo.c37
-rw-r--r--include/pugl/attributes.h19
-rw-r--r--include/pugl/cairo.h7
-rw-r--r--include/pugl/gl.h16
-rw-r--r--include/pugl/pugl.h1017
-rw-r--r--include/pugl/stub.h7
-rw-r--r--include/pugl/vulkan.h25
-rw-r--r--meson.build37
-rw-r--r--meson_options.txt11
-rw-r--r--src/common.c111
-rw-r--r--src/internal.c12
-rw-r--r--src/internal.h8
-rw-r--r--src/mac.h2
-rw-r--r--src/mac.m214
-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.h31
-rw-r--r--src/win.c232
-rw-r--r--src/win.h21
-rw-r--r--src/win_cairo.c2
-rw-r--r--src/win_gl.c2
-rw-r--r--src/win_stub.c2
-rw-r--r--src/win_vulkan.c2
-rw-r--r--src/x11.c148
-rw-r--r--src/x11.h8
-rw-r--r--src/x11_cairo.c4
-rw-r--r--src/x11_gl.c10
-rw-r--r--src/x11_stub.c4
-rw-r--r--src/x11_vulkan.c4
-rw-r--r--subprojects/puglutil/include/puglutil/test_utils.h (renamed from test/test_utils.h)2
-rw-r--r--subprojects/puglutil/meson.build14
-rw-r--r--test/.clang-tidy1
-rw-r--r--test/cpp/.clang-tidy1
-rw-r--r--test/cpp/meson.build2
-rw-r--r--test/cpp/test_build.cpp16
-rw-r--r--test/cpp/test_inline_cpp.cpp26
-rw-r--r--test/cpp/test_inline_objcpp.mm16
-rw-r--r--test/headers/meson.build3
-rw-r--r--test/meson.build31
-rw-r--r--test/test_build.c16
-rw-r--r--test/test_cairo.c8
-rw-r--r--test/test_clipboard.c4
-rw-r--r--test/test_cursor.c8
-rw-r--r--test/test_gl.c8
-rw-r--r--test/test_gl_free_unrealized.c6
-rw-r--r--test/test_gl_hints.c12
-rw-r--r--test/test_local_copy_paste.c8
-rw-r--r--test/test_realize.c8
-rw-r--r--test/test_redisplay.c10
-rw-r--r--test/test_remote_copy_paste.c10
-rw-r--r--test/test_show_hide.c8
-rw-r--r--test/test_size.c41
-rw-r--r--test/test_strerror.c2
-rw-r--r--test/test_stub.c8
-rw-r--r--test/test_stub_hints.c12
-rw-r--r--test/test_timer.c8
-rw-r--r--test/test_update.c8
-rw-r--r--test/test_view.c8
-rw-r--r--test/test_vulkan.c8
-rw-r--r--test/test_world.c2
100 files changed, 1023 insertions, 1719 deletions
diff --git a/.clang-format b/.clang-format
index 26ada71..299c8a2 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,10 +1,17 @@
-# Copyright 2020-2022 David Robillard <d@drobilla.net>
+# Copyright 2020-2025 David Robillard <d@drobilla.net>
# SPDX-License-Identifier: 0BSD OR ISC
---
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
-AlignEscapedNewlinesLeft: true
+AlignEscapedNewlines: Left
+AttributeMacros:
+ - PUGL_API
+ - PUGL_CONST_API
+ - PUGL_CONST_FUNC
+ - PUGL_MALLOC_API
+ - PUGL_MALLOC_FUNC
+ - PUGL_WARN_UNUSED_RESULT
BasedOnStyle: Mozilla
BraceWrapping:
AfterNamespace: false
@@ -22,11 +29,5 @@ IndentPPDirectives: AfterHash
KeepEmptyLinesAtTheStartOfBlocks: false
SpacesInContainerLiterals: false
StatementMacros:
- - PUGL_API
- - PUGL_CONST_API
- - PUGL_CONST_FUNC
- - PUGL_DEPRECATED_BY
- PUGL_UNUSED
- - PUGL_WARN_UNUSED_RESULT
- - _Pragma
...
diff --git a/README.md b/README.md
index f8e9aba..839c52a 100644
--- a/README.md
+++ b/README.md
@@ -39,11 +39,7 @@ Stability
Pugl is currently being developed towards a long-term stable API. For the time
being, however, the API may break occasionally. Please report any relevant
feedback, or file feature requests, so that we can ensure that the released API
-is stable for as long as possible.
-
-When the API changes, backwards compatibility is maintained where possible.
-These compatibility shims will be removed before release, so users are
-encouraged to build with `PUGL_DISABLE_DEPRECATED` defined.
+will be stable for as long as possible.
Documentation
-------------
diff --git a/bindings/cpp/include/pugl/cairo.hpp b/bindings/cpp/include/pugl/cairo.hpp
index e619412..4a51f96 100644
--- a/bindings/cpp/include/pugl/cairo.hpp
+++ b/bindings/cpp/include/pugl/cairo.hpp
@@ -4,8 +4,8 @@
#ifndef PUGL_CAIRO_HPP
#define PUGL_CAIRO_HPP
-#include "pugl/cairo.h"
-#include "pugl/pugl.h"
+#include <pugl/cairo.h>
+#include <pugl/pugl.h>
namespace pugl {
diff --git a/bindings/cpp/include/pugl/gl.hpp b/bindings/cpp/include/pugl/gl.hpp
index 7c361e6..5aa5ca5 100644
--- a/bindings/cpp/include/pugl/gl.hpp
+++ b/bindings/cpp/include/pugl/gl.hpp
@@ -4,9 +4,9 @@
#ifndef PUGL_GL_HPP
#define PUGL_GL_HPP
-#include "pugl/gl.h"
-#include "pugl/pugl.h"
-#include "pugl/pugl.hpp"
+#include <pugl/gl.h>
+#include <pugl/pugl.h>
+#include <pugl/pugl.hpp>
namespace pugl {
diff --git a/bindings/cpp/include/pugl/pugl.hpp b/bindings/cpp/include/pugl/pugl.hpp
index bf87ed3..eba2583 100644
--- a/bindings/cpp/include/pugl/pugl.hpp
+++ b/bindings/cpp/include/pugl/pugl.hpp
@@ -4,10 +4,10 @@
#ifndef PUGL_PUGL_HPP
#define PUGL_PUGL_HPP
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
-#include <cstddef> // IWYU pragma: keep
-#include <cstdint> // IWYU pragma: keep
+#include <cstddef>
+#include <cstdint>
#if defined(PUGL_HPP_THROW_FAILED_CONSTRUCTION)
# include <exception>
@@ -66,8 +66,17 @@ private:
} // namespace detail
-/// @copydoc PuglRect
-using Rect = PuglRect;
+/// @copydoc PuglCoord
+using Coord = PuglCoord;
+
+/// @copydoc PuglSpan
+using Span = PuglSpan;
+
+/// @copydoc PuglPoint
+using Point = PuglPoint;
+
+/// @copydoc PuglArea
+using Area = PuglArea;
/// @copydoc PuglStringHint
enum class StringHint {
@@ -227,6 +236,7 @@ enum class Status {
setFormatFailed, ///< @copydoc PUGL_SET_FORMAT_FAILED
createContextFailed, ///< @copydoc PUGL_CREATE_CONTEXT_FAILED
unsupported, ///< @copydoc PUGL_UNSUPPORTED
+ noMemory, ///< @copydoc PUGL_NO_MEMORY
};
static_assert(static_cast<Status>(PUGL_UNSUPPORTED) == Status::unsupported, "");
@@ -370,11 +380,19 @@ using Backend = PuglBackend;
/// @copydoc PuglNativeView
using NativeView = PuglNativeView;
+/// @copydoc PuglPositionHint
+enum class PositionHint {
+ defaultPosition, ///< @copydoc PUGL_DEFAULT_POSITION
+ currentPosition, ///< @copydoc PUGL_CURRENT_POSITION
+};
+
/// @copydoc PuglSizeHint
enum class SizeHint {
defaultSize, ///< @copydoc PUGL_DEFAULT_SIZE
+ currentSize, ///< @copydoc PUGL_CURRENT_SIZE
minSize, ///< @copydoc PUGL_MIN_SIZE
maxSize, ///< @copydoc PUGL_MAX_SIZE
+ fixedAspect, ///< @copydoc PUGL_FIXED_ASPECT
minAspect, ///< @copydoc PUGL_MIN_ASPECT
maxAspect, ///< @copydoc PUGL_MAX_ASPECT
};
@@ -535,13 +553,23 @@ public:
@{
*/
- /// @copydoc puglGetFrame
- Rect frame() const noexcept { return puglGetFrame(cobj()); }
+ /// @copydoc puglGetPositionHint
+ Point position(PositionHint hint) const noexcept
+ {
+ return puglGetPositionHint(cobj(), static_cast<PuglPositionHint>(hint));
+ }
+
+ /// @copydoc puglGetSizeHint
+ Area size(SizeHint hint) const noexcept
+ {
+ return puglGetSizeHint(cobj(), static_cast<PuglSizeHint>(hint));
+ }
- /// @copydoc puglSetFrame
- Status setFrame(const Rect& frame) noexcept
+ /// @copydoc puglSetSizeHint
+ Status setSize(unsigned width, unsigned height) noexcept
{
- return static_cast<Status>(puglSetFrame(cobj(), frame));
+ return static_cast<Status>(
+ puglSetSizeHint(cobj(), PUGL_CURRENT_SIZE, width, height));
}
/// @copydoc puglSetSizeHint
diff --git a/bindings/cpp/include/pugl/stub.hpp b/bindings/cpp/include/pugl/stub.hpp
index 08281b0..13b050d 100644
--- a/bindings/cpp/include/pugl/stub.hpp
+++ b/bindings/cpp/include/pugl/stub.hpp
@@ -4,8 +4,8 @@
#ifndef PUGL_STUB_HPP
#define PUGL_STUB_HPP
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
namespace pugl {
diff --git a/bindings/cpp/include/pugl/vulkan.hpp b/bindings/cpp/include/pugl/vulkan.hpp
index 5bb790d..56c91b0 100644
--- a/bindings/cpp/include/pugl/vulkan.hpp
+++ b/bindings/cpp/include/pugl/vulkan.hpp
@@ -10,9 +10,9 @@
#ifndef PUGL_VULKAN_HPP
#define PUGL_VULKAN_HPP
-#include "pugl/pugl.h"
-#include "pugl/pugl.hpp"
-#include "pugl/vulkan.h"
+#include <pugl/pugl.h>
+#include <pugl/pugl.hpp>
+#include <pugl/vulkan.h>
#include <vulkan/vulkan_core.h>
diff --git a/bindings/cpp/meson.build b/bindings/cpp/meson.build
index 3e55c71..0e8ba6a 100644
--- a/bindings/cpp/meson.build
+++ b/bindings/cpp/meson.build
@@ -8,7 +8,7 @@
subdir('include')
puglpp_dep = declare_dependency(
- dependencies: core_deps + [pugl_dep],
+ dependencies: [pugl_dep],
include_directories: include_directories('include'),
link_with: libpugl,
)
diff --git a/bindings/cpp/test/headers/meson.build b/bindings/cpp/test/headers/meson.build
index 0100853..064c2cf 100644
--- a/bindings/cpp/test/headers/meson.build
+++ b/bindings/cpp/test/headers/meson.build
@@ -33,6 +33,7 @@ test(
files('test_headers.cpp'),
cpp_args: test_headers_cpp_args,
dependencies: [puglpp_dep, vulkan_dep],
+ implicit_include_directories: false,
),
suite: 'unit',
)
diff --git a/doc/c/Doxyfile.in b/doc/c/Doxyfile.in
index 4bf1b42..f6990af 100644
--- a/doc/c/Doxyfile.in
+++ b/doc/c/Doxyfile.in
@@ -26,7 +26,6 @@ MACRO_EXPANSION = YES
PREDEFINED = PUGL_API \
PUGL_CONST_API= \
PUGL_CONST_FUNC= \
- PUGL_DISABLE_DEPRECATED \
PUGL_MALLOC_API= \
PUGL_MALLOC_FUNC=
diff --git a/doc/cpp/Doxyfile.in b/doc/cpp/Doxyfile.in
index 05deae7..3d0d45f 100644
--- a/doc/cpp/Doxyfile.in
+++ b/doc/cpp/Doxyfile.in
@@ -31,7 +31,6 @@ MACRO_EXPANSION = YES
PREDEFINED = PUGL_API \
PUGL_CONST_API= \
PUGL_CONST_FUNC= \
- PUGL_DISABLE_DEPRECATED \
PUGL_MALLOC_API= \
PUGL_MALLOC_FUNC=
diff --git a/examples/.clang-tidy b/examples/.clang-tidy
index c9cacb3..bc26cde 100644
--- a/examples/.clang-tidy
+++ b/examples/.clang-tidy
@@ -6,6 +6,7 @@ Checks: >
-*-non-private-member-variables-in-classes,
-*avoid-c-arrays,
-android-cloexec-fopen,
+ -boost-*,
-bugprone-easily-swappable-parameters,
-bugprone-macro-parentheses,
-bugprone-multi-level-implicit-pointer-conversion,
diff --git a/examples/cube_view.h b/examples/cube_view.h
index 6941870..a02154f 100644
--- a/examples/cube_view.h
+++ b/examples/cube_view.h
@@ -8,8 +8,8 @@
#include "demo_utils.h"
-#include "pugl/gl.h"
-#include "pugl/pugl.h"
+#include <pugl/gl.h>
+#include <pugl/pugl.h>
#include <stdbool.h>
diff --git a/examples/demo_utils.h b/examples/demo_utils.h
index da3b2cd..db66b21 100644
--- a/examples/demo_utils.h
+++ b/examples/demo_utils.h
@@ -4,7 +4,7 @@
#ifndef EXAMPLES_DEMO_UTILS_H
#define EXAMPLES_DEMO_UTILS_H
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#include <math.h>
#include <stdio.h>
diff --git a/examples/glad/.clang-format b/examples/glad/.clang-format
new file mode 100644
index 0000000..f219d75
--- /dev/null
+++ b/examples/glad/.clang-format
@@ -0,0 +1,6 @@
+# Copyright 2025 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+---
+DisableFormat: true
+...
diff --git a/examples/meson.build b/examples/meson.build
index 0c4f998..65daa31 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -1,4 +1,4 @@
-# Copyright 2021-2023 David Robillard <d@drobilla.net>
+# Copyright 2021-2025 David Robillard <d@drobilla.net>
# SPDX-License-Identifier: 0BSD OR ISC
data_dir = get_option('prefix') / get_option('datadir') / 'pugl-0'
@@ -27,12 +27,6 @@ vulkan_examples = [
'pugl_vulkan_demo.c',
]
-includes = include_directories(
- '..',
- '../bindings/cpp/include',
- '../include',
-)
-
# Suppress some additional C warnings in examples
example_c_args = []
if get_option('warning_level') == 'everything'
@@ -120,7 +114,7 @@ else
foreach example : stub_examples
source = [example]
target = example.split('.')[0]
- dependencies = [pugl_dep, pugl_stub_dep]
+ dependencies = [pugl_dep, pugl_stub_dep, puglutil_dep]
defines = []
executable(
@@ -129,7 +123,7 @@ else
c_args: example_defines + example_c_args + defines,
cpp_args: example_defines + example_cpp_args + defines,
dependencies: dependencies,
- include_directories: includes,
+ implicit_include_directories: false,
)
endforeach
@@ -138,7 +132,7 @@ else
foreach example : gl_examples
source = [example]
target = example.split('.')[0]
- dependencies = [pugl_dep, pugl_gl_dep]
+ dependencies = [pugl_dep, pugl_gl_dep, puglutil_dep]
defines = []
if target == 'pugl_shader_demo'
@@ -148,6 +142,10 @@ else
elif target == 'pugl_print_events'
dependencies += [pugl_stub_dep]
elif target == 'pugl_cpp_demo'
+ if not is_variable('puglpp_dep')
+ continue
+ endif
+
dependencies += [puglpp_dep]
endif
@@ -157,7 +155,7 @@ else
c_args: example_defines + example_c_args + defines,
cpp_args: example_defines + example_cpp_args + defines,
dependencies: dependencies,
- include_directories: includes,
+ implicit_include_directories: false,
)
endforeach
endif
@@ -170,8 +168,8 @@ else
target,
example,
c_args: example_defines + example_c_args + cairo_args,
- dependencies: [pugl_dep, pugl_cairo_dep],
- include_directories: includes,
+ dependencies: [pugl_dep, pugl_cairo_dep, puglutil_dep],
+ implicit_include_directories: false,
)
endforeach
endif
@@ -181,12 +179,17 @@ else
foreach example : vulkan_examples
source = [example]
target = example.split('.')[0]
- dependencies = [dl_dep, pugl_vulkan_dep]
+ dependencies = [dl_dep, pugl_vulkan_dep, puglutil_dep]
defines = []
if target == 'pugl_vulkan_cpp_demo'
+ if not is_variable('puglpp_dep')
+ continue
+ endif
+
source += ['file_utils.c']
defines += ['-D_POSIX_C_SOURCE=200809L']
+ dependencies += [puglpp_dep]
endif
executable(
@@ -195,7 +198,7 @@ else
c_args: example_defines + example_c_args + defines,
cpp_args: example_defines + example_cpp_args + defines,
dependencies: dependencies,
- include_directories: includes,
+ implicit_include_directories: false,
)
endforeach
endif
diff --git a/examples/pugl_cairo_demo.app/MacOS/meson.build b/examples/pugl_cairo_demo.app/MacOS/meson.build
index 18e1fcf..e8a5242 100644
--- a/examples/pugl_cairo_demo.app/MacOS/meson.build
+++ b/examples/pugl_cairo_demo.app/MacOS/meson.build
@@ -6,6 +6,6 @@ executable(
['../../pugl_cairo_demo.c'],
c_args: example_defines + example_c_args + cairo_args,
cpp_args: example_defines + example_cpp_args,
- dependencies: [pugl_dep, pugl_cairo_dep],
- include_directories: include_directories('../../..'),
+ dependencies: [pugl_dep, pugl_cairo_dep, puglutil_dep],
+ implicit_include_directories: false,
)
diff --git a/examples/pugl_cairo_demo.c b/examples/pugl_cairo_demo.c
index d973d69..109149d 100644
--- a/examples/pugl_cairo_demo.c
+++ b/examples/pugl_cairo_demo.c
@@ -2,10 +2,11 @@
// SPDX-License-Identifier: ISC
#include "demo_utils.h"
-#include "test/test_utils.h"
-#include "pugl/cairo.h"
-#include "pugl/pugl.h"
+#include <puglutil/test_utils.h>
+
+#include <pugl/cairo.h>
+#include <pugl/pugl.h>
#include <cairo.h>
@@ -49,9 +50,9 @@ static const Button buttons[] = {{128, 128, 64, 64, "1"},
static ViewScale
getScale(const PuglView* const view)
{
- const PuglRect frame = puglGetFrame(view);
- const ViewScale scale = {(frame.width - (512.0 / frame.width)) / 512.0,
- (frame.height - (512.0 / frame.height)) / 512.0};
+ const PuglArea size = puglGetSizeHint(view, PUGL_CURRENT_SIZE);
+ const ViewScale scale = {(size.width - (512.0 / size.width)) / 512.0,
+ (size.height - (512.0 / size.height)) / 512.0};
return scale;
}
@@ -100,8 +101,8 @@ buttonDraw(PuglTestApp* app, cairo_t* cr, const Button* but, const double time)
cairo_set_font_size(cr, 32.0);
cairo_text_extents(cr, but->label, &extents);
cairo_move_to(cr,
- (but->w / 2.0) - extents.width / 2,
- (but->h / 2.0) + extents.height / 2);
+ (but->w / 2.0) - (extents.width / 2),
+ (but->h / 2.0) + (extents.height / 2));
cairo_set_source_rgba(cr, 0, 0, 0, 1);
cairo_show_text(cr, but->label);
@@ -114,7 +115,7 @@ postButtonRedisplay(PuglView* view)
const ViewScale scale = getScale(view);
for (const Button* b = buttons; b->label; ++b) {
- const double span = sqrt(b->w * b->w + b->h * b->h);
+ const double span = sqrt((b->w * b->w) + (b->h * b->h));
puglObscureRegion(view,
(int)((b->x - span) * scale.x),
(int)((b->y - span) * scale.y),
diff --git a/examples/pugl_clipboard_demo.app/MacOS/meson.build b/examples/pugl_clipboard_demo.app/MacOS/meson.build
index 31ad2f0..f56ae59 100644
--- a/examples/pugl_clipboard_demo.app/MacOS/meson.build
+++ b/examples/pugl_clipboard_demo.app/MacOS/meson.build
@@ -5,6 +5,6 @@ executable(
'pugl_clipboard_demo',
'../../pugl_clipboard_demo.c',
c_args: example_defines + example_c_args,
- dependencies: [pugl_dep, pugl_gl_dep],
- include_directories: include_directories('../../..'),
+ dependencies: [pugl_dep, pugl_gl_dep, puglutil_dep],
+ implicit_include_directories: false,
)
diff --git a/examples/pugl_clipboard_demo.c b/examples/pugl_clipboard_demo.c
index 78ea4e8..04929ab 100644
--- a/examples/pugl_clipboard_demo.c
+++ b/examples/pugl_clipboard_demo.c
@@ -4,10 +4,11 @@
// A demonstration of using clipboards for copy/paste and drag and drop
#include "cube_view.h"
-#include "test/test_utils.h"
-#include "pugl/gl.h"
-#include "pugl/pugl.h"
+#include <puglutil/test_utils.h>
+
+#include <pugl/gl.h>
+#include <pugl/pugl.h>
#include <math.h>
#include <stdbool.h>
@@ -44,8 +45,8 @@ onDisplay(PuglView* view)
if (app->continuous) {
const double dTime = thisTime - cube->lastDrawTime;
- cube->xAngle = fmod(cube->xAngle + dTime * 100.0, 360.0);
- cube->yAngle = fmod(cube->yAngle + dTime * 100.0, 360.0);
+ cube->xAngle = fmod(cube->xAngle + (dTime * 100.0), 360.0);
+ cube->yAngle = fmod(cube->yAngle + (dTime * 100.0), 360.0);
}
displayCube(
diff --git a/examples/pugl_cpp_demo.app/MacOS/meson.build b/examples/pugl_cpp_demo.app/MacOS/meson.build
index f5ddd67..891dcd9 100644
--- a/examples/pugl_cpp_demo.app/MacOS/meson.build
+++ b/examples/pugl_cpp_demo.app/MacOS/meson.build
@@ -6,6 +6,6 @@ executable(
'../../pugl_cpp_demo.cpp',
c_args: example_defines + example_c_args,
cpp_args: example_defines + example_cpp_args,
- dependencies: [puglpp_dep, pugl_gl_dep],
- include_directories: include_directories('../../..'),
+ dependencies: [puglpp_dep, pugl_gl_dep, puglutil_dep],
+ implicit_include_directories: false,
)
diff --git a/examples/pugl_cpp_demo.cpp b/examples/pugl_cpp_demo.cpp
index 6b52d18..9ba5723 100644
--- a/examples/pugl_cpp_demo.cpp
+++ b/examples/pugl_cpp_demo.cpp
@@ -3,11 +3,12 @@
#include "cube_view.h"
#include "demo_utils.h"
-#include "test/test_utils.h"
-#include "pugl/gl.hpp"
-#include "pugl/pugl.h"
-#include "pugl/pugl.hpp"
+#include <puglutil/test_utils.h>
+
+#include <pugl/gl.hpp>
+#include <pugl/pugl.h>
+#include <pugl/pugl.hpp>
#include <cmath>
@@ -57,8 +58,9 @@ CubeView::onEvent(const pugl::UpdateEvent&) noexcept
// return obscure();
// But for testing, use sendEvent() instead:
+ const auto currentSize = this->size(pugl::SizeHint::currentSize);
return sendEvent(pugl::ExposeEvent{
- 0U, PuglCoord{0}, PuglCoord{0}, frame().width, frame().height});
+ 0U, PuglCoord{0}, PuglCoord{0}, currentSize.width, currentSize.height});
}
pugl::Status
diff --git a/examples/pugl_cursor_demo.app/MacOS/meson.build b/examples/pugl_cursor_demo.app/MacOS/meson.build
index 94359cd..0836875 100644
--- a/examples/pugl_cursor_demo.app/MacOS/meson.build
+++ b/examples/pugl_cursor_demo.app/MacOS/meson.build
@@ -6,6 +6,6 @@ executable(
'../../pugl_cursor_demo.c',
c_args: example_defines + example_c_args,
cpp_args: example_defines + example_cpp_args,
- dependencies: [pugl_dep, pugl_gl_dep],
- include_directories: include_directories('../../..'),
+ dependencies: [pugl_dep, pugl_gl_dep, puglutil_dep],
+ implicit_include_directories: false,
)
diff --git a/examples/pugl_cursor_demo.c b/examples/pugl_cursor_demo.c
index bc219f0..6ddd5ad 100644
--- a/examples/pugl_cursor_demo.c
+++ b/examples/pugl_cursor_demo.c
@@ -1,10 +1,10 @@
// Copyright 2012-2020 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
-#include "test/test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/gl.h"
-#include "pugl/pugl.h"
+#include <pugl/gl.h>
+#include <pugl/pugl.h>
#include <stdbool.h>
@@ -40,7 +40,7 @@ onExpose(void)
glColor3f(0.6f, 0.6f, 0.6f);
for (int row = 1; row < N_ROWS; ++row) {
- const float y = (float)row * (2.0f / (float)N_ROWS) - 1.0f;
+ const float y = ((float)row * (2.0f / (float)N_ROWS)) - 1.0f;
glBegin(GL_LINES);
glVertex2f(-1.0f, y);
glVertex2f(1.0f, y);
@@ -48,7 +48,7 @@ onExpose(void)
}
for (int col = 1; col < N_COLS; ++col) {
- const float x = (float)col * (2.0f / (float)N_COLS) - 1.0f;
+ const float x = ((float)col * (2.0f / (float)N_COLS)) - 1.0f;
glBegin(GL_LINES);
glVertex2f(x, -1.0f);
glVertex2f(x, 1.0f);
@@ -59,9 +59,9 @@ onExpose(void)
static void
onMotion(PuglView* view, double x, double y)
{
- const PuglRect frame = puglGetFrame(view);
- int row = (int)(y * N_ROWS / frame.height);
- int col = (int)(x * N_COLS / frame.width);
+ const PuglArea size = puglGetSizeHint(view, PUGL_CURRENT_SIZE);
+ int row = (int)(y * N_ROWS / size.height);
+ int col = (int)(x * N_COLS / size.width);
row = (row < 0) ? 0 : (row >= N_ROWS) ? (N_ROWS - 1) : row;
col = (col < 0) ? 0 : (col >= N_COLS) ? (N_COLS - 1) : col;
diff --git a/examples/pugl_embed_demo.app/MacOS/meson.build b/examples/pugl_embed_demo.app/MacOS/meson.build
index 9e6dd58..34d4ccb 100644
--- a/examples/pugl_embed_demo.app/MacOS/meson.build
+++ b/examples/pugl_embed_demo.app/MacOS/meson.build
@@ -6,6 +6,6 @@ executable(
'../../pugl_embed_demo.c',
c_args: example_defines + example_c_args,
cpp_args: example_defines + example_cpp_args,
- dependencies: [pugl_dep, pugl_gl_dep],
- include_directories: include_directories('../../..'),
+ dependencies: [pugl_dep, pugl_gl_dep, puglutil_dep],
+ implicit_include_directories: false,
)
diff --git a/examples/pugl_embed_demo.c b/examples/pugl_embed_demo.c
index c14afde..70e00c2 100644
--- a/examples/pugl_embed_demo.c
+++ b/examples/pugl_embed_demo.c
@@ -3,10 +3,11 @@
#include "cube_view.h"
#include "demo_utils.h"
-#include "test/test_utils.h"
-#include "pugl/gl.h"
-#include "pugl/pugl.h"
+#include <puglutil/test_utils.h>
+
+#include <pugl/gl.h>
+#include <pugl/pugl.h>
#include <math.h>
#include <stdbool.h>
@@ -50,18 +51,6 @@ static const float backgroundColorVertices[] = {
// clang-format on
-static PuglRect
-getChildFrame(const PuglRect parentFrame)
-{
- const PuglRect childFrame = {
- borderWidth,
- borderWidth,
- (PuglSpan)(parentFrame.width - 2 * borderWidth),
- (PuglSpan)(parentFrame.height - 2 * borderWidth)};
-
- return childFrame;
-}
-
static void
onDisplay(PuglView* view)
{
@@ -72,8 +61,8 @@ onDisplay(PuglView* view)
const double dTime =
(thisTime - app->lastDrawTime) * (app->reversing ? -1.0 : 1.0);
- app->xAngle = fmod(app->xAngle + dTime * 100.0, 360.0);
- app->yAngle = fmod(app->yAngle + dTime * 100.0, 360.0);
+ app->xAngle = fmod(app->xAngle + (dTime * 100.0), 360.0);
+ app->yAngle = fmod(app->yAngle + (dTime * 100.0), 360.0);
}
displayCube(
@@ -100,32 +89,33 @@ swapFocus(PuglTestApp* app)
static void
onKeyPress(PuglView* view, const PuglKeyEvent* event)
{
- PuglTestApp* app = (PuglTestApp*)puglGetHandle(view);
- PuglRect frame = puglGetFrame(view);
+ PuglTestApp* app = (PuglTestApp*)puglGetHandle(view);
if (event->key == '\t') {
swapFocus(app);
} else if (event->key == 'q' || event->key == PUGL_KEY_ESCAPE) {
app->quit = 1;
} else if (event->state & PUGL_MOD_SHIFT) {
+ const PuglArea size = puglGetSizeHint(view, PUGL_CURRENT_SIZE);
if (event->key == PUGL_KEY_UP) {
- puglSetSize(view, frame.width, frame.height - 10U);
+ puglSetSizeHint(view, PUGL_CURRENT_SIZE, size.width, size.height - 10U);
} else if (event->key == PUGL_KEY_DOWN) {
- puglSetSize(view, frame.width, frame.height + 10U);
+ puglSetSizeHint(view, PUGL_CURRENT_SIZE, size.width, size.height + 10U);
} else if (event->key == PUGL_KEY_LEFT) {
- puglSetSize(view, frame.width - 10U, frame.height);
+ puglSetSizeHint(view, PUGL_CURRENT_SIZE, size.width - 10U, size.height);
} else if (event->key == PUGL_KEY_RIGHT) {
- puglSetSize(view, frame.width + 10U, frame.height);
+ puglSetSizeHint(view, PUGL_CURRENT_SIZE, size.width + 10U, size.height);
}
} else {
+ const PuglPoint pos = puglGetPositionHint(view, PUGL_CURRENT_POSITION);
if (event->key == PUGL_KEY_UP) {
- puglSetPosition(view, frame.x, frame.y - 10);
+ puglSetPositionHint(view, PUGL_CURRENT_POSITION, pos.x, pos.y - 10);
} else if (event->key == PUGL_KEY_DOWN) {
- puglSetPosition(view, frame.x, frame.y + 10);
+ puglSetPositionHint(view, PUGL_CURRENT_POSITION, pos.x, pos.y + 10);
} else if (event->key == PUGL_KEY_LEFT) {
- puglSetPosition(view, frame.x - 10, frame.y);
+ puglSetPositionHint(view, PUGL_CURRENT_POSITION, pos.x - 10, pos.y);
} else if (event->key == PUGL_KEY_RIGHT) {
- puglSetPosition(view, frame.x + 10, frame.y);
+ puglSetPositionHint(view, PUGL_CURRENT_POSITION, pos.x + 10, pos.y);
}
}
}
@@ -133,16 +123,17 @@ onKeyPress(PuglView* view, const PuglKeyEvent* event)
static PuglStatus
onParentEvent(PuglView* view, const PuglEvent* event)
{
- PuglTestApp* app = (PuglTestApp*)puglGetHandle(view);
- const PuglRect parentFrame = puglGetFrame(view);
+ PuglTestApp* const app = (PuglTestApp*)puglGetHandle(view);
printEvent(event, "Parent: ", app->verbose);
switch (event->type) {
case PUGL_CONFIGURE:
reshapeCube((float)event->configure.width, (float)event->configure.height);
-
- puglSetFrame(app->child, getChildFrame(parentFrame));
+ puglSetSizeHint(app->child,
+ PUGL_CURRENT_SIZE,
+ event->configure.width - (2U * borderWidth),
+ event->configure.height - (2U * borderWidth));
break;
case PUGL_UPDATE:
if (app->continuous) {
@@ -261,7 +252,6 @@ main(int argc, char** argv)
puglSetWorldString(app.world, PUGL_CLASS_NAME, "PuglEmbedDemo");
- const PuglRect parentFrame = {0, 0, 512, 512};
puglSetSizeHint(app.parent, PUGL_DEFAULT_SIZE, 512, 512);
puglSetSizeHint(app.parent, PUGL_MIN_SIZE, 192, 192);
puglSetSizeHint(app.parent, PUGL_MAX_SIZE, 1024, 1024);
@@ -288,8 +278,13 @@ main(int argc, char** argv)
return logError("Failed to create parent window (%s)\n", puglStrerror(st));
}
- puglSetFrame(app.child, getChildFrame(parentFrame));
puglSetParent(app.child, puglGetNativeView(app.parent));
+ puglSetPositionHint(
+ app.child, PUGL_DEFAULT_POSITION, borderWidth, borderWidth);
+ puglSetSizeHint(app.child,
+ PUGL_DEFAULT_SIZE,
+ 512U - (2U * borderWidth),
+ 512U - (2U * borderWidth));
puglSetViewHint(app.child, PUGL_CONTEXT_DEBUG, opts.errorChecking);
puglSetViewHint(app.child, PUGL_SAMPLES, opts.samples);
diff --git a/examples/pugl_management_demo.app/MacOS/meson.build b/examples/pugl_management_demo.app/MacOS/meson.build
index 69dafc7..308a88c 100644
--- a/examples/pugl_management_demo.app/MacOS/meson.build
+++ b/examples/pugl_management_demo.app/MacOS/meson.build
@@ -6,6 +6,6 @@ executable(
['../../pugl_management_demo.c'],
c_args: example_defines + example_c_args + cairo_args,
cpp_args: example_defines + example_cpp_args,
- dependencies: [pugl_dep, pugl_cairo_dep],
- include_directories: include_directories('../../..'),
+ dependencies: [pugl_dep, pugl_cairo_dep, puglutil_dep],
+ implicit_include_directories: false,
)
diff --git a/examples/pugl_management_demo.c b/examples/pugl_management_demo.c
index 51d2f43..c9b3f4a 100644
--- a/examples/pugl_management_demo.c
+++ b/examples/pugl_management_demo.c
@@ -1,14 +1,12 @@
// Copyright 2012-2023 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
-/*
- A demonstration of window types, states, and management.
-*/
+// A demonstration of window types, states, and management
-#include "test/test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/cairo.h"
-#include "pugl/pugl.h"
+#include <pugl/cairo.h>
+#include <pugl/pugl.h>
#include <cairo.h>
@@ -37,12 +35,13 @@ onMainEvent(PuglView* view, const PuglEvent* event);
static PuglStatus
onExpose(PuglView* const view, const PuglExposeEvent* const event)
{
- PuglWorld* const world = puglGetWorld(view);
- DemoApp* const app = (DemoApp*)puglGetWorldHandle(world);
- const PuglRect frame = puglGetFrame(view);
+ PuglWorld* const world = puglGetWorld(view);
+ DemoApp* const app = (DemoApp*)puglGetWorldHandle(world);
+ const PuglPoint pos = puglGetPositionHint(view, PUGL_CURRENT_POSITION);
+ const PuglArea size = puglGetSizeHint(view, PUGL_CURRENT_SIZE);
const PuglViewStyleFlags style = puglGetViewStyle(view);
- const PuglCoord cx = (PuglCoord)(frame.width / 2U);
- const PuglCoord cy = (PuglCoord)(frame.height / 2U);
+ const PuglCoord cx = (PuglCoord)(size.width / 2U);
+ const PuglCoord cy = (PuglCoord)(size.height / 2U);
cairo_t* const cr = (cairo_t*)puglGetContext(view);
// Clip to expose region
@@ -61,29 +60,31 @@ onExpose(PuglView* const view, const PuglExposeEvent* const event)
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
// Draw position label
- snprintf(buf, sizeof(buf), "Position: %5d, %5d", frame.x, frame.y);
+ snprintf(buf, sizeof(buf), "Position: %5d, %5d", pos.x, pos.y);
cairo_text_extents(cr, buf, &extents);
cairo_move_to(
- cr, cx - extents.width / 2.0, cy + extents.height / 2.0 - 192.0);
+ cr, cx - (extents.width / 2.0), cy + (extents.height / 2.0) - 192.0);
cairo_show_text(cr, buf);
// Draw size label
- snprintf(buf, sizeof(buf), "Size: %5u, %5u", frame.width, frame.height);
+ snprintf(buf, sizeof(buf), "Size: %5u, %5u", size.width, size.height);
cairo_text_extents(cr, buf, &extents);
cairo_move_to(
- cr, cx - extents.width / 2.0, cy + extents.height / 2.0 - 144.0);
+ cr, cx - (extents.width / 2.0), cy + (extents.height / 2.0) - 144.0);
cairo_show_text(cr, buf);
// Draw scale label
snprintf(buf, sizeof(buf), "Scale: %g", puglGetScaleFactor(view));
cairo_text_extents(cr, buf, &extents);
- cairo_move_to(cr, cx - extents.width / 2.0, cy + extents.height / 2.0 - 96.0);
+ cairo_move_to(
+ cr, cx - (extents.width / 2.0), cy + (extents.height / 2.0) - 96.0);
cairo_show_text(cr, buf);
// Draw time label
snprintf(buf, sizeof(buf), "Draw time: %g", puglGetTime(world));
cairo_text_extents(cr, buf, &extents);
- cairo_move_to(cr, cx - extents.width / 2.0, cy + extents.height / 2.0 - 48.0);
+ cairo_move_to(
+ cr, cx - (extents.width / 2.0), cy + (extents.height / 2.0) - 48.0);
cairo_show_text(cr, buf);
// Draw style label
@@ -100,7 +101,7 @@ onExpose(PuglView* const view, const PuglExposeEvent* const event)
style & PUGL_VIEW_STYLE_DEMANDING ? " demanding" : "",
style & PUGL_VIEW_STYLE_RESIZING ? " resizing" : "");
cairo_text_extents(cr, buf, &extents);
- cairo_move_to(cr, cx - extents.width / 2.0, cy + extents.height / 2.0);
+ cairo_move_to(cr, cx - (extents.width / 2.0), cy + (extents.height / 2.0));
cairo_show_text(cr, buf);
if (view == app->mainView.view) {
@@ -108,7 +109,7 @@ onExpose(PuglView* const view, const PuglExposeEvent* const event)
snprintf(buf, sizeof(buf), "Keys: Space T W H M F A B D Q");
cairo_text_extents(cr, buf, &extents);
cairo_move_to(
- cr, cx - extents.width / 2.0, cy + extents.height / 2.0 + 48.0);
+ cr, cx - (extents.width / 2.0), cy + (extents.height / 2.0) + 48.0);
cairo_show_text(cr, buf);
}
diff --git a/examples/pugl_print_events.c b/examples/pugl_print_events.c
index 96a8889..9445e50 100644
--- a/examples/pugl_print_events.c
+++ b/examples/pugl_print_events.c
@@ -1,10 +1,10 @@
// Copyright 2012-2020 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
-#include "test/test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
#include <stdbool.h>
#include <stdio.h>
diff --git a/examples/pugl_shader_demo.app/MacOS/meson.build b/examples/pugl_shader_demo.app/MacOS/meson.build
index d3d0755..afcd532 100644
--- a/examples/pugl_shader_demo.app/MacOS/meson.build
+++ b/examples/pugl_shader_demo.app/MacOS/meson.build
@@ -10,6 +10,6 @@ executable(
],
c_args: example_defines + example_c_args,
cpp_args: example_defines + example_cpp_args,
- dependencies: [pugl_dep, pugl_gl_dep, dl_dep],
- include_directories: include_directories('../../..'),
+ dependencies: [pugl_dep, pugl_gl_dep, dl_dep, puglutil_dep],
+ implicit_include_directories: false,
)
diff --git a/examples/pugl_shader_demo.c b/examples/pugl_shader_demo.c
index 2b122a9..5bef21e 100644
--- a/examples/pugl_shader_demo.c
+++ b/examples/pugl_shader_demo.c
@@ -21,16 +21,19 @@
about 100000 rectangles.
*/
+#define PUGL_NO_INCLUDE_GL_H
+
#include "demo_utils.h"
#include "file_utils.h"
#include "rects.h"
#include "shader_utils.h"
-#include "test/test_utils.h"
#include "glad/glad.h"
-#include "pugl/gl.h"
-#include "pugl/pugl.h"
+#include <puglutil/test_utils.h>
+
+#include <pugl/gl.h>
+#include <pugl/pugl.h>
#include <math.h>
#include <stddef.h>
@@ -90,15 +93,15 @@ static void
onExpose(PuglView* view)
{
PuglTestApp* app = (PuglTestApp*)puglGetHandle(view);
- const PuglRect frame = puglGetFrame(view);
- const float width = (float)frame.width;
- const float height = (float)frame.height;
+ const PuglArea size = puglGetSizeHint(view, PUGL_CURRENT_SIZE);
+ const float width = (float)size.width;
+ const float height = (float)size.height;
const double time = puglGetTime(puglGetWorld(view));
// Construct projection matrix for 2D window surface (in pixels)
mat4 proj;
mat4Ortho(
- proj, 0.0f, (float)frame.width, 0.0f, (float)frame.height, -1.0f, 1.0f);
+ proj, 0.0f, (float)size.width, 0.0f, (float)size.height, -1.0f, 1.0f);
// Clear and bind everything that is the same for every rect
glClear(GL_COLOR_BUFFER_BIT);
@@ -108,7 +111,7 @@ onExpose(PuglView* view)
// Update horizontal mouse cursor line (last rect)
Rect* const mouseH = &app->rects[app->numRects];
mouseH->pos[0] = (float)(app->mouseX - 8.0);
- mouseH->pos[1] = (float)(frame.height - app->mouseY - 1.0);
+ mouseH->pos[1] = (float)(size.height - app->mouseY - 1.0);
mouseH->size[0] = 16.0f;
mouseH->size[1] = 2.0f;
mouseH->fillColor[0] = 1.0f;
@@ -119,7 +122,7 @@ onExpose(PuglView* view)
// Update vertical mouse cursor line (second last rect)
Rect* const mouseV = &app->rects[app->numRects + 1];
mouseV->pos[0] = (float)(app->mouseX - 2.0);
- mouseV->pos[1] = (float)(frame.height - app->mouseY - 8.0);
+ mouseV->pos[1] = (float)(size.height - app->mouseY - 8.0);
mouseV->size[0] = 2.0f;
mouseV->size[1] = 16.0f;
mouseV->fillColor[0] = 1.0f;
@@ -230,10 +233,15 @@ loadShader(const char* const programPath, const char* const name)
free(path);
fseek(file, 0, SEEK_END);
- const size_t fileSize = (size_t)ftell(file);
+ const long filePos = ftell(file);
+ if (filePos <= 0) {
+ fclose(file);
+ return NULL;
+ }
fseek(file, 0, SEEK_SET);
- char* source = (char*)calloc(1, fileSize + 1U);
+ const size_t fileSize = (size_t)filePos;
+ char* source = (char*)calloc(1, fileSize + 1U);
if (fread(source, 1, fileSize, file) != fileSize) {
free(source);
@@ -351,17 +359,16 @@ setupGl(PuglTestApp* app)
char* const fragmentSource =
loadShader(app->programPath, SHADER_DIR "rect.frag");
- if (!vertexSource || !fragmentSource) {
- logError("Failed to load shader sources\n");
- return PUGL_FAILURE;
+ // Compile rectangle shaders and program
+ if (headerSource && vertexSource && fragmentSource) {
+ app->drawRect = compileProgram(headerSource, vertexSource, fragmentSource);
}
- // Compile rectangle shaders and program
- app->drawRect = compileProgram(headerSource, vertexSource, fragmentSource);
free(fragmentSource);
free(vertexSource);
free(headerSource);
if (!app->drawRect.program) {
+ logError("Failed to compile shader program\n");
return PUGL_FAILURE;
}
diff --git a/examples/pugl_vulkan_cpp_demo.app/MacOS/meson.build b/examples/pugl_vulkan_cpp_demo.app/MacOS/meson.build
index d75c75d..7e7556b 100644
--- a/examples/pugl_vulkan_cpp_demo.app/MacOS/meson.build
+++ b/examples/pugl_vulkan_cpp_demo.app/MacOS/meson.build
@@ -9,6 +9,6 @@ executable(
],
c_args: example_defines + example_c_args,
cpp_args: example_defines + example_cpp_args,
- dependencies: [puglpp_dep, pugl_vulkan_dep],
- include_directories: include_directories('../../..'),
+ dependencies: [puglpp_dep, pugl_vulkan_dep, puglutil_dep],
+ implicit_include_directories: false,
)
diff --git a/examples/pugl_vulkan_cpp_demo.cpp b/examples/pugl_vulkan_cpp_demo.cpp
index a1d6954..4a73157 100644
--- a/examples/pugl_vulkan_cpp_demo.cpp
+++ b/examples/pugl_vulkan_cpp_demo.cpp
@@ -17,13 +17,14 @@
#include "demo_utils.h"
#include "file_utils.h"
#include "rects.h"
-#include "test/test_utils.h"
#include "sybok.hpp"
-#include "pugl/pugl.h"
-#include "pugl/pugl.hpp"
-#include "pugl/vulkan.hpp"
+#include <puglutil/test_utils.h>
+
+#include <pugl/pugl.h>
+#include <pugl/pugl.hpp>
+#include <pugl/vulkan.hpp>
#include <vulkan/vk_platform.h>
@@ -559,7 +560,7 @@ Swapchain::init(const sk::VulkanApi& vk,
const auto minNumImages =
(!capabilities.maxImageCount || capabilities.maxImageCount >= 3U)
- ? 3U
+ ? std::max(capabilities.minImageCount, 3U)
: capabilities.maxImageCount;
const VkSwapchainCreateInfoKHR swapchainCreateInfo{
@@ -576,7 +577,7 @@ Swapchain::init(const sk::VulkanApi& vk,
VK_SHARING_MODE_EXCLUSIVE,
SK_COUNTED(0, nullptr),
capabilities.currentTransform,
- VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
+ VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
mode == RenderMode::resizing ? gpu.resizePresentMode : gpu.presentMode,
VK_TRUE,
oldSwapchain};
@@ -715,7 +716,12 @@ readFile(const char* const programPath, const std::string& filename)
}
fseek(file.get(), 0, SEEK_END);
- const auto fileSize = static_cast<size_t>(ftell(file.get()));
+ const auto filePos = ftell(file.get());
+ if (filePos <= 0) {
+ return {};
+ }
+
+ const auto fileSize = static_cast<size_t>(filePos);
fseek(file.get(), 0, SEEK_SET);
const auto numWords = fileSize / sizeof(uint32_t);
diff --git a/examples/pugl_vulkan_demo.app/MacOS/meson.build b/examples/pugl_vulkan_demo.app/MacOS/meson.build
index 0d07171..0f7f4bf 100644
--- a/examples/pugl_vulkan_demo.app/MacOS/meson.build
+++ b/examples/pugl_vulkan_demo.app/MacOS/meson.build
@@ -8,6 +8,6 @@ executable(
'../../file_utils.c',
],
c_args: example_defines + example_c_args,
- dependencies: [pugl_dep, pugl_vulkan_dep],
- include_directories: include_directories('../../..'),
+ dependencies: [pugl_dep, pugl_vulkan_dep, puglutil_dep],
+ implicit_include_directories: false,
)
diff --git a/examples/pugl_vulkan_demo.c b/examples/pugl_vulkan_demo.c
index 708a28f..75083c4 100644
--- a/examples/pugl_vulkan_demo.c
+++ b/examples/pugl_vulkan_demo.c
@@ -10,10 +10,11 @@
*/
#include "demo_utils.h"
-#include "test/test_utils.h"
-#include "pugl/pugl.h"
-#include "pugl/vulkan.h"
+#include <puglutil/test_utils.h>
+
+#include <pugl/pugl.h>
+#include <pugl/vulkan.h>
#include <vulkan/vk_platform.h>
#include <vulkan/vulkan_core.h>
diff --git a/examples/pugl_window_demo.app/MacOS/meson.build b/examples/pugl_window_demo.app/MacOS/meson.build
index 7bfc219..f2623f2 100644
--- a/examples/pugl_window_demo.app/MacOS/meson.build
+++ b/examples/pugl_window_demo.app/MacOS/meson.build
@@ -6,6 +6,6 @@ executable(
'../../pugl_window_demo.c',
c_args: example_defines + example_c_args,
cpp_args: example_defines + example_cpp_args,
- dependencies: [pugl_dep, pugl_gl_dep],
- include_directories: include_directories('../../..'),
+ dependencies: [pugl_dep, pugl_gl_dep, puglutil_dep],
+ implicit_include_directories: false,
)
diff --git a/examples/pugl_window_demo.c b/examples/pugl_window_demo.c
index cd4fd67..867f856 100644
--- a/examples/pugl_window_demo.c
+++ b/examples/pugl_window_demo.c
@@ -7,10 +7,11 @@
#include "cube_view.h"
#include "demo_utils.h"
-#include "test/test_utils.h"
-#include "pugl/gl.h"
-#include "pugl/pugl.h"
+#include <puglutil/test_utils.h>
+
+#include <pugl/gl.h>
+#include <pugl/pugl.h>
#include <math.h>
#include <stdbool.h>
@@ -49,8 +50,8 @@ onDisplay(PuglView* view)
if (app->continuous) {
const double dTime = thisTime - cube->lastDrawTime;
- cube->xAngle = fmod(cube->xAngle + dTime * 100.0, 360.0);
- cube->yAngle = fmod(cube->yAngle + dTime * 100.0, 360.0);
+ cube->xAngle = fmod(cube->xAngle + (dTime * 100.0), 360.0);
+ cube->yAngle = fmod(cube->yAngle + (dTime * 100.0), 360.0);
}
displayCube(
@@ -64,29 +65,30 @@ onKeyPress(PuglView* view, const PuglKeyEvent* event)
{
PuglWorld* world = puglGetWorld(view);
PuglTestApp* app = (PuglTestApp*)puglGetWorldHandle(world);
- PuglRect frame = puglGetFrame(view);
if (event->key == 'q' || event->key == PUGL_KEY_ESCAPE) {
app->quit = 1;
} else if (event->state & PUGL_MOD_SHIFT) {
+ const PuglArea size = puglGetSizeHint(view, PUGL_CURRENT_SIZE);
if (event->key == PUGL_KEY_UP) {
- puglSetSize(view, frame.width, frame.height - 10U);
+ puglSetSizeHint(view, PUGL_CURRENT_SIZE, size.width, size.height - 10U);
} else if (event->key == PUGL_KEY_DOWN) {
- puglSetSize(view, frame.width, frame.height + 10U);
+ puglSetSizeHint(view, PUGL_CURRENT_SIZE, size.width, size.height + 10U);
} else if (event->key == PUGL_KEY_LEFT) {
- puglSetSize(view, frame.width - 10U, frame.height);
+ puglSetSizeHint(view, PUGL_CURRENT_SIZE, size.width - 10U, size.height);
} else if (event->key == PUGL_KEY_RIGHT) {
- puglSetSize(view, frame.width + 10U, frame.height);
+ puglSetSizeHint(view, PUGL_CURRENT_SIZE, size.width + 10U, size.height);
}
} else {
+ const PuglPoint pos = puglGetPositionHint(view, PUGL_CURRENT_POSITION);
if (event->key == PUGL_KEY_UP) {
- puglSetPosition(view, frame.x, frame.y - 10);
+ puglSetPositionHint(view, PUGL_CURRENT_POSITION, pos.x, pos.y - 10);
} else if (event->key == PUGL_KEY_DOWN) {
- puglSetPosition(view, frame.x, frame.y + 10);
+ puglSetPositionHint(view, PUGL_CURRENT_POSITION, pos.x, pos.y + 10);
} else if (event->key == PUGL_KEY_LEFT) {
- puglSetPosition(view, frame.x - 10, frame.y);
+ puglSetPositionHint(view, PUGL_CURRENT_POSITION, pos.x - 10, pos.y);
} else if (event->key == PUGL_KEY_RIGHT) {
- puglSetPosition(view, frame.x + 10, frame.y);
+ puglSetPositionHint(view, PUGL_CURRENT_POSITION, pos.x + 10, pos.y);
}
}
}
@@ -186,9 +188,10 @@ main(int argc, char** argv)
cube->dist = 10;
puglSetViewString(view, PUGL_WINDOW_TITLE, "Pugl Window Demo");
- puglSetPosition(view,
- (PuglCoord)(pad + (128U + pad) * i),
- (PuglCoord)(pad + (128U + pad) * i));
+ puglSetPositionHint(view,
+ PUGL_DEFAULT_POSITION,
+ (PuglCoord)(pad + ((128U + pad) * i)),
+ (PuglCoord)(pad + ((128U + pad) * i)));
puglSetSizeHint(view, PUGL_DEFAULT_SIZE, 512, 512);
puglSetSizeHint(view, PUGL_MIN_SIZE, 128, 128);
diff --git a/include/pugl/attributes.h b/include/pugl/attributes.h
index 75322ee..1e2264c 100644
--- a/include/pugl/attributes.h
+++ b/include/pugl/attributes.h
@@ -26,17 +26,6 @@
# endif
#endif
-// Deprecated API
-#ifndef PUGL_DISABLE_DEPRECATED
-# if defined(__clang__)
-# define PUGL_DEPRECATED_BY(rep) __attribute__((deprecated("", rep)))
-# elif defined(__GNUC__)
-# define PUGL_DEPRECATED_BY(rep) __attribute__((deprecated("Use " rep)))
-# else
-# define PUGL_DEPRECATED_BY(rep)
-# endif
-#endif
-
// GCC function attributes
#if defined(__GNUC__)
# define PUGL_CONST_FUNC __attribute__((const))
@@ -47,13 +36,9 @@
#endif
/// A const function in the public API that only reads parameters
-#define PUGL_CONST_API \
- PUGL_API \
- PUGL_CONST_FUNC
+#define PUGL_CONST_API PUGL_API PUGL_CONST_FUNC
/// A malloc function in the public API that returns allocated memory
-#define PUGL_MALLOC_API \
- PUGL_API \
- PUGL_MALLOC_FUNC
+#define PUGL_MALLOC_API PUGL_API PUGL_MALLOC_FUNC
#endif // PUGL_ATTRIBUTES_H
diff --git a/include/pugl/cairo.h b/include/pugl/cairo.h
index fda1191..8a5ae4e 100644
--- a/include/pugl/cairo.h
+++ b/include/pugl/cairo.h
@@ -4,8 +4,8 @@
#ifndef PUGL_CAIRO_H
#define PUGL_CAIRO_H
-#include "pugl/attributes.h"
-#include "pugl/pugl.h"
+#include <pugl/attributes.h>
+#include <pugl/pugl.h>
PUGL_BEGIN_DECLS
@@ -21,8 +21,7 @@ PUGL_BEGIN_DECLS
Pass the returned value to puglSetBackend() to draw to a view with Cairo.
*/
-PUGL_CONST_API
-const PuglBackend*
+PUGL_CONST_API const PuglBackend*
puglCairoBackend(void);
/**
diff --git a/include/pugl/gl.h b/include/pugl/gl.h
index ac7c557..f4d5f3d 100644
--- a/include/pugl/gl.h
+++ b/include/pugl/gl.h
@@ -4,8 +4,8 @@
#ifndef PUGL_GL_H
#define PUGL_GL_H
-#include "pugl/attributes.h"
-#include "pugl/pugl.h"
+#include <pugl/attributes.h>
+#include <pugl/pugl.h>
// IWYU pragma: begin_exports
@@ -42,8 +42,7 @@ typedef void (*PuglGlFunc)(void);
/**
Return the address of an OpenGL extension function.
*/
-PUGL_API
-PuglGlFunc
+PUGL_API PuglGlFunc
puglGetProcAddress(const char* name);
/**
@@ -53,8 +52,7 @@ puglGetProcAddress(const char* name);
doing things like loading textures. Note that this must not be used for
drawing, which may only be done while processing an expose event.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglEnterContext(PuglView* view);
/**
@@ -62,8 +60,7 @@ puglEnterContext(PuglView* view);
This must only be called after puglEnterContext().
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglLeaveContext(PuglView* view);
/**
@@ -71,8 +68,7 @@ puglLeaveContext(PuglView* view);
Pass the returned value to puglSetBackend() to draw to a view with OpenGL.
*/
-PUGL_CONST_API
-const PuglBackend*
+PUGL_CONST_API const PuglBackend*
puglGlBackend(void);
PUGL_END_DECLS
diff --git a/include/pugl/pugl.h b/include/pugl/pugl.h
index d7366c6..5ba5a46 100644
--- a/include/pugl/pugl.h
+++ b/include/pugl/pugl.h
@@ -4,7 +4,7 @@
#ifndef PUGL_PUGL_H
#define PUGL_PUGL_H
-#include "pugl/attributes.h"
+#include <pugl/attributes.h>
#include <stddef.h>
#include <stdint.h>
@@ -46,22 +46,17 @@ typedef int16_t PuglCoord;
*/
typedef uint16_t PuglSpan;
-/**
- A rectangle in a view or on the screen.
-
- This type is used to describe two things: the position and size of a view
- (for configuring), or a rectangle within a view (for exposing).
-
- The coordinate (0, 0) represents the top-left pixel of the parent window (or
- display if there isn't one), or the top-left pixel of the view,
- respectively.
-*/
+/// A 2-dimensional position within/of a view
typedef struct {
PuglCoord x;
PuglCoord y;
- PuglSpan width;
- PuglSpan height;
-} PuglRect;
+} PuglPoint;
+
+/// A 2-dimensional size within/of a view
+typedef struct {
+ PuglSpan width;
+ PuglSpan height;
+} PuglArea;
/// A string property for configuration
typedef enum {
@@ -341,77 +336,77 @@ typedef struct {
mapping used here is arbitrary and specific to Pugl.
*/
typedef enum {
- PUGL_KEY_NONE = 0U, ///< Sentinel value for no key
- PUGL_KEY_BACKSPACE = 0x00000008U, ///< Backspace
- PUGL_KEY_TAB = 0x00000009U, ///< Tab
- PUGL_KEY_ENTER = 0x0000000DU, ///< Enter
- PUGL_KEY_ESCAPE = 0x0000001BU, ///< Escape
- PUGL_KEY_DELETE = 0x0000007FU, ///< Delete
- PUGL_KEY_SPACE = 0x00000020U, ///< Space
- PUGL_KEY_F1 = 0x0000E000U, ///< F1
- PUGL_KEY_F2, ///< F2
- PUGL_KEY_F3, ///< F3
- PUGL_KEY_F4, ///< F4
- PUGL_KEY_F5, ///< F5
- PUGL_KEY_F6, ///< F6
- PUGL_KEY_F7, ///< F7
- PUGL_KEY_F8, ///< F8
- PUGL_KEY_F9, ///< F9
- PUGL_KEY_F10, ///< F10
- PUGL_KEY_F11, ///< F11
- PUGL_KEY_F12, ///< F12
- PUGL_KEY_PAGE_UP = 0xE031, ///< Page Up
- PUGL_KEY_PAGE_DOWN, ///< Page Down
- PUGL_KEY_END, ///< End
- PUGL_KEY_HOME, ///< Home
- PUGL_KEY_LEFT, ///< Left
- PUGL_KEY_UP, ///< Up
- PUGL_KEY_RIGHT, ///< Right
- PUGL_KEY_DOWN, ///< Down
- PUGL_KEY_PRINT_SCREEN = 0xE041U, ///< Print Screen
- PUGL_KEY_INSERT, ///< Insert
- PUGL_KEY_PAUSE, ///< Pause/Break
- PUGL_KEY_MENU, ///< Menu
- PUGL_KEY_NUM_LOCK, ///< Num Lock
- PUGL_KEY_SCROLL_LOCK, ///< Scroll Lock
- PUGL_KEY_CAPS_LOCK, ///< Caps Lock
- PUGL_KEY_SHIFT_L = 0xE051U, ///< Left Shift
- PUGL_KEY_SHIFT_R, ///< Right Shift
- PUGL_KEY_CTRL_L, ///< Left Control
- PUGL_KEY_CTRL_R, ///< Right Control
- PUGL_KEY_ALT_L, ///< Left Alt
- PUGL_KEY_ALT_R, ///< Right Alt / AltGr
- PUGL_KEY_SUPER_L, ///< Left Super
- PUGL_KEY_SUPER_R, ///< Right Super
- PUGL_KEY_PAD_0 = 0xE060U, ///< Keypad 0
- PUGL_KEY_PAD_1, ///< Keypad 1
- PUGL_KEY_PAD_2, ///< Keypad 2
- PUGL_KEY_PAD_3, ///< Keypad 3
- PUGL_KEY_PAD_4, ///< Keypad 4
- PUGL_KEY_PAD_5, ///< Keypad 5
- PUGL_KEY_PAD_6, ///< Keypad 6
- PUGL_KEY_PAD_7, ///< Keypad 7
- PUGL_KEY_PAD_8, ///< Keypad 8
- PUGL_KEY_PAD_9, ///< Keypad 9
- PUGL_KEY_PAD_ENTER, ///< Keypad Enter
- PUGL_KEY_PAD_PAGE_UP = 0xE071U, ///< Keypad Page Up
- PUGL_KEY_PAD_PAGE_DOWN, ///< Keypad Page Down
- PUGL_KEY_PAD_END, ///< Keypad End
- PUGL_KEY_PAD_HOME, ///< Keypad Home
- PUGL_KEY_PAD_LEFT, ///< Keypad Left
- PUGL_KEY_PAD_UP, ///< Keypad Up
- PUGL_KEY_PAD_RIGHT, ///< Keypad Right
- PUGL_KEY_PAD_DOWN, ///< Keypad Down
- PUGL_KEY_PAD_CLEAR = 0xE09DU, ///< Keypad Clear/Begin
- PUGL_KEY_PAD_INSERT, ///< Keypad Insert
- PUGL_KEY_PAD_DELETE, ///< Keypad Delete
- PUGL_KEY_PAD_EQUAL, ///< Keypad Equal
- PUGL_KEY_PAD_MULTIPLY = 0xE0AAU, ///< Keypad Multiply
- PUGL_KEY_PAD_ADD, ///< Keypad Add
- PUGL_KEY_PAD_SEPARATOR, ///< Keypad Separator
- PUGL_KEY_PAD_SUBTRACT, ///< Keypad Subtract
- PUGL_KEY_PAD_DECIMAL, ///< Keypad Decimal
- PUGL_KEY_PAD_DIVIDE, ///< Keypad Divide
+ PUGL_KEY_NONE = 0U, ///< Sentinel value for no key
+ PUGL_KEY_BACKSPACE = 0x0008U, ///< Backspace
+ PUGL_KEY_TAB = 0x0009U, ///< Tab
+ PUGL_KEY_ENTER = 0x000DU, ///< Enter
+ PUGL_KEY_ESCAPE = 0x001BU, ///< Escape
+ PUGL_KEY_DELETE = 0x007FU, ///< Delete
+ PUGL_KEY_SPACE = 0x0020U, ///< Space
+ PUGL_KEY_F1 = 0xE000U, ///< F1
+ PUGL_KEY_F2 = 0xE001U, ///< F2
+ PUGL_KEY_F3 = 0xE002U, ///< F3
+ PUGL_KEY_F4 = 0xE003U, ///< F4
+ PUGL_KEY_F5 = 0xE004U, ///< F5
+ PUGL_KEY_F6 = 0xE005U, ///< F6
+ PUGL_KEY_F7 = 0xE006U, ///< F7
+ PUGL_KEY_F8 = 0xE007U, ///< F8
+ PUGL_KEY_F9 = 0xE008U, ///< F9
+ PUGL_KEY_F10 = 0xE009U, ///< F10
+ PUGL_KEY_F11 = 0xE010U, ///< F11
+ PUGL_KEY_F12 = 0xE011U, ///< F12
+ PUGL_KEY_PAGE_UP = 0xE031U, ///< Page Up
+ PUGL_KEY_PAGE_DOWN = 0xE032U, ///< Page Down
+ PUGL_KEY_END = 0xE033U, ///< End
+ PUGL_KEY_HOME = 0xE034U, ///< Home
+ PUGL_KEY_LEFT = 0xE035U, ///< Left
+ PUGL_KEY_UP = 0xE036U, ///< Up
+ PUGL_KEY_RIGHT = 0xE037U, ///< Right
+ PUGL_KEY_DOWN = 0xE038U, ///< Down
+ PUGL_KEY_PRINT_SCREEN = 0xE041U, ///< Print Screen
+ PUGL_KEY_INSERT = 0xE042U, ///< Insert
+ PUGL_KEY_PAUSE = 0xE043U, ///< Pause/Break
+ PUGL_KEY_MENU = 0xE044U, ///< Menu
+ PUGL_KEY_NUM_LOCK = 0xE045U, ///< Num Lock
+ PUGL_KEY_SCROLL_LOCK = 0xE046U, ///< Scroll Lock
+ PUGL_KEY_CAPS_LOCK = 0xE047U, ///< Caps Lock
+ PUGL_KEY_SHIFT_L = 0xE051U, ///< Left Shift
+ PUGL_KEY_SHIFT_R = 0xE052U, ///< Right Shift
+ PUGL_KEY_CTRL_L = 0xE053U, ///< Left Control
+ PUGL_KEY_CTRL_R = 0xE054U, ///< Right Control
+ PUGL_KEY_ALT_L = 0xE055U, ///< Left Alt
+ PUGL_KEY_ALT_R = 0xE056U, ///< Right Alt / AltGr
+ PUGL_KEY_SUPER_L = 0xE057U, ///< Left Super
+ PUGL_KEY_SUPER_R = 0xE058U, ///< Right Super
+ PUGL_KEY_PAD_0 = 0xE060U, ///< Keypad 0
+ PUGL_KEY_PAD_1 = 0xE061U, ///< Keypad 1
+ PUGL_KEY_PAD_2 = 0xE062U, ///< Keypad 2
+ PUGL_KEY_PAD_3 = 0xE063U, ///< Keypad 3
+ PUGL_KEY_PAD_4 = 0xE064U, ///< Keypad 4
+ PUGL_KEY_PAD_5 = 0xE065U, ///< Keypad 5
+ PUGL_KEY_PAD_6 = 0xE066U, ///< Keypad 6
+ PUGL_KEY_PAD_7 = 0xE067U, ///< Keypad 7
+ PUGL_KEY_PAD_8 = 0xE068U, ///< Keypad 8
+ PUGL_KEY_PAD_9 = 0xE069U, ///< Keypad 9
+ PUGL_KEY_PAD_ENTER = 0xE070U, ///< Keypad Enter
+ PUGL_KEY_PAD_PAGE_UP = 0xE071U, ///< Keypad Page Up
+ PUGL_KEY_PAD_PAGE_DOWN = 0xE072U, ///< Keypad Page Down
+ PUGL_KEY_PAD_END = 0xE073U, ///< Keypad End
+ PUGL_KEY_PAD_HOME = 0xE074U, ///< Keypad Home
+ PUGL_KEY_PAD_LEFT = 0xE075U, ///< Keypad Left
+ PUGL_KEY_PAD_UP = 0xE076U, ///< Keypad Up
+ PUGL_KEY_PAD_RIGHT = 0xE077U, ///< Keypad Right
+ PUGL_KEY_PAD_DOWN = 0xE078U, ///< Keypad Down
+ PUGL_KEY_PAD_CLEAR = 0xE09DU, ///< Keypad Clear/Begin
+ PUGL_KEY_PAD_INSERT = 0xE09EU, ///< Keypad Insert
+ PUGL_KEY_PAD_DELETE = 0xE09FU, ///< Keypad Delete
+ PUGL_KEY_PAD_EQUAL = 0xE0A0U, ///< Keypad Equal
+ PUGL_KEY_PAD_MULTIPLY = 0xE0AAU, ///< Keypad Multiply
+ PUGL_KEY_PAD_ADD = 0xE0ABU, ///< Keypad Add
+ PUGL_KEY_PAD_SEPARATOR = 0xE0ACU, ///< Keypad Separator
+ PUGL_KEY_PAD_SUBTRACT = 0xE0ADU, ///< Keypad Subtract
+ PUGL_KEY_PAD_DECIMAL = 0xE0AEU, ///< Keypad Decimal
+ PUGL_KEY_PAD_DIVIDE = 0xE0AFU, ///< Keypad Divide
} PuglKey;
/// Keyboard modifier flags
@@ -444,8 +439,8 @@ typedef struct {
Key press or release event.
This event represents low-level key presses and releases. This can be used
- for "direct" keyboard handing like key bindings, but must not be interpreted
- as text input.
+ for "direct" keyboard handling like key bindings, but must not be
+ interpreted as text input.
Keys are represented portably as Unicode code points, using the "natural"
code point for the key where possible (see #PuglKey for details). The `key`
@@ -734,8 +729,7 @@ typedef enum {
} PuglStatus;
/// Return a string describing a status code
-PUGL_CONST_API
-const char*
+PUGL_CONST_API const char*
puglStrerror(PuglStatus status);
/**
@@ -791,13 +785,11 @@ typedef uint32_t PuglWorldFlags;
@param flags Flags to control world features.
@return A new world, which must be later freed with puglFreeWorld().
*/
-PUGL_MALLOC_API
-PuglWorld*
+PUGL_MALLOC_API PuglWorld*
puglNewWorld(PuglWorldType type, PuglWorldFlags flags);
/// Free a world allocated with puglNewWorld()
-PUGL_API
-void
+PUGL_API void
puglFreeWorld(PuglWorld* world);
/**
@@ -808,13 +800,11 @@ puglFreeWorld(PuglWorld* world);
The handle is opaque to Pugl and is not interpreted in any way.
*/
-PUGL_API
-void
+PUGL_API void
puglSetWorldHandle(PuglWorld* world, PuglWorldHandle handle);
/// Get the user data for the world
-PUGL_API
-PuglWorldHandle
+PUGL_API PuglWorldHandle
puglGetWorldHandle(PuglWorld* world);
/**
@@ -826,8 +816,7 @@ puglGetWorldHandle(PuglWorld* world);
Windows: Returns the `HMODULE` of the calling process.
*/
-PUGL_API
-void*
+PUGL_API void*
puglGetNativeWorld(PuglWorld* world);
/**
@@ -836,8 +825,7 @@ puglGetNativeWorld(PuglWorld* world);
The string value only needs to be valid for the duration of this call, it
will be copied if necessary.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglSetWorldString(PuglWorld* world, PuglStringHint key, const char* value);
/**
@@ -846,8 +834,7 @@ puglSetWorldString(PuglWorld* world, PuglStringHint key, const char* value);
The returned string should be accessed immediately, or copied. It may
become invalid upon any call to any function that manipulates the same view.
*/
-PUGL_API
-const char*
+PUGL_API const char*
puglGetWorldString(const PuglWorld* world, PuglStringHint key);
/**
@@ -857,8 +844,7 @@ puglGetWorldString(const PuglWorld* world, PuglStringHint key);
time is only useful to compare against other times returned by this
function, its absolute value has no meaning.
*/
-PUGL_API
-double
+PUGL_API double
puglGetTime(const PuglWorld* world);
/**
@@ -883,8 +869,7 @@ puglGetTime(const PuglWorld* world);
@return #PUGL_SUCCESS if events are read, #PUGL_FAILURE if no events are
read, or an error.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglUpdate(PuglWorld* world, double timeout);
/**
@@ -960,9 +945,9 @@ typedef enum {
/// A special view hint value
typedef enum {
- PUGL_DONT_CARE = -1, ///< Generic trinary: Use best default
- PUGL_FALSE = 0, ///< Generic trinary: Explicitly false
- PUGL_TRUE = 1, ///< Generic trinary: Explicitly true
+ PUGL_DONT_CARE = -1, ///< Generic trinary: unset
+ PUGL_FALSE = 0, ///< Generic trinary: false
+ PUGL_TRUE = 1, ///< Generic trinary: true
PUGL_OPENGL_API = 2, ///< For #PUGL_CONTEXT_API
PUGL_OPENGL_ES_API = 3, ///< For #PUGL_CONTEXT_API
PUGL_OPENGL_CORE_PROFILE = 4, ///< For #PUGL_CONTEXT_PROFILE
@@ -977,6 +962,49 @@ typedef enum {
} PuglViewType;
/**
+ A hint for configuring/constraining the position of a view.
+
+ The system will attempt to make the view's window adhere to these, but they
+ are suggestions, not hard constraints. Applications should handle any view
+ position gracefully.
+
+ An unset position has `INT16_MIN` (-32768) for both `x` and `y`. In
+ practice, set positions should be between -16000 and 16000 for portability.
+ Usually, the origin is the top left of the display, although negative
+ coordinates are possible, particularly on multi-display system.
+*/
+typedef enum {
+ /**
+ Default position.
+
+ This is used as the position during window creation as a default, if no
+ other position is specified. It isn't necessary to set a default position
+ (unlike the default size, which is required). If not even a default
+ position is set, then the window will be created at an arbitrary position.
+ This position is a best-effort attempt to do the most reasonable thing for
+ the initial display of the window, for example, by centering. Note that
+ it is implementation-defined, subject to change, platform-specific, and
+ for embedded views, may no longer make sense if the parent's size is
+ adjusted. Code that wants to make assumptions about the initial position
+ must set the default to a specific valid one, such as `{0, 0}`.
+ */
+ PUGL_DEFAULT_POSITION,
+
+ /**
+ Current position.
+
+ This reflects the current position of the view, which may be different from
+ the default position if the view has been moved by the user, window
+ manager, or for any other reason. Typically, it overrides the
+ default position.
+ */
+ PUGL_CURRENT_POSITION,
+} PuglPositionHint;
+
+/// The number of #PuglPositionHint values
+#define PUGL_NUM_POSITION_HINTS ((unsigned)PUGL_CURRENT_POSITION + 1U)
+
+/**
A hint for configuring/constraining the size of a view.
The system will attempt to make the view's window adhere to these, but they
@@ -993,6 +1021,15 @@ typedef enum {
PUGL_DEFAULT_SIZE,
/**
+ Current size.
+
+ This reflects the current size of the view, which may be different from
+ the default size if the view is resizable. Typically, it overrides the
+ default size.
+ */
+ PUGL_CURRENT_SIZE,
+
+ /**
Minimum size.
If set, the view's size should be constrained to be at least this large.
@@ -1050,18 +1087,15 @@ typedef PuglStatus (*PuglEventFunc)(PuglView* view, const PuglEvent* event);
It must first be configured, then the system view can be created with
puglRealize().
*/
-PUGL_MALLOC_API
-PuglView*
+PUGL_MALLOC_API PuglView*
puglNewView(PuglWorld* world);
/// Free a view created with puglNewView()
-PUGL_API
-void
+PUGL_API void
puglFreeView(PuglView* view);
/// Return the world that `view` is a part of
-PUGL_API
-PuglWorld*
+PUGL_API PuglWorld*
puglGetWorld(PuglView* view);
/**
@@ -1073,13 +1107,11 @@ puglGetWorld(PuglView* view);
The handle is opaque to Pugl and is not interpreted in any way.
*/
-PUGL_API
-void
+PUGL_API void
puglSetHandle(PuglView* view, PuglHandle handle);
/// Get the user data for a view
-PUGL_API
-PuglHandle
+PUGL_API PuglHandle
puglGetHandle(PuglView* view);
/**
@@ -1099,18 +1131,15 @@ puglGetHandle(PuglView* view);
applications must link against the appropriate backend library, or be sure
to compile in the appropriate code if using a local copy of Pugl.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglSetBackend(PuglView* view, const PuglBackend* backend);
/// Return the graphics backend used by a view
-PUGL_API
-const PuglBackend*
+PUGL_API const PuglBackend*
puglGetBackend(const PuglView* view);
/// Set the function to call when an event occurs
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglSetEventFunc(PuglView* view, PuglEventFunc eventFunc);
/**
@@ -1118,8 +1147,7 @@ puglSetEventFunc(PuglView* view, PuglEventFunc eventFunc);
This only has an effect when called before puglRealize().
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglSetViewHint(PuglView* view, PuglViewHint hint, int value);
/**
@@ -1129,8 +1157,7 @@ puglSetViewHint(PuglView* view, PuglViewHint hint, int value);
hint which was initially set to PUGL_DONT_CARE, or has been adjusted from
the suggested value.
*/
-PUGL_API
-int
+PUGL_API int
puglGetViewHint(const PuglView* view, PuglViewHint hint);
/**
@@ -1140,8 +1167,7 @@ puglGetViewHint(const PuglView* view, PuglViewHint hint);
string value only needs to be valid for the duration of this call, it will
be copied if necessary.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglSetViewString(PuglView* view, PuglStringHint key, const char* value);
/**
@@ -1150,8 +1176,7 @@ puglSetViewString(PuglView* view, PuglStringHint key, const char* value);
The returned string should be accessed immediately, or copied. It may
become invalid upon any call to any function that manipulates the same view.
*/
-PUGL_API
-const char*
+PUGL_API const char*
puglGetViewString(const PuglView* view, PuglStringHint key);
/**
@@ -1166,8 +1191,7 @@ puglGetViewString(const PuglView* view, PuglStringHint key);
that is reasonably sized on a 96 DPI display, and the scale 2.0 should have
text twice that large.
*/
-PUGL_API
-double
+PUGL_API double
puglGetScaleFactor(const PuglView* view);
/**
@@ -1178,60 +1202,52 @@ puglGetScaleFactor(const PuglView* view);
*/
/**
- Get the current position and size of the view.
+ Get a position hint for the view.
- The position is in screen coordinates with an upper left origin.
+ This can be used to get the default or current position of a view, in screen
+ coordinates with an upper left origin.
*/
-PUGL_API
-PuglRect
-puglGetFrame(const PuglView* view);
+PUGL_API PuglPoint
+puglGetPositionHint(const PuglView* view, PuglPositionHint hint);
/**
- Set the current position and size of the view.
+ Set a position hint for the view.
- The position is in screen coordinates with an upper left origin.
+ This can be used to set the default or current position of a view.
- @return #PUGL_UNKNOWN_ERROR on failure, in which case the view frame is
- unchanged.
-*/
-PUGL_API
-PuglStatus
-puglSetFrame(PuglView* view, PuglRect frame);
-
-/**
- Set the current position of the view.
+ This should be called before puglRealize() so the initial window for the
+ view can be configured correctly. It may also be used dynamically after the
+ window is realized, for some hints.
- @return #PUGL_UNKNOWN_ERROR on failure, in which case the view frame is
- unchanged.
+ @return An error code on failure, but always succeeds if the view is not yet
+ realized.
*/
-PUGL_API
-PuglStatus
-puglSetPosition(PuglView* view, int x, int y);
+PUGL_API PuglStatus
+puglSetPositionHint(PuglView* view, PuglPositionHint hint, int x, int y);
/**
- Set the current size of the view.
+ Get a size hint for the view.
- @return #PUGL_UNKNOWN_ERROR on failure, in which case the view frame is
- unchanged.
+ This can be used to get the default, current, minimum, and maximum size of a
+ view, as well as the supported range of aspect ratios.
*/
-PUGL_API
-PuglStatus
-puglSetSize(PuglView* view, unsigned width, unsigned height);
+PUGL_API PuglArea
+puglGetSizeHint(const PuglView* view, PuglSizeHint hint);
/**
Set a size hint for the view.
- This can be used to set the default, minimum, and maximum size of a view,
- as well as the supported range of aspect ratios.
+ This can be used to set the default, current, minimum, and maximum size of a
+ view, as well as the supported range of aspect ratios.
This should be called before puglRealize() so the initial window for the
- view can be configured correctly.
+ view can be configured correctly. It may also be used dynamically after the
+ window is realized, for some hints.
- @return #PUGL_UNKNOWN_ERROR on failure, but always succeeds if the view is
- not yet realized.
+ @return An error code on failure, but always succeeds if the view is not yet
+ realized.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglSetSizeHint(PuglView* view,
PuglSizeHint hint,
unsigned width,
@@ -1249,13 +1265,11 @@ puglSetSizeHint(PuglView* view,
This must be called before puglRealize(), reparenting is not supported.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglSetParent(PuglView* view, PuglNativeView parent);
/// Return the parent window this view is embedded in, or null
-PUGL_API
-PuglNativeView
+PUGL_API PuglNativeView
puglGetParent(const PuglView* view);
/**
@@ -1268,8 +1282,7 @@ puglGetParent(const PuglView* view);
A view can either have a parent (for embedding) or a transient parent (for
top-level windows like dialogs), but not both.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglSetTransientParent(PuglView* view, PuglNativeView parent);
/**
@@ -1278,8 +1291,7 @@ puglSetTransientParent(PuglView* view, PuglNativeView parent);
@return The native handle to the window this view is a transient child of,
or null.
*/
-PUGL_API
-PuglNativeView
+PUGL_API PuglNativeView
puglGetTransientParent(const PuglView* view);
/**
@@ -1291,8 +1303,7 @@ puglGetTransientParent(const PuglView* view);
The view should be fully configured using the above functions before this is
called. This function may only be called once per view.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglRealize(PuglView* view);
/**
@@ -1301,8 +1312,7 @@ puglRealize(PuglView* view);
This is the inverse of puglRealize(). After this call, the view no longer
corresponds to a real system view, and can be realized again later.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglUnrealize(PuglView* view);
/// A command to control the behaviour of puglShow()
@@ -1346,13 +1356,11 @@ typedef enum {
If the view is currently hidden, it will be shown and possibly raised to the
top depending on the platform.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglShow(PuglView* view, PuglShowCommand command);
/// Hide the current window
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglHide(PuglView* view);
/**
@@ -1365,8 +1373,7 @@ puglHide(PuglView* view);
used to determine if the state has actually been set. Any changes to the
actual state of the view will arrive in later configure events.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglSetViewStyle(PuglView* view, PuglViewStyleFlags flags);
/**
@@ -1375,18 +1382,15 @@ puglSetViewStyle(PuglView* view, PuglViewStyleFlags flags);
The result is determined based on the state announced in the last configure
event.
*/
-PUGL_API
-PuglViewStyleFlags
+PUGL_API PuglViewStyleFlags
puglGetViewStyle(const PuglView* view);
/// Return true iff the view is currently visible
-PUGL_API
-bool
+PUGL_API bool
puglGetVisible(const PuglView* view);
/// Return the native window handle
-PUGL_API
-PuglNativeView
+PUGL_API PuglNativeView
puglGetNativeView(PuglView* view);
/**
@@ -1407,8 +1411,7 @@ puglGetNativeView(PuglView* view);
All other backends: returns null.
*/
-PUGL_API
-void*
+PUGL_API void*
puglGetContext(PuglView* view);
/**
@@ -1420,8 +1423,7 @@ puglGetContext(PuglView* view);
platforms. If called elsewhere, an expose will be enqueued to be processed
in the next event loop iteration.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglObscureView(PuglView* view);
/**
@@ -1441,8 +1443,7 @@ puglObscureView(PuglView* view);
@param width The width of the rectangle to obscure.
@param height The height coordinate of the rectangle to obscure.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglObscureRegion(PuglView* view,
int x,
int y,
@@ -1486,13 +1487,11 @@ typedef enum {
@return #PUGL_SUCCESS if the focus was successfully grabbed, or an error.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglGrabFocus(PuglView* view);
/// Return whether `view` has the keyboard input focus
-PUGL_API
-bool
+PUGL_API bool
puglHasFocus(const PuglView* view);
/**
@@ -1500,8 +1499,7 @@ puglHasFocus(const PuglView* view);
A #PUGL_DATA_OFFER event will be sent if data is available.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglPaste(PuglView* view);
/**
@@ -1509,8 +1507,7 @@ puglPaste(PuglView* view);
Returns zero if the clipboard is empty.
*/
-PUGL_API
-uint32_t
+PUGL_API uint32_t
puglGetNumClipboardTypes(const PuglView* view);
/**
@@ -1522,8 +1519,7 @@ puglGetNumClipboardTypes(const PuglView* view);
Returns null if `typeIndex` is out of bounds according to
puglGetNumClipboardTypes().
*/
-PUGL_API
-const char*
+PUGL_API const char*
puglGetClipboardType(const PuglView* view, uint32_t typeIndex);
/**
@@ -1542,8 +1538,7 @@ puglGetClipboardType(const PuglView* view, uint32_t typeIndex);
the `typeIndex` argument to the call of puglGetClipboardType() that returned
the accepted type.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglAcceptOffer(PuglView* view,
const PuglDataOfferEvent* offer,
uint32_t typeIndex);
@@ -1559,8 +1554,7 @@ puglAcceptOffer(PuglView* view,
@param data The data to copy to the clipboard.
@param len The length of data in bytes (including terminator if necessary).
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglSetClipboard(PuglView* view,
const char* type,
const void* data,
@@ -1577,8 +1571,7 @@ puglSetClipboard(PuglView* view,
@param[out] len Set to the length of the data in bytes.
@return The clipboard contents, or null.
*/
-PUGL_API
-const void*
+PUGL_API const void*
puglGetClipboard(PuglView* view, uint32_t typeIndex, size_t* len);
/**
@@ -1592,8 +1585,7 @@ puglGetClipboard(PuglView* view, uint32_t typeIndex, size_t* len);
#PUGL_UNSUPPORTED if setting the cursor is not supported on this system, or
another error if the cursor is known but loading it fails.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglSetCursor(PuglView* view, PuglCursor cursor);
/**
@@ -1622,8 +1614,7 @@ puglSetCursor(PuglView* view, PuglCursor cursor);
@return #PUGL_FAILURE if timers are not supported by the system,
#PUGL_UNKNOWN_ERROR if setting the timer failed.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglStartTimer(PuglView* view, uintptr_t id, double timeout);
/**
@@ -1635,8 +1626,7 @@ puglStartTimer(PuglView* view, uintptr_t id, double timeout);
@return #PUGL_FAILURE if timers are not supported by this system,
#PUGL_UNKNOWN_ERROR if stopping the timer failed.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglStopTimer(PuglView* view, uintptr_t id);
/**
@@ -1655,592 +1645,11 @@ puglStopTimer(PuglView* view, uintptr_t id);
@return #PUGL_UNSUPPORTED if sending events of this type is not supported,
#PUGL_UNKNOWN_ERROR if sending the event failed.
*/
-PUGL_API
-PuglStatus
+PUGL_API PuglStatus
puglSendEvent(PuglView* view, const PuglEvent* event);
/**
@}
-*/
-
-#ifndef PUGL_DISABLE_DEPRECATED
-
-/**
- @}
- @defgroup pugl_deprecated Deprecated API
- @{
-*/
-
-PUGL_DEPRECATED_BY("PuglRealizeEvent")
-typedef PuglRealizeEvent PuglCreateEvent;
-
-PUGL_DEPRECATED_BY("PuglUnrealizeEvent")
-typedef PuglUnrealizeEvent PuglDestroyEvent;
-
-PUGL_DEPRECATED_BY("PuglRealizeEvent")
-typedef PuglRealizeEvent PuglEventCreate;
-
-PUGL_DEPRECATED_BY("PuglUnrealizeEvent")
-typedef PuglUnrealizeEvent PuglEventDestroy;
-
-PUGL_DEPRECATED_BY("PuglConfigureEvent")
-typedef PuglConfigureEvent PuglEventConfigure;
-
-PUGL_DEPRECATED_BY("PuglUpdateEvent")
-typedef PuglUpdateEvent PuglEventUpdate;
-
-PUGL_DEPRECATED_BY("PuglExposeEvent")
-typedef PuglExposeEvent PuglEventExpose;
-
-PUGL_DEPRECATED_BY("PuglCloseEvent")
-typedef PuglCloseEvent PuglEventClose;
-
-PUGL_DEPRECATED_BY("PuglFocusEvent")
-typedef PuglFocusEvent PuglEventFocus;
-
-PUGL_DEPRECATED_BY("PuglKeyEvent")
-typedef PuglKeyEvent PuglEventKey;
-
-PUGL_DEPRECATED_BY("PuglTextEvent")
-typedef PuglTextEvent PuglEventText;
-
-PUGL_DEPRECATED_BY("PuglCrossingEvent")
-typedef PuglCrossingEvent PuglEventCrossing;
-
-PUGL_DEPRECATED_BY("PuglButtonEvent")
-typedef PuglButtonEvent PuglEventButton;
-
-PUGL_DEPRECATED_BY("PuglMotionEvent")
-typedef PuglMotionEvent PuglEventMotion;
-
-PUGL_DEPRECATED_BY("PuglScrollEvent")
-typedef PuglScrollEvent PuglEventScroll;
-
-PUGL_DEPRECATED_BY("PuglClientEvent")
-typedef PuglClientEvent PuglEventClient;
-
-PUGL_DEPRECATED_BY("PuglTimerEvent")
-typedef PuglTimerEvent PuglEventTimer;
-
-PUGL_DEPRECATED_BY("PuglLoopEnterEvent")
-typedef PuglLoopEnterEvent PuglEventLoopEnter;
-
-PUGL_DEPRECATED_BY("PuglLoopLeaveEvent")
-typedef PuglLoopLeaveEvent PuglEventLoopLeave;
-
-/**
- A native window handle.
-
- X11: This is a `Window`.
-
- MacOS: This is a pointer to an `NSView*`.
-
- Windows: This is a `HWND`.
-*/
-PUGL_DEPRECATED_BY("PuglNativeView")
-typedef uintptr_t PuglNativeWindow;
-
-/**
- Create a Pugl application and view.
-
- To create a window, call the various puglInit* functions as necessary, then
- call puglRealize().
-
- @deprecated Use puglNewApp() and puglNewView().
-
- @param pargc Pointer to argument count (currently unused).
- @param argv Arguments (currently unused).
- @return A newly created view.
-*/
-static inline PUGL_DEPRECATED_BY("puglNewView")
-PuglView*
-puglInit(const int* pargc, char** argv)
-{
- (void)pargc;
- (void)argv;
-
- return puglNewView(puglNewWorld(PUGL_MODULE, 0));
-}
-
-/**
- Destroy an app and view created with `puglInit()`.
-
- @deprecated Use puglFreeApp() and puglFreeView().
-*/
-static inline PUGL_DEPRECATED_BY("puglFreeView")
-void
-puglDestroy(PuglView* view)
-{
- PuglWorld* const world = puglGetWorld(view);
-
- puglFreeView(view);
- puglFreeWorld(world);
-}
-
-/**
- Set the class name of the application.
-
- This is a stable identifier for the application, used as the window
- class/instance name on X11 and Windows. It is not displayed to the user,
- but can be used in scripts and by window managers, so it should be the same
- for every instance of the application, but different from other
- applications.
-*/
-static inline PUGL_DEPRECATED_BY("puglSetWorldString")
-PuglStatus
-puglSetClassName(PuglWorld* world, const char* name)
-{
- return puglSetWorldString(world, PUGL_CLASS_NAME, name);
-}
-
-/// Get the class name of the application, or null
-static inline PUGL_DEPRECATED_BY("puglGetWorldString")
-const char*
-puglGetClassName(const PuglWorld* world)
-{
- return puglGetWorldString(world, PUGL_CLASS_NAME);
-}
-
-/**
- Set the window class name before creating a window.
-*/
-static inline PUGL_DEPRECATED_BY("puglSetWorldString")
-void
-puglInitWindowClass(PuglView* view, const char* name)
-{
- puglSetWorldString(puglGetWorld(view), PUGL_CLASS_NAME, name);
-}
-
-/**
- Set the window size before creating a window.
-
- @deprecated Use puglSetFrame().
-*/
-static inline PUGL_DEPRECATED_BY("puglSetFrame")
-void
-puglInitWindowSize(PuglView* view, int width, int height)
-{
- PuglRect frame = puglGetFrame(view);
-
- frame.width = (PuglSpan)width;
- frame.height = (PuglSpan)height;
-
- puglSetFrame(view, frame);
-}
-
-/**
- Set the minimum window size before creating a window.
-*/
-static inline PUGL_DEPRECATED_BY("puglSetSizeHint")
-void
-puglInitWindowMinSize(PuglView* view, int width, int height)
-{
- puglSetSizeHint(view, PUGL_MIN_SIZE, (unsigned)width, (unsigned)height);
-}
-
-/**
- Set the window aspect ratio range before creating a window.
-
- The x and y values here represent a ratio of width to height. To set a
- fixed aspect ratio, set the minimum and maximum values to the same ratio.
-
- Note that setting different minimum and maximum constraints does not
- currently work on MacOS (the minimum is used), so only setting a fixed
- aspect ratio works properly across all platforms.
-*/
-static inline PUGL_DEPRECATED_BY("puglSetSizeHint")
-void
-puglInitWindowAspectRatio(PuglView* view,
- int minX,
- int minY,
- int maxX,
- int maxY)
-{
- puglSetSizeHint(view, PUGL_MIN_ASPECT, (unsigned)minX, (unsigned)minY);
- puglSetSizeHint(view, PUGL_MAX_ASPECT, (unsigned)maxX, (unsigned)maxY);
-}
-
-/**
- Set transient parent before creating a window.
-
- On X11, parent must be a Window.
- On OSX, parent must be an NSView*.
-*/
-static inline PUGL_DEPRECATED_BY("puglSetTransientParent")
-void
-puglInitTransientFor(PuglView* view, uintptr_t parent)
-{
- puglSetTransientParent(view, (PuglNativeView)parent);
-}
-
-/**
- Set transient parent before creating a window.
-
- @deprecated Use puglSetTransientParent().
-*/
-static inline PUGL_DEPRECATED_BY("puglSetTransientParent")
-PuglStatus
-puglSetTransientFor(PuglView* view, uintptr_t parent)
-{
- return puglSetTransientParent(view, (PuglNativeView)parent);
-}
-
-/**
- Enable or disable resizing before creating a window.
-
- @deprecated Use puglSetViewHint() with #PUGL_RESIZABLE.
-*/
-static inline PUGL_DEPRECATED_BY("puglSetViewHint")
-void
-puglInitResizable(PuglView* view, bool resizable)
-{
- puglSetViewHint(view, PUGL_RESIZABLE, resizable);
-}
-
-/**
- Get the current size of the view.
-
- @deprecated Use puglGetFrame().
-
-*/
-static inline PUGL_DEPRECATED_BY("puglGetFrame")
-void
-puglGetSize(PuglView* view, int* width, int* height)
-{
- const PuglRect frame = puglGetFrame(view);
-
- *width = (int)frame.width;
- *height = (int)frame.height;
-}
-
-/**
- Ignore synthetic repeated key events.
-
- @deprecated Use puglSetViewHint() with #PUGL_IGNORE_KEY_REPEAT.
-*/
-static inline PUGL_DEPRECATED_BY("puglSetViewHint")
-void
-puglIgnoreKeyRepeat(PuglView* view, bool ignore)
-{
- puglSetViewHint(view, PUGL_IGNORE_KEY_REPEAT, ignore);
-}
-
-/**
- Set a hint before creating a window.
-
- @deprecated Use puglSetWindowHint().
-*/
-static inline PUGL_DEPRECATED_BY("puglSetViewHint")
-void
-puglInitWindowHint(PuglView* view, PuglViewHint hint, int value)
-{
- puglSetViewHint(view, hint, value);
-}
-
-/**
- Set the parent window before creating a window (for embedding).
-
- @deprecated Use puglSetWindowParent().
-*/
-static inline PUGL_DEPRECATED_BY("puglSetParent")
-void
-puglInitWindowParent(PuglView* view, PuglNativeView parent)
-{
- puglSetParent(view, parent);
-}
-
-/**
- Set the graphics backend to use.
-
- @deprecated Use puglSetBackend().
-*/
-static inline PUGL_DEPRECATED_BY("puglSetBackend")
-int
-puglInitBackend(PuglView* view, const PuglBackend* backend)
-{
- return (int)puglSetBackend(view, backend);
-}
-
-/**
- Set the title of the window.
-
- This only makes sense for non-embedded views that will have a corresponding
- top-level window, and sets the title, typically displayed in the title bar
- or in window switchers.
-*/
-static inline PUGL_DEPRECATED_BY("puglSetViewString")
-PuglStatus
-puglSetWindowTitle(PuglView* view, const char* title)
-{
- return puglSetViewString(view, PUGL_WINDOW_TITLE, title);
-}
-
-/// Return the title of the window, or null
-static inline PUGL_DEPRECATED_BY("puglGetViewString")
-const char*
-puglGetWindowTitle(const PuglView* view)
-{
- return puglGetViewString(view, PUGL_WINDOW_TITLE);
-}
-
-/**
- Realize a view by creating a corresponding system view or window.
-
- The view should be fully configured using the above functions before this is
- called. This function may only be called once per view.
-
- @deprecated Use puglRealize(), or just show the view.
-*/
-static inline PUGL_DEPRECATED_BY("puglRealize")
-PuglStatus
-puglCreateWindow(PuglView* view, const char* title)
-{
- puglSetViewString(view, PUGL_WINDOW_TITLE, title);
- return puglRealize(view);
-}
-
-/**
- Block and wait for an event to be ready.
-
- This can be used in a loop to only process events via puglProcessEvents when
- necessary. This function will block indefinitely if no events are
- available, so is not appropriate for use in programs that need to perform
- regular updates (e.g. animation).
-
- @deprecated Use puglPollEvents().
-*/
-PUGL_API
-PUGL_DEPRECATED_BY("puglPollEvents")
-PuglStatus
-puglWaitForEvent(PuglView* view);
-
-/**
- Process all pending window events.
-
- This handles input events as well as rendering, so it should be called
- regularly and rapidly enough to keep the UI responsive. This function does
- not block if no events are pending.
-
- @deprecated Use puglDispatchEvents().
-*/
-PUGL_API
-PUGL_DEPRECATED_BY("puglDispatchEvents")
-PuglStatus
-puglProcessEvents(PuglView* view);
-
-/**
- Poll for events that are ready to be processed.
-
- This polls for events that are ready for any view in the world, potentially
- blocking depending on `timeout`.
-
- @param world The world to poll for events.
-
- @param timeout Maximum time to wait, in seconds. If zero, the call returns
- immediately, if negative, the call blocks indefinitely.
-
- @return #PUGL_SUCCESS if events are read, #PUGL_FAILURE if not, or an error.
-
- @deprecated Use puglUpdate().
-*/
-static inline PUGL_DEPRECATED_BY("puglUpdate")
-PuglStatus
-puglPollEvents(PuglWorld* world, double timeout)
-{
- return puglUpdate(world, timeout);
-}
-
-/**
- Dispatch any pending events to views.
-
- This processes all pending events, dispatching them to the appropriate
- views. View event handlers will be called in the scope of this call. This
- function does not block, if no events are pending then it will return
- immediately.
-
- @deprecated Use puglUpdate().
-*/
-static inline PUGL_DEPRECATED_BY("puglUpdate")
-PuglStatus
-puglDispatchEvents(PuglWorld* world)
-{
- return puglUpdate(world, 0.0);
-}
-
-static inline PUGL_DEPRECATED_BY("puglShow")
-PuglStatus
-puglShowWindow(PuglView* view)
-{
- return puglShow(view, PUGL_SHOW_RAISE);
-}
-
-static inline PUGL_DEPRECATED_BY("puglHide")
-PuglStatus
-puglHideWindow(PuglView* view)
-{
- return puglHide(view);
-}
-
-/**
- Set the default size of the view.
-
- This should be called before puglRealize() to set the default size of the
- view, which will be the initial size of the window if this is a top level
- view.
-
- @return #PUGL_UNKNOWN_ERROR on failure, but always succeeds if the view is
- not yet realized.
-*/
-static inline PUGL_DEPRECATED_BY("puglSetSizeHint")
-PuglStatus
-puglSetDefaultSize(PuglView* view, int width, int height)
-{
- return puglSetSizeHint(
- view, PUGL_DEFAULT_SIZE, (unsigned)width, (unsigned)height);
-}
-
-/**
- Set the minimum size of the view.
-
- If an initial minimum size is known, this should be called before
- puglRealize() to avoid stutter, though it can be called afterwards as well.
-
- @return #PUGL_UNKNOWN_ERROR on failure, but always succeeds if the view is
- not yet realized.
-*/
-static inline PUGL_DEPRECATED_BY("puglSetSizeHint")
-PuglStatus
-puglSetMinSize(PuglView* view, int width, int height)
-{
- return puglSetSizeHint(
- view, PUGL_MIN_SIZE, (unsigned)width, (unsigned)height);
-}
-
-/**
- Set the maximum size of the view.
-
- If an initial maximum size is known, this should be called before
- puglRealize() to avoid stutter, though it can be called afterwards as well.
-
- @return #PUGL_UNKNOWN_ERROR on failure, but always succeeds if the view is
- not yet realized.
-*/
-static inline PUGL_DEPRECATED_BY("puglSetSizeHint")
-PuglStatus
-puglSetMaxSize(PuglView* view, int width, int height)
-{
- return puglSetSizeHint(
- view, PUGL_MAX_SIZE, (unsigned)width, (unsigned)height);
-}
-
-/**
- Set the view aspect ratio range.
-
- The x and y values here represent a ratio of width to height. To set a
- fixed aspect ratio, set the minimum and maximum values to the same ratio.
-
- Note that setting different minimum and maximum constraints does not
- currently work on MacOS (the minimum is used), so only setting a fixed
- aspect ratio works properly across all platforms.
-
- If an initial aspect ratio is known, this should be called before
- puglRealize() to avoid stutter, though it can be called afterwards as well.
-
- @return #PUGL_UNKNOWN_ERROR on failure, but always succeeds if the view is
- not yet realized.
-*/
-static inline PUGL_DEPRECATED_BY("puglSetSizeHint")
-PuglStatus
-puglSetAspectRatio(PuglView* view, int minX, int minY, int maxX, int maxY)
-{
- const PuglStatus st0 =
- puglSetSizeHint(view, PUGL_MIN_ASPECT, (unsigned)minX, (unsigned)minY);
-
- const PuglStatus st1 =
- puglSetSizeHint(view, PUGL_MAX_ASPECT, (unsigned)maxX, (unsigned)maxY);
-
- return st0 ? st0 : st1;
-}
-
-/// Return the native window handle
-static inline PUGL_DEPRECATED_BY("puglGetNativeView")
-PuglNativeView
-puglGetNativeWindow(PuglView* view)
-{
- return puglGetNativeView(view);
-}
-
-/**
- Request user attention.
-
- This hints to the system that the window or application requires attention
- from the user. The exact effect depends on the platform, but is usually
- something like a flashing task bar entry or bouncing application icon.
-*/
-static inline PUGL_DEPRECATED_BY("puglSetViewStyle")
-PuglStatus
-puglRequestAttention(PuglView* view)
-{
- return puglSetViewStyle(view,
- puglGetViewStyle(view) | PUGL_VIEW_STYLE_DEMANDING);
-}
-
-# define PUGL_KEY_SHIFT PUGL_KEY_SHIFT_L
-
-# define PUGL_KEY_CTRL PUGL_KEY_CTRL_L
-
-# define PUGL_KEY_ALT PUGL_KEY_ALT_L
-
-# define PUGL_KEY_SUPER PUGL_KEY_SUPER_L
-
-/// Set the parent window for embedding a view in an existing window
-static inline PUGL_DEPRECATED_BY("puglSetParent")
-PuglStatus
-puglSetParentWindow(PuglView* view, PuglNativeView parent)
-{
- return puglSetParent(view, parent);
-}
-
-/// Return the parent window this view is embedded in, or null
-static inline PUGL_DEPRECATED_BY("puglGetParent")
-PuglNativeView
-puglGetParentWindow(PuglView* view)
-{
- return puglGetParent(view);
-}
-
-/**
- Request a redisplay for the entire view.
-
- This will cause an expose event to be dispatched later. If called from
- within the event handler, the expose should arrive at the end of the current
- event loop iteration, though this is not strictly guaranteed on all
- platforms. If called elsewhere, an expose will be enqueued to be processed
- in the next event loop iteration.
-*/
-static inline PUGL_DEPRECATED_BY("puglObscureView")
-PuglStatus
-puglPostRedisplay(PuglView* view)
-{
- return puglObscureView(view);
-}
-
-/**
- Request a redisplay of the given rectangle within the view.
-
- This has the same semantics as puglPostRedisplay(), but allows giving a
- precise region for redrawing only a portion of the view.
-*/
-static inline PUGL_DEPRECATED_BY("puglObscureRegion")
-PuglStatus
-puglPostRedisplayRect(PuglView* view, PuglRect rect)
-{
- return puglObscureRegion(view, rect.x, rect.y, rect.width, rect.height);
-}
-
-#endif // PUGL_DISABLE_DEPRECATED
-
-/**
@}
@}
*/
diff --git a/include/pugl/stub.h b/include/pugl/stub.h
index 8bfe4d8..73f20aa 100644
--- a/include/pugl/stub.h
+++ b/include/pugl/stub.h
@@ -4,8 +4,8 @@
#ifndef PUGL_STUB_H
#define PUGL_STUB_H
-#include "pugl/attributes.h"
-#include "pugl/pugl.h"
+#include <pugl/attributes.h>
+#include <pugl/pugl.h>
PUGL_BEGIN_DECLS
@@ -22,8 +22,7 @@ PUGL_BEGIN_DECLS
This backend just creates a simple native window without setting up any
portable graphics API.
*/
-PUGL_CONST_API
-const PuglBackend*
+PUGL_CONST_API const PuglBackend*
puglStubBackend(void);
/**
diff --git a/include/pugl/vulkan.h b/include/pugl/vulkan.h
index a26ca8a..325c39d 100644
--- a/include/pugl/vulkan.h
+++ b/include/pugl/vulkan.h
@@ -10,8 +10,8 @@
#ifndef PUGL_VULKAN_H
#define PUGL_VULKAN_H
-#include "pugl/attributes.h"
-#include "pugl/pugl.h"
+#include <pugl/attributes.h>
+#include <pugl/pugl.h>
#include <vulkan/vulkan_core.h>
@@ -70,8 +70,7 @@ typedef struct PuglVulkanLoaderImpl PuglVulkanLoader;
@return A new Vulkan loader, or null on failure.
*/
-PUGL_API
-PuglVulkanLoader*
+PUGL_API PuglVulkanLoader*
puglNewVulkanLoader(PuglWorld* world, const char* libraryName);
/**
@@ -80,8 +79,7 @@ puglNewVulkanLoader(PuglWorld* world, const char* libraryName);
Note that this closes the Vulkan library, so no Vulkan objects or API may be
used after this is called.
*/
-PUGL_API
-void
+PUGL_API void
puglFreeVulkanLoader(PuglVulkanLoader* loader);
/**
@@ -90,8 +88,7 @@ puglFreeVulkanLoader(PuglVulkanLoader* loader);
@return Null if the Vulkan library does not contain this function (which is
unlikely and indicates a broken system).
*/
-PUGL_API
-PFN_vkGetInstanceProcAddr
+PUGL_API PFN_vkGetInstanceProcAddr
puglGetInstanceProcAddrFunc(const PuglVulkanLoader* loader);
/**
@@ -100,8 +97,7 @@ puglGetInstanceProcAddrFunc(const PuglVulkanLoader* loader);
@return Null if the Vulkan library does not contain this function (which is
unlikely and indicates a broken system).
*/
-PUGL_API
-PFN_vkGetDeviceProcAddr
+PUGL_API PFN_vkGetDeviceProcAddr
puglGetDeviceProcAddrFunc(const PuglVulkanLoader* loader);
/**
@@ -113,8 +109,7 @@ puglGetDeviceProcAddrFunc(const PuglVulkanLoader* loader);
@param[out] count The number of extensions in the returned array.
@return An array of extension name strings.
*/
-PUGL_API
-const char* const*
+PUGL_API const char* const*
puglGetInstanceExtensions(uint32_t* count);
/**
@@ -127,8 +122,7 @@ puglGetInstanceExtensions(uint32_t* count);
@param[out] surface Pointed to a newly created Vulkan surface.
@return `VK_SUCCESS` on success, or a Vulkan error code.
*/
-PUGL_API
-VkResult
+PUGL_API VkResult
puglCreateSurface(PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr,
PuglView* view,
VkInstance instance,
@@ -140,8 +134,7 @@ puglCreateSurface(PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr,
Pass the returned value to puglSetBackend() to draw to a view with Vulkan.
*/
-PUGL_CONST_API
-const PuglBackend*
+PUGL_CONST_API const PuglBackend*
puglVulkanBackend(void);
/**
diff --git a/meson.build b/meson.build
index 1c2d8ca..6fc3973 100644
--- a/meson.build
+++ b/meson.build
@@ -1,4 +1,4 @@
-# Copyright 2021-2023 David Robillard <d@drobilla.net>
+# Copyright 2021-2025 David Robillard <d@drobilla.net>
# SPDX-License-Identifier: 0BSD OR ISC
project(
@@ -8,6 +8,7 @@ project(
'b_ndebug=if-release',
'buildtype=release',
'c_std=c99',
+ 'c_winlibs=',
'cpp_std=c++14',
],
license: 'ISC',
@@ -28,8 +29,11 @@ versioned_name = 'pugl' + version_suffix
pkg = import('pkgconfig')
cc = meson.get_compiler('c')
-# Enable C++ support if we're building the examples
-if not get_option('examples').disabled() or not get_option('tests').disabled()
+# Enable C++ support if we're building the examples or the bindings
+if (
+ not get_option('bindings_cpp').disabled()
+ or not get_option('examples').disabled()
+)
if add_languages(['cpp'], native: false, required: false)
cpp = meson.get_compiler('cpp')
endif
@@ -44,12 +48,6 @@ endif
# Set global warning suppressions
subdir('meson/suppressions')
-# Disable deprecated API which is not used by tests or examples
-add_project_arguments(
- ['-DPUGL_DISABLE_DEPRECATED'],
- language: ['c', 'cpp', 'objc', 'objcpp'],
-)
-
#############
# Platforms #
#############
@@ -165,10 +163,11 @@ elif host_machine.system() == 'windows'
user32_dep = cc.find_library('user32')
shlwapi_dep = cc.find_library('shlwapi')
dwmapi_dep = cc.find_library('dwmapi')
+ gdi32_dep = cc.find_library('gdi32')
platform = 'win'
platform_sources = files('src/win.c')
- core_deps = [user32_dep, shlwapi_dep, dwmapi_dep]
+ core_deps = [user32_dep, shlwapi_dep, dwmapi_dep, gdi32_dep]
extension = '.c'
soversion = ''
@@ -244,6 +243,7 @@ libpugl = library(
c_args: library_args + core_args,
dependencies: core_deps,
gnu_symbol_visibility: 'hidden',
+ implicit_include_directories: false,
include_directories: includes,
install: true,
soversion: soversion,
@@ -253,7 +253,7 @@ libpugl = library(
pugl_dep = declare_dependency(
compile_args: extra_c_args,
dependencies: core_deps,
- include_directories: ['include'],
+ include_directories: includes,
link_with: libpugl,
)
@@ -283,6 +283,7 @@ if get_option('stub')
c_args: library_args,
dependencies: [pugl_dep],
gnu_symbol_visibility: 'hidden',
+ implicit_include_directories: false,
include_directories: includes,
install: true,
soversion: soversion,
@@ -325,6 +326,7 @@ if opengl_dep.found()
c_args: library_args,
dependencies: [pugl_dep, opengl_dep],
gnu_symbol_visibility: 'hidden',
+ implicit_include_directories: false,
include_directories: includes,
install: true,
soversion: soversion,
@@ -378,6 +380,7 @@ if cairo_dep.found()
c_args: library_args + cairo_args,
dependencies: [pugl_dep, cairo_dep],
gnu_symbol_visibility: 'hidden',
+ implicit_include_directories: false,
include_directories: includes,
install: true,
objc_args: library_args + cairo_args,
@@ -433,6 +436,7 @@ if vulkan_dep.found()
c_args: library_args,
dependencies: vulkan_deps,
gnu_symbol_visibility: 'hidden',
+ implicit_include_directories: false,
include_directories: includes,
install: true,
soversion: soversion,
@@ -464,12 +468,20 @@ endif
###############################
subdir('include')
-subdir('bindings/cpp')
+
+if not get_option('bindings_cpp').disabled()
+ subdir('bindings/cpp')
+endif
######################
# Tests and Examples #
######################
+if not get_option('tests').disabled() or not get_option('examples').disabled()
+ puglutil = subproject('puglutil')
+ puglutil_dep = puglutil.get_variable('puglutil_dep')
+endif
+
if not get_option('tests').disabled()
subdir('test')
endif
@@ -524,6 +536,7 @@ if meson.version().version_compare('>=0.53.0')
'Tests': not get_option('tests').disabled(),
'Examples': not get_option('examples').disabled(),
'Documentation': build_docs,
+ 'C++ bindings': not get_option('bindings_cpp').disabled(),
},
bool_yn: true,
section: 'Components',
diff --git a/meson_options.txt b/meson_options.txt
index 6e92100..571a640 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,18 +1,21 @@
-# Copyright 2021-2024 David Robillard <d@drobilla.net>
+# Copyright 2021-2025 David Robillard <d@drobilla.net>
# SPDX-License-Identifier: 0BSD OR ISC
+option('bindings_cpp', type: 'feature', yield: true,
+ description: 'Build C++ bindings')
+
option('cairo', type: 'feature',
description: 'Enable support for the Cairo graphics API')
-option('examples', type: 'feature', yield: true,
- description: 'Build example programs')
-
option('docs', type: 'feature', yield: true,
description: 'Build documentation')
option('docs_cpp', type: 'boolean', value: false,
description: 'Attempt to build C++ documentation for development')
+option('examples', type: 'feature', yield: true,
+ description: 'Build example programs')
+
option('lint', type: 'boolean', value: false, yield: true,
description: 'Run code quality checks')
diff --git a/src/common.c b/src/common.c
index 2e6e0e6..c8ac3d4 100644
--- a/src/common.c
+++ b/src/common.c
@@ -4,14 +4,13 @@
// 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>
#include <string.h>
@@ -105,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*
@@ -137,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;
@@ -286,32 +290,37 @@ 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 (!puglIsValidPosition(x, y)) {
- 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
diff --git a/src/internal.c b/src/internal.c
index 38a595a..ca84ed1 100644
--- a/src/internal.c
+++ b/src/internal.c
@@ -5,7 +5,7 @@
#include "types.h"
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#include <assert.h>
#include <stdbool.h>
@@ -23,7 +23,8 @@ make_point(const PuglCoord x, const PuglCoord y)
bool
puglIsValidPosition(const int x, const int y)
{
- return x >= INT16_MIN && x <= INT16_MAX && y >= INT16_MIN && y <= INT16_MAX;
+ // 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
@@ -60,9 +61,10 @@ puglGetInitialPosition(const PuglView* const view, const PuglArea size)
return make_point(view->lastConfigure.x, view->lastConfigure.y);
}
- if (puglIsValidPosition(view->defaultX, view->defaultY)) {
+ 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((PuglCoord)view->defaultX, (PuglCoord)view->defaultY);
+ return make_point(defaultPos.x, defaultPos.y);
}
if (view->parent) {
@@ -247,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 7387494..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>
@@ -62,7 +62,6 @@ puglStoreSizeHint(PuglView* view,
unsigned height);
/// Handle a changed string property
-PUGL_API
PuglStatus
puglViewStringChanged(PuglView* view, PuglStringHint key, const char* value);
@@ -83,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 5f9d71e..41d358a 100644
--- a/src/mac.m
+++ b/src/mac.m
@@ -10,7 +10,7 @@
#include "macros.h"
#include "platform.h"
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#import <Cocoa/Cocoa.h>
@@ -151,12 +151,6 @@ nsPointFromPoints(const PuglView* view, const NSPoint point)
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 PuglSpan width, const PuglSpan height)
{
@@ -200,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,
@@ -250,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,
@@ -332,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),
@@ -497,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,
@@ -538,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,
@@ -573,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,
@@ -594,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,
@@ -653,7 +647,7 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
const PuglScrollEvent ev = {
PUGL_SCROLL,
- 0,
+ 0U,
[event timestamp],
wloc.x,
wloc.y,
@@ -685,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,
@@ -716,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,
@@ -828,7 +822,7 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
PuglTextEvent ev = {
PUGL_TEXT,
- 0,
+ 0U,
[event timestamp],
wloc.x,
wloc.y,
@@ -878,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,
@@ -920,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;
@@ -985,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);
}
@@ -994,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);
}
@@ -1124,6 +1118,7 @@ updateSizeHint(PuglView* const view, const PuglSizeHint hint)
switch (hint) {
case PUGL_DEFAULT_SIZE:
+ case PUGL_CURRENT_SIZE:
break;
case PUGL_MIN_SIZE:
@@ -1166,8 +1161,8 @@ puglGetAncestorCenter(const PuglView* const view)
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)};
+ (PuglCoord)(boundsPx.origin.x + (boundsPx.size.width / 2.0)),
+ (PuglCoord)(boundsPx.origin.y + (boundsPx.size.height / 2.0))};
return center;
}
@@ -1216,13 +1211,12 @@ puglRealize(PuglView* view)
CVDisplayLinkRelease(link);
}
- // Get the initial frame to use from the defaults or last configuration
- const PuglArea size = puglGetInitialSize(view);
- const PuglPoint pos = puglGetInitialPosition(view, size);
- const PuglRect initialFrame = {pos.x, pos.y, size.width, size.height};
+ // 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,
@@ -1308,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);
@@ -1581,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)
{
@@ -1626,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)
{
@@ -1720,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 (!puglIsValidPosition(x, y)) {
- 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 (!puglIsValidSize(width, height)) {
- 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];
@@ -1833,11 +1748,40 @@ 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
+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;
+ }
+
+ 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,
@@ -1845,7 +1789,9 @@ puglSetSizeHint(PuglView* const view,
{
const PuglStatus st = puglStoreSizeHint(view, hint, width, height);
- return (!st && view->impl->window) ? updateSizeHint(view, hint) : st;
+ return st ? st
+ : (hint == PUGL_CURRENT_SIZE) ? puglSetWindowSize(view, width, height)
+ : updateSizeHint(view, hint);
}
PuglStatus
@@ -1873,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 bbebbb7..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;
-} PuglArea;
-
/// Blob of arbitrary data
typedef struct {
void* data; ///< Dynamically allocated data
@@ -57,10 +45,9 @@ struct PuglViewImpl {
uintptr_t transientParent;
PuglConfigureEvent lastConfigure;
PuglHints 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 2cefd8b..a8cd841 100644
--- a/src/win.c
+++ b/src/win.c
@@ -7,7 +7,7 @@
#include "macros.h"
#include "platform.h"
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#include <dwmapi.h>
#include <windows.h>
@@ -44,7 +44,8 @@
#ifdef __cplusplus
# define PUGL_INIT_STRUCT \
- {}
+ { \
+ }
#else
# define PUGL_INIT_STRUCT {0}
#endif
@@ -314,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));
@@ -349,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;
}
}
@@ -385,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;
}
@@ -679,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,
@@ -689,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);
}
@@ -739,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;
@@ -801,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);
}
@@ -954,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
@@ -1040,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
@@ -1055,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)
{
@@ -1156,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)
{
@@ -1199,8 +1174,7 @@ puglGetTime(const PuglWorld* world)
PuglStatus
puglObscureView(PuglView* view)
{
- InvalidateRect(view->impl->hwnd, NULL, false);
- return PUGL_SUCCESS;
+ return puglWinStatus(InvalidateRect(view->impl->hwnd, NULL, false));
}
PuglStatus
@@ -1220,9 +1194,7 @@ puglObscureRegion(PuglView* const view,
const unsigned ch = MIN(view->lastConfigure.height, height);
const RECT r = {cx, cy, cx + (long)cw, cy + (long)ch};
- InvalidateRect(view->impl->hwnd, &r, false);
-
- return PUGL_SUCCESS;
+ return puglWinStatus(InvalidateRect(view->impl->hwnd, &r, false));
}
PuglNativeView
@@ -1236,17 +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) {
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
@@ -1271,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 (!puglIsValidPosition(x, y)) {
- 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);
@@ -1320,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 (!puglIsValidSize(width, height)) {
- 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,
@@ -1353,12 +1281,33 @@ puglSetSize(PuglView* const view, const unsigned width, const unsigned height)
}
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;
+ }
+
+ 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)
{
- return puglStoreSizeHint(view, hint, width, height);
+ const PuglStatus st = puglStoreSizeHint(view, hint, width, height);
+
+ return (!st && hint == PUGL_CURRENT_SIZE)
+ ? puglSetWindowSize(view, width, height)
+ : st;
}
PuglStatus
@@ -1404,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*
@@ -1422,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;
}
@@ -1434,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
@@ -1453,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;
}
@@ -1498,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[] = {
@@ -1582,8 +1541,8 @@ puglGetAncestorCenter(const PuglView* const view)
&rect);
const PuglPoint center = {
- (PuglCoord)(rect.left + (rect.right - rect.left) / 2),
- (PuglCoord)(rect.top + (rect.bottom - rect.top) / 2)};
+ (PuglCoord)(rect.left + ((rect.right - rect.left) / 2)),
+ (PuglCoord)(rect.top + ((rect.bottom - rect.top) / 2))};
return center;
}
@@ -1653,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;
}
@@ -1666,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 8607bdd..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>
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 f60528b..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,7 +70,8 @@
#ifdef __cplusplus
# define PUGL_INIT_STRUCT \
- {}
+ { \
+ }
#else
# define PUGL_INIT_STRUCT {0}
#endif
@@ -404,14 +405,18 @@ 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 PuglArea defaultSize = view->sizeHints[PUGL_DEFAULT_SIZE];
@@ -522,8 +527,8 @@ puglGetAncestorCenter(const PuglView* const view)
&ancestorAttrs);
const PuglPoint center = {
- (PuglCoord)(ancestorAttrs.x + ancestorAttrs.width / 2),
- (PuglCoord)(ancestorAttrs.y + ancestorAttrs.height / 2)};
+ (PuglCoord)(ancestorAttrs.x + (ancestorAttrs.width / 2)),
+ (PuglCoord)(ancestorAttrs.y + (ancestorAttrs.height / 2))};
return center;
}
@@ -1000,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];
@@ -1083,7 +1088,7 @@ getCurrentConfiguration(PuglView* const view)
}
// Build a configure event based on the current window configuration
- PuglEvent configureEvent = {{PUGL_CONFIGURE, 0}};
+ PuglEvent configureEvent = {{PUGL_CONFIGURE, 0U}};
configureEvent.configure.x = (PuglCoord)x;
configureEvent.configure.y = (PuglCoord)y;
configureEvent.configure.width = (PuglSpan)attrs.width;
@@ -1114,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
@@ -1164,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) {
@@ -1185,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;
@@ -1508,16 +1516,6 @@ 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)
{
@@ -1586,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
@@ -1596,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;
@@ -1673,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;
@@ -1727,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);
}
@@ -1825,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)
{
@@ -1871,7 +1860,10 @@ 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;
}
@@ -1899,14 +1891,14 @@ puglObscureRegion(PuglView* const view,
const PuglSpan cw = MIN(view->lastConfigure.width, (PuglSpan)width);
const PuglSpan ch = MIN(view->lastConfigure.height, (PuglSpan)height);
- const PuglExposeEvent event = {PUGL_EXPOSE, 0, cx, cy, cw, ch};
+ 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);
}
@@ -1960,65 +1952,41 @@ 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 (!puglIsValidPosition(x, y)) {
- 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 (!puglIsValidSize(width, height)) {
+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
@@ -2029,7 +1997,9 @@ puglSetSizeHint(PuglView* const view,
{
const PuglStatus st = puglStoreSizeHint(view, hint, width, height);
- return st ? st : 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 ff0b154..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>
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>
diff --git a/test/test_utils.h b/subprojects/puglutil/include/puglutil/test_utils.h
index 4ebd985..6419e16 100644
--- a/test/test_utils.h
+++ b/subprojects/puglutil/include/puglutil/test_utils.h
@@ -4,7 +4,7 @@
#ifndef TEST_TEST_UTILS_H
#define TEST_TEST_UTILS_H
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#include <inttypes.h>
#include <stdarg.h>
diff --git a/subprojects/puglutil/meson.build b/subprojects/puglutil/meson.build
new file mode 100644
index 0000000..e7ffece
--- /dev/null
+++ b/subprojects/puglutil/meson.build
@@ -0,0 +1,14 @@
+# Copyright 2025 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+project(
+ 'puglutil',
+ ['c'],
+ license: 'ISC',
+ meson_version: '>= 0.54.0',
+ version: '0.0.0',
+)
+
+puglutil_dep = declare_dependency(
+ include_directories: include_directories(['include']),
+)
diff --git a/test/.clang-tidy b/test/.clang-tidy
index 456eb2e..4dbdc80 100644
--- a/test/.clang-tidy
+++ b/test/.clang-tidy
@@ -3,7 +3,6 @@
Checks: >
-bugprone-multi-level-implicit-pointer-conversion,
- -bugprone-suspicious-include,
-cert-err33-c,
-cert-err34-c,
-clang-analyzer-optin.core.EnumCastOutOfRange,
diff --git a/test/cpp/.clang-tidy b/test/cpp/.clang-tidy
index 1d936a2..fe7d8ec 100644
--- a/test/cpp/.clang-tidy
+++ b/test/cpp/.clang-tidy
@@ -5,6 +5,7 @@ Checks: >
-*-use-auto,
-*-use-nullptr,
-bugprone-easily-swappable-parameters,
+ -bugprone-suspicious-include,
-cert-dcl50-cpp,
-cppcoreguidelines-avoid-c-arrays,
-cppcoreguidelines-avoid-do-while,
diff --git a/test/cpp/meson.build b/test/cpp/meson.build
index 73e2320..94c64d1 100644
--- a/test/cpp/meson.build
+++ b/test/cpp/meson.build
@@ -54,6 +54,7 @@ if host_machine.system() == 'darwin'
'test_inline_objcpp',
'test_inline_objcpp.mm',
dependencies: unified_deps,
+ implicit_include_directories: false,
include_directories: include_directories('../../include'),
objcpp_args: objcpp_unified_args,
),
@@ -99,6 +100,7 @@ elif is_variable('cpp')
'test_inline_cpp.cpp',
cpp_args: cpp_unified_args,
dependencies: unified_deps,
+ implicit_include_directories: false,
include_directories: include_directories('../../include'),
),
suite: 'unit',
diff --git a/test/cpp/test_build.cpp b/test/cpp/test_build.cpp
index 4fd2dac..2419be9 100644
--- a/test/cpp/test_build.cpp
+++ b/test/cpp/test_build.cpp
@@ -1,17 +1,13 @@
// Copyright 2020 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
-/*
- Tests that C++ headers compile without any warnings.
-*/
+// Tests that C++ headers compile without any warnings
-#define PUGL_DISABLE_DEPRECATED
-
-#include "pugl/cairo.hpp" // IWYU pragma: keep
-#include "pugl/gl.hpp" // IWYU pragma: keep
-#include "pugl/pugl.h" // IWYU pragma: keep
-#include "pugl/pugl.hpp" // IWYU pragma: keep
-#include "pugl/stub.hpp" // IWYU pragma: keep
+#include <pugl/cairo.hpp> // IWYU pragma: keep
+#include <pugl/gl.hpp> // IWYU pragma: keep
+#include <pugl/pugl.h> // IWYU pragma: keep
+#include <pugl/pugl.hpp> // IWYU pragma: keep
+#include <pugl/stub.hpp> // IWYU pragma: keep
int
main()
diff --git a/test/cpp/test_inline_cpp.cpp b/test/cpp/test_inline_cpp.cpp
index f5694eb..4c47ffb 100644
--- a/test/cpp/test_inline_cpp.cpp
+++ b/test/cpp/test_inline_cpp.cpp
@@ -23,34 +23,34 @@
# pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif
-#include "../src/common.c" // IWYU pragma: keep
-#include "../src/internal.c" // IWYU pragma: keep
+#include "../../src/common.c" // IWYU pragma: keep
+#include "../../src/internal.c" // IWYU pragma: keep
#if defined(_WIN32)
-# include "../src/win.c" // IWYU pragma: keep
-# include "../src/win.h" // IWYU pragma: keep
-# include "../src/win_stub.c" // IWYU pragma: keep
+# include "../../src/win.c" // IWYU pragma: keep
+# include "../../src/win.h" // IWYU pragma: keep
+# include "../../src/win_stub.c" // IWYU pragma: keep
# if defined(WITH_CAIRO)
-# include "../src/win_cairo.c" // IWYU pragma: keep
+# include "../../src/win_cairo.c" // IWYU pragma: keep
# endif
# if defined(WITH_OPENGL)
-# include "../src/win_gl.c" // IWYU pragma: keep
+# include "../../src/win_gl.c" // IWYU pragma: keep
# endif
# if defined(WITH_VULKAN)
-# include "../src/win_vulkan.c" // IWYU pragma: keep
+# include "../../src/win_vulkan.c" // IWYU pragma: keep
# endif
#else
-# include "../src/x11.c" // IWYU pragma: keep
-# include "../src/x11_stub.c" // IWYU pragma: keep
+# include "../../src/x11.c" // IWYU pragma: keep
+# include "../../src/x11_stub.c" // IWYU pragma: keep
# if defined(WITH_CAIRO)
-# include "../src/x11_cairo.c" // IWYU pragma: keep
+# include "../../src/x11_cairo.c" // IWYU pragma: keep
# endif
# if defined(WITH_OPENGL)
-# include "../src/x11_gl.c" // IWYU pragma: keep
+# include "../../src/x11_gl.c" // IWYU pragma: keep
# endif
# if defined(WITH_VULKAN)
-# include "../src/x11_vulkan.c" // IWYU pragma: keep
+# include "../../src/x11_vulkan.c" // IWYU pragma: keep
# endif
#endif
diff --git a/test/cpp/test_inline_objcpp.mm b/test/cpp/test_inline_objcpp.mm
index 1c9079b..b4d65c6 100644
--- a/test/cpp/test_inline_objcpp.mm
+++ b/test/cpp/test_inline_objcpp.mm
@@ -9,22 +9,22 @@
# pragma clang diagnostic ignored "-Wold-style-cast"
#endif
-#include "../src/common.c" // IWYU pragma: keep
-#include "../src/internal.c" // IWYU pragma: keep
-#include "../src/mac.h" // IWYU pragma: keep
-#include "../src/mac.m" // IWYU pragma: keep
-#include "../src/mac_stub.m" // IWYU pragma: keep
+#include "../../src/common.c" // IWYU pragma: keep
+#include "../../src/internal.c" // IWYU pragma: keep
+#include "../../src/mac.h" // IWYU pragma: keep
+#include "../../src/mac.m" // IWYU pragma: keep
+#include "../../src/mac_stub.m" // IWYU pragma: keep
#if defined(WITH_CAIRO)
-# include "../src/mac_cairo.m" // IWYU pragma: keep
+# include "../../src/mac_cairo.m" // IWYU pragma: keep
#endif
#if defined(WITH_OPENGL)
-# include "../src/mac_gl.m" // IWYU pragma: keep
+# include "../../src/mac_gl.m" // IWYU pragma: keep
#endif
#if defined(WITH_VULKAN)
-# include "../src/mac_vulkan.m" // IWYU pragma: keep
+# include "../../src/mac_vulkan.m" // IWYU pragma: keep
#endif
#if defined(__clang__)
diff --git a/test/headers/meson.build b/test/headers/meson.build
index c0adabd..69fd51b 100644
--- a/test/headers/meson.build
+++ b/test/headers/meson.build
@@ -11,7 +11,7 @@ if get_option('warning_level') == 'everything'
endif
endif
-header_c_suppressions = cpp.get_supported_arguments(header_c_suppressions)
+header_c_suppressions = cc.get_supported_arguments(header_c_suppressions)
test_headers_c_args = header_c_suppressions
test_headers_c_args += [
@@ -30,6 +30,7 @@ test(
files('test_headers.c'),
c_args: test_headers_c_args,
dependencies: [pugl_dep, vulkan_dep],
+ implicit_include_directories: false,
),
suite: 'unit',
)
diff --git a/test/meson.build b/test/meson.build
index f015596..f047ff0 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -1,4 +1,4 @@
-# Copyright 2021-2023 David Robillard <d@drobilla.net>
+# Copyright 2021-2025 David Robillard <d@drobilla.net>
# SPDX-License-Identifier: 0BSD OR ISC
# Suppress some additional C warnings in tests
@@ -56,11 +56,6 @@ if with_timers
basic_tests += ['timer']
endif
-includes = [
- '.',
- '../include',
-]
-
foreach test : basic_tests
test(
test,
@@ -68,8 +63,8 @@ foreach test : basic_tests
'test_' + test,
'test_@0@.c'.format(test),
c_args: test_c_args,
- dependencies: [pugl_dep, pugl_stub_dep],
- include_directories: include_directories(includes),
+ dependencies: [pugl_dep, pugl_stub_dep, puglutil_dep],
+ implicit_include_directories: false,
),
suite: 'unit',
)
@@ -82,8 +77,8 @@ foreach test : basic_exclusive_tests
'test_' + test,
'test_@0@.c'.format(test),
c_args: test_c_args,
- dependencies: [pugl_dep, pugl_stub_dep],
- include_directories: include_directories(includes),
+ dependencies: [pugl_dep, pugl_stub_dep, puglutil_dep],
+ implicit_include_directories: false,
),
is_parallel: false,
suite: 'unit',
@@ -98,8 +93,8 @@ if opengl_dep.found()
'test_' + test,
'test_@0@.c'.format(test),
c_args: test_c_args,
- dependencies: [pugl_dep, pugl_gl_dep],
- include_directories: include_directories(includes),
+ dependencies: [pugl_dep, pugl_gl_dep, puglutil_dep],
+ implicit_include_directories: false,
),
suite: 'unit',
)
@@ -114,8 +109,8 @@ if cairo_dep.found()
'test_' + test,
'test_@0@.c'.format(test),
c_args: test_c_args + cairo_args,
- dependencies: [pugl_dep, pugl_cairo_dep],
- include_directories: include_directories(includes),
+ dependencies: [pugl_dep, pugl_cairo_dep, puglutil_dep],
+ implicit_include_directories: false,
),
suite: 'unit',
)
@@ -130,8 +125,8 @@ if vulkan_dep.found()
'test_' + test,
'test_@0@.c'.format(test),
c_args: test_c_args,
- dependencies: [pugl_dep, pugl_vulkan_dep],
- include_directories: include_directories(includes),
+ dependencies: [pugl_dep, pugl_vulkan_dep, puglutil_dep],
+ implicit_include_directories: false,
),
suite: 'unit',
)
@@ -148,4 +143,6 @@ subdir('headers')
# C++ / Objective C++ #
#######################
-subdir('cpp')
+if is_variable('cpp')
+ subdir('cpp')
+endif
diff --git a/test/test_build.c b/test/test_build.c
index e28df3c..4f66eca 100644
--- a/test/test_build.c
+++ b/test/test_build.c
@@ -1,17 +1,13 @@
// Copyright 2020 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
-/*
- Tests that C headers compile without any warnings.
-*/
+// Tests that C headers compile without any warnings
-#define PUGL_DISABLE_DEPRECATED
-
-#include "pugl/cairo.h" // IWYU pragma: keep
-#include "pugl/gl.h" // IWYU pragma: keep
-#include "pugl/glu.h" // IWYU pragma: keep
-#include "pugl/pugl.h" // IWYU pragma: keep
-#include "pugl/stub.h" // IWYU pragma: keep
+#include <pugl/cairo.h> // IWYU pragma: keep
+#include <pugl/gl.h> // IWYU pragma: keep
+#include <pugl/glu.h> // IWYU pragma: keep
+#include <pugl/pugl.h> // IWYU pragma: keep
+#include <pugl/stub.h> // IWYU pragma: keep
int
main(void)
diff --git a/test/test_cairo.c b/test/test_cairo.c
index 11d6cce..9abc51e 100644
--- a/test/test_cairo.c
+++ b/test/test_cairo.c
@@ -5,10 +5,10 @@
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/cairo.h"
-#include "pugl/pugl.h"
+#include <pugl/cairo.h>
+#include <pugl/pugl.h>
#include <cairo.h>
@@ -66,7 +66,7 @@ main(int argc, char** argv)
puglSetBackend(test.view, puglCairoBackend());
puglSetEventFunc(test.view, onEvent);
puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(test.view, 128, 896);
+ puglSetPositionHint(test.view, PUGL_DEFAULT_POSITION, 128, 896);
puglShow(test.view, PUGL_SHOW_RAISE);
// Drive event loop until the view gets exposed
diff --git a/test/test_clipboard.c b/test/test_clipboard.c
index debe8e3..054f71d 100644
--- a/test/test_clipboard.c
+++ b/test/test_clipboard.c
@@ -9,8 +9,8 @@
#include "test_utils.h"
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
#include <assert.h>
#include <stdbool.h>
diff --git a/test/test_cursor.c b/test/test_cursor.c
index 9b0fa66..399f797 100644
--- a/test/test_cursor.c
+++ b/test/test_cursor.c
@@ -5,10 +5,10 @@
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
#include <assert.h>
#include <stdbool.h>
@@ -52,7 +52,7 @@ main(int argc, char** argv)
puglSetBackend(test.view, puglStubBackend());
puglSetEventFunc(test.view, onEvent);
puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(test.view, 896, 640);
+ puglSetPositionHint(test.view, PUGL_DEFAULT_POSITION, 896, 640);
puglShow(test.view, PUGL_SHOW_RAISE);
// Drive event loop until the view gets exposed
diff --git a/test/test_gl.c b/test/test_gl.c
index 8854cad..dac41b5 100644
--- a/test/test_gl.c
+++ b/test/test_gl.c
@@ -5,10 +5,10 @@
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/gl.h"
-#include "pugl/pugl.h"
+#include <pugl/gl.h>
+#include <pugl/pugl.h>
#include <assert.h>
#include <stdbool.h>
@@ -85,7 +85,7 @@ main(int argc, char** argv)
puglSetBackend(test.view, puglGlBackend());
puglSetEventFunc(test.view, onEvent);
puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(test.view, 384, 896);
+ puglSetPositionHint(test.view, PUGL_DEFAULT_POSITION, 384, 896);
puglShow(test.view, PUGL_SHOW_RAISE);
// Enter OpenGL context as if setting things up
diff --git a/test/test_gl_free_unrealized.c b/test/test_gl_free_unrealized.c
index ba0d895..7ff8913 100644
--- a/test/test_gl_free_unrealized.c
+++ b/test/test_gl_free_unrealized.c
@@ -9,8 +9,8 @@
#undef NDEBUG
-#include "pugl/gl.h"
-#include "pugl/pugl.h"
+#include <pugl/gl.h>
+#include <pugl/pugl.h>
#include <assert.h>
#include <stddef.h>
@@ -32,7 +32,7 @@ main(void)
puglSetBackend(test.view, puglGlBackend());
puglSetHandle(test.view, &test);
puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(test.view, 640, 896);
+ puglSetPositionHint(test.view, PUGL_DEFAULT_POSITION, 640, 896);
assert(!puglGetVisible(test.view));
diff --git a/test/test_gl_hints.c b/test/test_gl_hints.c
index 250136a..824679a 100644
--- a/test/test_gl_hints.c
+++ b/test/test_gl_hints.c
@@ -1,16 +1,14 @@
// Copyright 2020 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
-/*
- Tests that all hints are set to real values after a view is realized.
-*/
+// Tests that all hints are set to real values after a view is realized
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/gl.h"
-#include "pugl/pugl.h"
+#include <pugl/gl.h>
+#include <pugl/pugl.h>
#include <assert.h>
@@ -35,7 +33,7 @@ main(void)
puglSetBackend(view, puglGlBackend());
puglSetEventFunc(view, onEvent);
puglSetSizeHint(view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(view, 128, 128);
+ puglSetPositionHint(view, PUGL_DEFAULT_POSITION, 128, 128);
// Check invalid cases
assert(puglSetViewHint(view, PUGL_CONTEXT_API, PUGL_DONT_CARE) ==
diff --git a/test/test_local_copy_paste.c b/test/test_local_copy_paste.c
index 737f193..6d4899e 100644
--- a/test/test_local_copy_paste.c
+++ b/test/test_local_copy_paste.c
@@ -5,10 +5,10 @@
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
#include <assert.h>
#include <stdbool.h>
@@ -133,7 +133,7 @@ main(int argc, char** argv)
puglSetHandle(app.view, &app);
puglSetEventFunc(app.view, onEvent);
puglSetSizeHint(app.view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(app.view, 384, 128);
+ puglSetPositionHint(app.view, PUGL_DEFAULT_POSITION, 384, 128);
// Create and show window
assert(!puglRealize(app.view));
diff --git a/test/test_realize.c b/test/test_realize.c
index 7e37319..3d706ce 100644
--- a/test/test_realize.c
+++ b/test/test_realize.c
@@ -11,10 +11,10 @@
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
#include <assert.h>
#include <stdbool.h>
@@ -75,7 +75,7 @@ main(int argc, char** argv)
assert(puglRealize(test.view) == PUGL_BAD_CONFIGURATION);
puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(test.view, 640, 128);
+ puglSetPositionHint(test.view, PUGL_DEFAULT_POSITION, 640, 128);
// Create initially invisible window
assert(!puglRealize(test.view));
diff --git a/test/test_redisplay.c b/test/test_redisplay.c
index ae7267d..01be5b6 100644
--- a/test/test_redisplay.c
+++ b/test/test_redisplay.c
@@ -8,10 +8,10 @@
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
#include <assert.h>
#include <stdbool.h>
@@ -119,7 +119,7 @@ main(int argc, char** argv)
puglSetHandle(test.view, &test);
puglSetEventFunc(test.view, onEvent);
puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(test.view, 896, 128);
+ puglSetPositionHint(test.view, PUGL_DEFAULT_POSITION, 896, 128);
// Create and show window
assert(!puglRealize(test.view));
@@ -129,7 +129,7 @@ main(int argc, char** argv)
}
// Send a custom event to trigger a redisplay in the event loop
- PuglEvent client_event = {{PUGL_CLIENT, 0}};
+ PuglEvent client_event = {{PUGL_CLIENT, 0U}};
client_event.client.data1 = obscureId;
client_event.client.data2 = 0;
assert(!puglSendEvent(test.view, &client_event));
diff --git a/test/test_remote_copy_paste.c b/test/test_remote_copy_paste.c
index a9f079e..3d1756b 100644
--- a/test/test_remote_copy_paste.c
+++ b/test/test_remote_copy_paste.c
@@ -5,10 +5,10 @@
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
#include <assert.h>
#include <stdbool.h>
@@ -148,7 +148,7 @@ main(int argc, char** argv)
puglSetHandle(app.copierView, &app);
puglSetEventFunc(app.copierView, onCopierEvent);
puglSetSizeHint(app.copierView, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(app.copierView, 640, 896);
+ puglSetPositionHint(app.copierView, PUGL_DEFAULT_POSITION, 640, 896);
// Set up paster view
app.pasterView = puglNewView(app.world);
@@ -158,7 +158,7 @@ main(int argc, char** argv)
puglSetHandle(app.pasterView, &app);
puglSetEventFunc(app.pasterView, onPasterEvent);
puglSetSizeHint(app.pasterView, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(app.pasterView, 896, 896);
+ puglSetPositionHint(app.pasterView, PUGL_DEFAULT_POSITION, 896, 896);
// Create and show both views
assert(!puglShow(app.copierView, PUGL_SHOW_RAISE));
diff --git a/test/test_show_hide.c b/test/test_show_hide.c
index 1517203..8b67325 100644
--- a/test/test_show_hide.c
+++ b/test/test_show_hide.c
@@ -8,10 +8,10 @@
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
#include <assert.h>
#include <stdbool.h>
@@ -115,7 +115,7 @@ main(int argc, char** argv)
puglSetHandle(test.view, &test);
puglSetEventFunc(test.view, onEvent);
puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(test.view, 128, 384);
+ puglSetPositionHint(test.view, PUGL_DEFAULT_POSITION, 128, 384);
// Create initially invisible window
assert(!puglRealize(test.view));
diff --git a/test/test_size.c b/test/test_size.c
index e3f738a..9c9f518 100644
--- a/test/test_size.c
+++ b/test/test_size.c
@@ -5,10 +5,10 @@
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
#include <assert.h>
#include <stdbool.h>
@@ -26,7 +26,8 @@ typedef struct {
PuglView* view;
PuglTestOptions opts;
State state;
- PuglRect configuredFrame;
+ PuglPoint configuredPos;
+ PuglArea configuredSize;
} PuglTest;
static PuglStatus
@@ -47,10 +48,10 @@ onEvent(PuglView* view, const PuglEvent* event)
if (test->state == REALIZED) {
test->state = CONFIGURED;
}
- test->configuredFrame.x = event->configure.x;
- test->configuredFrame.y = event->configure.y;
- test->configuredFrame.width = event->configure.width;
- test->configuredFrame.height = event->configure.height;
+ test->configuredPos.x = event->configure.x;
+ test->configuredPos.y = event->configure.y;
+ test->configuredSize.width = event->configure.width;
+ test->configuredSize.height = event->configure.height;
break;
case PUGL_UNREALIZE:
test->state = UNREALIZED;
@@ -73,7 +74,8 @@ main(int argc, char** argv)
NULL,
puglParseTestOptions(&argc, &argv),
START,
- {0, 0, 0U, 0U}};
+ {0, 0},
+ {0U, 0U}};
// Set up view with size bounds and an aspect ratio
test.view = puglNewView(test.world);
@@ -87,7 +89,7 @@ main(int argc, char** argv)
puglSetSizeHint(test.view, PUGL_MIN_SIZE, minSize, minSize);
puglSetSizeHint(test.view, PUGL_MAX_SIZE, maxSize, maxSize);
puglSetSizeHint(test.view, PUGL_FIXED_ASPECT, 1, 1);
- puglSetPosition(test.view, 384, 384);
+ puglSetPositionHint(test.view, PUGL_DEFAULT_POSITION, 384, 384);
// Create and show window
assert(!puglRealize(test.view));
@@ -97,21 +99,22 @@ main(int argc, char** argv)
}
// Check that the frame matches the last configure event
- const PuglRect frame = puglGetFrame(test.view);
- assert(frame.x == test.configuredFrame.x);
- assert(frame.y == test.configuredFrame.y);
- assert(frame.width == test.configuredFrame.width);
- assert(frame.height == test.configuredFrame.height);
+ const PuglPoint pos = puglGetPositionHint(test.view, PUGL_CURRENT_POSITION);
+ const PuglArea size = puglGetSizeHint(test.view, PUGL_CURRENT_SIZE);
+ assert(pos.x == test.configuredPos.x);
+ assert(pos.y == test.configuredPos.y);
+ assert(size.width == test.configuredSize.width);
+ assert(size.height == test.configuredSize.height);
#if defined(_WIN32) || defined(__APPLE__)
/* Some window managers on Linux (particularly tiling ones) just disregard
these hints entirely, so we only check that the size is in bounds on MacOS
and Windows where this is more or less universally supported. */
- assert(frame.width >= minSize);
- assert(frame.height >= minSize);
- assert(frame.width <= maxSize);
- assert(frame.height <= maxSize);
+ assert(size.width >= minSize);
+ assert(size.height >= minSize);
+ assert(size.width <= maxSize);
+ assert(size.height <= maxSize);
#endif
// Tear down
diff --git a/test/test_strerror.c b/test/test_strerror.c
index c120a93..4bce4eb 100644
--- a/test/test_strerror.c
+++ b/test/test_strerror.c
@@ -5,7 +5,7 @@
#undef NDEBUG
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#include <assert.h>
#include <ctype.h>
diff --git a/test/test_stub.c b/test/test_stub.c
index bd8a0eb..7913fd4 100644
--- a/test/test_stub.c
+++ b/test/test_stub.c
@@ -5,10 +5,10 @@
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
#include <assert.h>
#include <stdbool.h>
@@ -52,7 +52,7 @@ main(int argc, char** argv)
puglSetBackend(test.view, puglStubBackend());
puglSetEventFunc(test.view, onEvent);
puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(test.view, 384, 896);
+ puglSetPositionHint(test.view, PUGL_DEFAULT_POSITION, 384, 896);
puglShow(test.view, PUGL_SHOW_RAISE);
// Drive event loop until the view gets exposed
diff --git a/test/test_stub_hints.c b/test/test_stub_hints.c
index b7d54e3..5694261 100644
--- a/test/test_stub_hints.c
+++ b/test/test_stub_hints.c
@@ -1,16 +1,14 @@
// Copyright 2020 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
-/*
- Tests that all hints are set to real values after a view is realized.
-*/
+// Tests that all hints are set to real values after a view is realized
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
#include <assert.h>
@@ -35,7 +33,7 @@ main(void)
puglSetBackend(view, puglStubBackend());
puglSetEventFunc(view, onEvent);
puglSetSizeHint(view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(view, 640, 384);
+ puglSetPositionHint(view, PUGL_DEFAULT_POSITION, 640, 384);
// Check invalid cases
assert(puglSetViewHint(view, (PuglViewHint)-1, 0) == PUGL_BAD_PARAMETER);
diff --git a/test/test_timer.c b/test/test_timer.c
index 405a5c2..8015b9a 100644
--- a/test/test_timer.c
+++ b/test/test_timer.c
@@ -8,10 +8,10 @@
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
#include <assert.h>
#include <math.h>
@@ -157,7 +157,7 @@ main(int argc, char** argv)
puglSetHandle(test.view, &test);
puglSetEventFunc(test.view, onEvent);
puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(test.view, 896, 384);
+ puglSetPositionHint(test.view, PUGL_DEFAULT_POSITION, 896, 384);
// Create and show window
assert(!puglRealize(test.view));
diff --git a/test/test_update.c b/test/test_update.c
index c5997ba..c078e6b 100644
--- a/test/test_update.c
+++ b/test/test_update.c
@@ -8,10 +8,10 @@
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
#include <assert.h>
#include <stdbool.h>
@@ -90,7 +90,7 @@ main(int argc, char** argv)
puglSetHandle(test.view, &test);
puglSetEventFunc(test.view, onEvent);
puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(test.view, 128, 640);
+ puglSetPositionHint(test.view, PUGL_DEFAULT_POSITION, 128, 640);
// Create and show window
assert(!puglRealize(test.view));
diff --git a/test/test_view.c b/test/test_view.c
index a6af9f2..08e5255 100644
--- a/test/test_view.c
+++ b/test/test_view.c
@@ -5,10 +5,10 @@
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/pugl.h"
-#include "pugl/stub.h"
+#include <pugl/pugl.h>
+#include <pugl/stub.h>
#include <assert.h>
#include <stdbool.h>
@@ -73,7 +73,7 @@ main(int argc, char** argv)
puglSetHandle(test.view, &test);
puglSetEventFunc(test.view, onEvent);
puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(test.view, 384, 640);
+ puglSetPositionHint(test.view, PUGL_DEFAULT_POSITION, 384, 640);
// Check basic accessors
assert(puglGetBackend(test.view) == puglStubBackend());
diff --git a/test/test_vulkan.c b/test/test_vulkan.c
index 3a7c612..258f978 100644
--- a/test/test_vulkan.c
+++ b/test/test_vulkan.c
@@ -5,10 +5,10 @@
#undef NDEBUG
-#include "test_utils.h"
+#include <puglutil/test_utils.h>
-#include "pugl/pugl.h"
-#include "pugl/vulkan.h"
+#include <pugl/pugl.h>
+#include <pugl/vulkan.h>
#include <vulkan/vulkan_core.h>
@@ -172,7 +172,7 @@ main(int argc, char** argv)
puglSetBackend(test.view, puglVulkanBackend());
puglSetEventFunc(test.view, onEvent);
puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 256, 256);
- puglSetPosition(test.view, 640, 640);
+ puglSetPositionHint(test.view, PUGL_DEFAULT_POSITION, 640, 640);
assert(!puglRealize(test.view));
// Create Vulkan surface for window
diff --git a/test/test_world.c b/test/test_world.c
index 18c8ef2..9d0d145 100644
--- a/test/test_world.c
+++ b/test/test_world.c
@@ -5,7 +5,7 @@
#undef NDEBUG
-#include "pugl/pugl.h"
+#include <pugl/pugl.h>
#include <assert.h>
#include <stdint.h>