LMMS
Loading...
Searching...
No Matches
internal.c
Go to the documentation of this file.
1// Copyright 2012-2022 David Robillard <d@drobilla.net>
2// SPDX-License-Identifier: ISC
3
4#include "internal.h"
5
6#include "types.h"
7
8#include "pugl/pugl.h"
9
10#include <assert.h>
11#include <stdbool.h>
12#include <stdlib.h>
13#include <string.h>
14
16puglSetBlob(PuglBlob* const dest, const void* const data, const size_t len)
17{
18 if (data) {
19 void* const newData = realloc(dest->data, len + 1);
20 if (!newData) {
21 free(dest->data);
22 dest->len = 0;
23 return PUGL_NO_MEMORY;
24 }
25
26 memcpy(newData, data, len);
27 ((char*)newData)[len] = 0;
28
29 dest->len = len;
30 dest->data = newData;
31 } else {
32 dest->len = 0;
33 dest->data = NULL;
34 }
35
36 return PUGL_SUCCESS;
37}
38
39void
40puglSetString(char** dest, const char* string)
41{
42 if (*dest != string) {
43 const size_t len = strlen(string);
44
45 *dest = (char*)realloc(*dest, len + 1);
46 strncpy(*dest, string, len + 1);
47 }
48}
49
52{
53#define FAIL_IF(cond) \
54 do { \
55 if (cond) \
56 return 0xFFFD; \
57 } while (0)
58
59 // http://en.wikipedia.org/wiki/UTF-8
60
61 if (buf[0] < 0x80) {
62 return buf[0];
63 }
64
65 if (buf[0] < 0xC2) {
66 return 0xFFFD;
67 }
68
69 if (buf[0] < 0xE0) {
70 FAIL_IF((buf[1] & 0xC0u) != 0x80);
71 return ((uint32_t)buf[0] << 6u) + buf[1] - 0x3080u;
72 }
73
74 if (buf[0] < 0xF0) {
75 FAIL_IF((buf[1] & 0xC0u) != 0x80);
76 FAIL_IF(buf[0] == 0xE0 && buf[1] < 0xA0);
77 FAIL_IF((buf[2] & 0xC0u) != 0x80);
78 return ((uint32_t)buf[0] << 12u) + //
79 ((uint32_t)buf[1] << 6u) + //
80 ((uint32_t)buf[2] - 0xE2080u);
81 }
82
83 if (buf[0] < 0xF5) {
84 FAIL_IF((buf[1] & 0xC0u) != 0x80);
85 FAIL_IF(buf[0] == 0xF0 && buf[1] < 0x90);
86 FAIL_IF(buf[0] == 0xF4 && buf[1] >= 0x90);
87 FAIL_IF((buf[2] & 0xC0u) != 0x80u);
88 FAIL_IF((buf[3] & 0xC0u) != 0x80u);
89 return (((uint32_t)buf[0] << 18u) + //
90 ((uint32_t)buf[1] << 12u) + //
91 ((uint32_t)buf[2] << 6u) + //
92 ((uint32_t)buf[3] - 0x3C82080u));
93 }
94
95 return 0xFFFD;
96}
97
100{
104
105 const PuglEvent event = {{type, 0}};
106 return puglDispatchEvent(view, &event);
107}
108
109static inline bool
111{
112 return !!memcmp(configure, &view->lastConfigure, sizeof(PuglConfigureEvent));
113}
114
116puglConfigure(PuglView* view, const PuglEvent* event)
117{
119
120 assert(event->type == PUGL_CONFIGURE);
121
122 view->frame.x = event->configure.x;
123 view->frame.y = event->configure.y;
124 view->frame.width = event->configure.width;
125 view->frame.height = event->configure.height;
126
127 if (puglMustConfigure(view, &event->configure)) {
128 st = view->eventFunc(view, event);
129 view->lastConfigure = event->configure;
130 }
131
132 return st;
133}
134
136puglExpose(PuglView* view, const PuglEvent* event)
137{
138 return (event->expose.width > 0.0 && event->expose.height > 0.0)
139 ? view->eventFunc(view, event)
140 : PUGL_SUCCESS;
141}
142
145{
148
149 switch (event->type) {
150 case PUGL_NOTHING:
151 break;
152 case PUGL_CREATE:
153 case PUGL_DESTROY:
154 if (!(st0 = view->backend->enter(view, NULL))) {
155 st0 = view->eventFunc(view, event);
156 st1 = view->backend->leave(view, NULL);
157 }
158 break;
159 case PUGL_CONFIGURE:
160 if (puglMustConfigure(view, &event->configure)) {
161 if (!(st0 = view->backend->enter(view, NULL))) {
162 st0 = puglConfigure(view, event);
163 st1 = view->backend->leave(view, NULL);
164 }
165 }
166 break;
167 case PUGL_MAP:
168 if (!view->visible) {
169 view->visible = true;
170 st0 = view->eventFunc(view, event);
171 }
172 break;
173 case PUGL_UNMAP:
174 if (view->visible) {
175 view->visible = false;
176 st0 = view->eventFunc(view, event);
177 }
178 break;
179 case PUGL_EXPOSE:
180 if (!(st0 = view->backend->enter(view, &event->expose))) {
181 st0 = puglExpose(view, event);
182 st1 = view->backend->leave(view, &event->expose);
183 }
184 break;
185 default:
186 st0 = view->eventFunc(view, event);
187 }
188
189 return st0 ? st0 : st1;
190}
#define NULL
Definition CarlaBridgeFormat.cpp:30
assert(0)
CAdPlugDatabase::CRecord::RecordType type
Definition adplugdb.cpp:93
const PuglStatus st1
Definition pugl.h:1909
return st0 st0
Definition pugl.h:1912
PuglEventType
The type of a PuglEvent.
Definition pugl.h:179
@ PUGL_UPDATE
View ready to draw, a PuglUpdateEvent.
Definition pugl.h:186
@ PUGL_EXPOSE
View must be drawn, a PuglExposeEvent.
Definition pugl.h:187
@ PUGL_LOOP_LEAVE
Recursive loop left, a PuglLoopLeaveEvent.
Definition pugl.h:203
@ PUGL_LOOP_ENTER
Recursive loop entered, a PuglLoopEnterEvent.
Definition pugl.h:202
@ PUGL_CREATE
View created, a PuglCreateEvent.
Definition pugl.h:181
@ PUGL_CLOSE
View will be closed, a PuglCloseEvent.
Definition pugl.h:188
@ PUGL_UNMAP
View made invisible, a PuglUnmapEvent.
Definition pugl.h:185
@ PUGL_MAP
View made visible, a PuglMapEvent.
Definition pugl.h:184
@ PUGL_NOTHING
No event.
Definition pugl.h:180
@ PUGL_CONFIGURE
View moved/resized, a PuglConfigureEvent.
Definition pugl.h:183
@ PUGL_DESTROY
View destroyed, a PuglDestroyEvent.
Definition pugl.h:182
PuglStatus
Return status code.
Definition pugl.h:627
@ PUGL_SUCCESS
Success.
Definition pugl.h:628
@ PUGL_NO_MEMORY
Failed to allocate memory.
Definition pugl.h:640
struct PuglViewImpl PuglView
A drawable region that receives events.
Definition pugl.h:810
uint32_t puglDecodeUTF8(const uint8_t *buf)
Return the Unicode code point for buf or the replacement character.
Definition internal.c:51
PuglStatus puglSetBlob(PuglBlob *const dest, const void *const data, const size_t len)
Set blob to data with length len, reallocating if necessary.
Definition internal.c:16
#define FAIL_IF(cond)
PuglStatus puglExpose(PuglView *view, const PuglEvent *event)
Process expose event while already in the graphics context.
Definition internal.c:136
PuglStatus puglDispatchEvent(PuglView *view, const PuglEvent *event)
Dispatch event to view, entering graphics context if necessary.
Definition internal.c:144
static bool puglMustConfigure(PuglView *view, const PuglConfigureEvent *configure)
Definition internal.c:110
PuglStatus puglConfigure(PuglView *view, const PuglEvent *event)
Process configure event while already in the graphics context.
Definition internal.c:116
PuglStatus puglDispatchSimpleEvent(PuglView *view, const PuglEventType type)
Dispatch an event with a simple type to view.
Definition internal.c:99
void puglSetString(char **dest, const char *string)
Reallocate and set *dest to string.
Definition internal.c:40
JSAMPIMAGE data
Definition jpeglib.h:945
unsigned int uint32_t
Definition mid.cpp:100
unsigned char uint8_t
Definition mid.cpp:98
PUGL_WARN_UNUSED_RESULT PuglStatus(* leave)(PuglView *, const PuglExposeEvent *)
Leave drawing context, after drawing if expose is non-null.
Definition types.h:85
PUGL_WARN_UNUSED_RESULT PuglStatus(* enter)(PuglView *, const PuglExposeEvent *)
Enter drawing context, for drawing if expose is non-null.
Definition types.h:81
Blob of arbitrary data.
Definition types.h:31
void * data
Dynamically allocated data.
Definition types.h:32
size_t len
Length of data in bytes.
Definition types.h:33
Definition pugl.h:280
PuglSpan height
Height of exposed region.
Definition pugl.h:332
PuglSpan width
Width of exposed region.
Definition pugl.h:331
PuglSpan width
Definition pugl.h:90
PuglCoord y
Definition pugl.h:89
PuglCoord x
Definition pugl.h:88
PuglSpan height
Definition pugl.h:91
PuglEventFunc eventFunc
Definition types.h:42
PuglConfigureEvent lastConfigure
Definition types.h:47
PuglRect frame
Definition types.h:46
const PuglBackend * backend
Definition types.h:39
bool visible
Definition types.h:50
Definition pugl.h:599
PuglEventType type
Event type.
Definition pugl.h:601
PuglConfigureEvent configure
PUGL_CONFIGURE
Definition pugl.h:603
PuglExposeEvent expose
PUGL_EXPOSE
Definition pugl.h:604
memcpy(hh, h, RAND_HEAD_LEN)