diff --git a/doc/00_index.md b/doc/00_index.md index 34986e6e..88c76cb2 100644 --- a/doc/00_index.md +++ b/doc/00_index.md @@ -4,5 +4,9 @@ * [Initialization and the Main Loop](init-main.md) * [Event Handling](events.md) * [Controls](controls.md) +* Windows +** [Controls](windows-controls.md) +* Unix +** [Controls](unix-controls.md) * macOS ** [Controls](darwin-controls.md) diff --git a/doc/darwin-controls.md b/doc/darwin-controls.md index 503b38fc..fdc2e7e4 100644 --- a/doc/darwin-controls.md +++ b/doc/darwin-controls.md @@ -23,4 +23,4 @@ You are responsible for allocating and initializing this struct. To do so, you s Each method takes at least two parameters. The first, `c`, is the `uiControl` itself. The second, `implData`, is the implementation data pointer; it is the same as the pointer returned by `uiControlImplData(c)`, and is provided here as a convenience. -Each method is named for the `uiDarwinControl` function that it implements. As such, details on how to implement these methods are documented alongside those functions. For instance, instructions on implementing `TODO()` are given under the documentation for `TOOD()`. +Each method is named for the `uiDarwinControl` function that it implements. As such, details on how to implement these methods are documented alongside those functions. For instance, instructions on implementing `TODO()` are given under the documentation for `TODO()`. diff --git a/doc/unix-controls.md b/doc/unix-controls.md new file mode 100644 index 00000000..87fb4cc3 --- /dev/null +++ b/doc/unix-controls.md @@ -0,0 +1,26 @@ + + +# Controls on Unix systems other than macOS + +## Overview + +TODO + +## Reference + +### `uiControlOSVtable` + +```c +typedef struct uiControlOSVtable uiControlOSVtable; +struct uiControlOSVtable { + size_t Size; +}; +``` + +`uiControlOSVtable` describes the set of functions that control implementations on Unix need to implement. When registering your control type, you pass this in as a parameter to `uiRegisterControlType()`. Each method here is required. + +You are responsible for allocating and initializing this struct. To do so, you simply zero the memory for this struct and set its `Size` field to `sizeof (uiControlOSVtable)`. (TODO put this in a common place) + +Each method takes at least two parameters. The first, `c`, is the `uiControl` itself. The second, `implData`, is the implementation data pointer; it is the same as the pointer returned by `uiControlImplData(c)`, and is provided here as a convenience. + +Each method is named for the `uiUnixControl` function that it implements. As such, details on how to implement these methods are documented alongside those functions. For instance, instructions on implementing `TODO()` are given under the documentation for `TODO()`. diff --git a/doc/windows-controls.md b/doc/windows-controls.md new file mode 100644 index 00000000..6eef6eab --- /dev/null +++ b/doc/windows-controls.md @@ -0,0 +1,26 @@ + + +# Controls on Windows + +## Overview + +TODO + +## Reference + +### `uiControlOSVtable` + +```c +typedef struct uiControlOSVtable uiControlOSVtable; +struct uiControlOSVtable { + size_t Size; +}; +``` + +`uiControlOSVtable` describes the set of functions that control implementations on Windows need to implement. When registering your control type, you pass this in as a parameter to `uiRegisterControlType()`. Each method here is required. + +You are responsible for allocating and initializing this struct. To do so, you simply zero the memory for this struct and set its `Size` field to `sizeof (uiControlOSVtable)`. (TODO put this in a common place) + +Each method takes at least two parameters. The first, `c`, is the `uiControl` itself. The second, `implData`, is the implementation data pointer; it is the same as the pointer returned by `uiControlImplData(c)`, and is provided here as a convenience. + +Each method is named for the `uiWindowsControl` function that it implements. As such, details on how to implement these methods are documented alongside those functions. For instance, instructions on implementing `TODO()` are given under the documentation for `TODO()`. diff --git a/test/controls_windows.c b/test/controls_windows.c new file mode 100644 index 00000000..affdb52b --- /dev/null +++ b/test/controls_windows.c @@ -0,0 +1,11 @@ +// 10 june 2019 +#include "test_windows.h" + +static const uiControlOSVtable vtable = { + .Size = sizeof (uiControlOSVtable), +}; + +const uiControlOSVtable *testOSVtable(void) +{ + return &vtable; +} diff --git a/test/controls_windows_errors.cpp b/test/controls_windows_errors.cpp new file mode 100644 index 00000000..56b7c3e2 --- /dev/null +++ b/test/controls_windows_errors.cpp @@ -0,0 +1,17 @@ +// 16 june 2019 +#include "test_windows.h" + +const struct checkErrorCase controlOSVtableCases[] = { + { + "uiRegisterControlType() with OS vtable with wrong size", + [](void) { + uiControlOSVtable vtable; + + memset(&vtable, 0, sizeof (uiControlOSVtable)); + vtable.Size = 1; + uiRegisterControlType("name", testVtable(), &vtable, 0); + }, + "uiRegisterControlType(): wrong size 1 for uiControlOSVtable", + }, + { NULL, NULL, NULL }, +}; diff --git a/test/meson.build b/test/meson.build index b9aa1168..159d874a 100644 --- a/test/meson.build +++ b/test/meson.build @@ -14,6 +14,7 @@ libui_test_sources = [ if libui_OS == 'windows' libui_test_sources += [ 'controls_windows.c', + 'controls_windows_errors.cpp', ] elif libui_OS == 'darwin' libui_test_sources += [ diff --git a/test/test_windows.h b/test/test_windows.h new file mode 100644 index 00000000..2396dff5 --- /dev/null +++ b/test/test_windows.h @@ -0,0 +1,3 @@ +// 10 june 2019 +#define libuiOSHeader "../ui_windows.h" +#include "test.h" diff --git a/ui_windows.h b/ui_windows.h index cff24597..1bd916ff 100644 --- a/ui_windows.h +++ b/ui_windows.h @@ -11,6 +11,10 @@ This file assumes that you have included and "ui.h" beforehand. It p extern "C" { #endif +struct uiControlOSVtable { + size_t Size; +}; + #ifdef __cplusplus } #endif diff --git a/windows/controls.cpp b/windows/controls.cpp new file mode 100644 index 00000000..8dde1477 --- /dev/null +++ b/windows/controls.cpp @@ -0,0 +1,20 @@ +// 8 june 2019 +#include "uipriv_windows.hpp" + +bool uiprivOSVtableValid(const uiControlOSVtable *osVtable, const char *func) +{ + if (osVtable->Size != sizeof (uiControlOSVtable)) { + uiprivProgrammerErrorWrongStructSize(osVtable->Size, "uiControlOSVtable", func); + return false; + } + return true; +} + +uiControlOSVtable *uiprivCloneOSVtable(const uiControlOSVtable *osVtable) +{ + uiControlOSVtable *v2; + + v2 = uiprivNew(uiControlOSVtable); + *v2 = *osVtable; + return v2; +} diff --git a/windows/meson.build b/windows/meson.build index 15389b75..2528f009 100644 --- a/windows/meson.build +++ b/windows/meson.build @@ -3,6 +3,7 @@ windows = import('windows') libui_sources += [ + 'windows/controls.cpp', 'windows/main.cpp', 'windows/utilwin.cpp', 'windows/winhresult.cpp',