GCC Code Coverage Report


Directory: src/gate/
File: src/gate/ui/gateui.c
Date: 2025-09-22 22:57:09
Exec Total Coverage
Lines: 0 404 0.0%
Functions: 0 52 0.0%
Branches: 0 180 0.0%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/ui/gateui.h"
30 #include "gate/results.h"
31
32
33 /****************************
34 * generic implementation *
35 ****************************/
36
37 ✗ gate_result_t gate_ui_ctrl_init(gate_ui_ctrl_t* ctrl)
38 {
39 ✗ gate_mem_clear(ctrl, sizeof(gate_ui_ctrl_t));
40 ✗ return GATE_RESULT_OK;
41 }
42
43
44 ✗ gate_result_t gate_ui_layout_create(gate_ui_layout_t* layout)
45 {
46 ✗ layout->border = 0;
47 ✗ layout->colspace = 0;
48 ✗ layout->rowspace = 0;
49 ✗ layout->columns = gate_arraylist_create(sizeof(gate_ui_layout_def_t), NULL, 0, NULL, NULL);
50 ✗ if (layout->columns == NULL)
51 {
52 ✗ return GATE_RESULT_OUTOFMEMORY;
53 }
54 ✗ layout->rows = gate_arraylist_create(sizeof(gate_ui_layout_def_t), NULL, 0, NULL, NULL);
55 ✗ if (layout->rows == NULL)
56 {
57 ✗ gate_arraylist_release(layout->columns);
58 ✗ return GATE_RESULT_OUTOFMEMORY;
59 }
60 ✗ layout->cells = gate_arraylist_create(sizeof(gate_arraylist_t), NULL, 0, NULL, NULL);
61 ✗ if (layout->cells == NULL)
62 {
63 ✗ gate_arraylist_release(layout->rows);
64 ✗ gate_arraylist_release(layout->columns);
65 ✗ return GATE_RESULT_OUTOFMEMORY;
66 }
67 ✗ return GATE_RESULT_OK;
68 }
69
70 ✗ gate_result_t gate_ui_layout_destroy(gate_ui_layout_t* layout)
71 {
72 ✗ gate_size_t maxrows = gate_arraylist_length(layout->cells);
73 gate_size_t ndx;
74 gate_arraylist_t* collist;
75 ✗ for (ndx = 0; ndx < maxrows; ++ndx)
76 {
77 ✗ collist = (gate_arraylist_t*)gate_arraylist_get(layout->cells, ndx);
78 ✗ gate_arraylist_release(*collist);
79 }
80 ✗ gate_arraylist_release(layout->cells);
81 ✗ gate_arraylist_release(layout->rows);
82 ✗ gate_arraylist_release(layout->columns);
83 ✗ return GATE_RESULT_NOTIMPLEMENTED;
84 }
85
86 ✗ gate_result_t gate_ui_layout_clear(gate_ui_layout_t* layout)
87 {
88 ✗ gate_ui_layout_destroy(layout);
89 ✗ return gate_ui_layout_create(layout);
90 }
91
92 static gate_ui_layout_cell_t const gate_ui_layout_empty_cell = { NULL, 0, 0, 0, 0, 0, 0 };
93
94 ✗ gate_result_t gate_ui_layout_add_column(gate_ui_layout_t* layout, gate_uint32_t type, gate_real32_t value)
95 {
96 gate_result_t ret;
97 gate_ui_layout_def_t def;
98 ✗ def.type = type;
99 ✗ def.value = value;
100 ✗ if (NULL == gate_arraylist_add(layout->columns, &def))
101 {
102 ✗ ret = GATE_RESULT_FAILED;
103 }
104 else
105 {
106 ✗ ret = GATE_RESULT_OK;
107 }
108 ✗ return ret;
109 }
110
111 ✗ gate_result_t gate_ui_layout_add_row(gate_ui_layout_t* layout, gate_uint32_t type, gate_real32_t value)
112 {
113 gate_result_t ret;
114 gate_ui_layout_def_t def;
115 ✗ def.type = type;
116 ✗ def.value = value;
117 ✗ if (NULL == gate_arraylist_add(layout->rows, &def))
118 {
119 ✗ ret = GATE_RESULT_FAILED;
120 }
121 else
122 {
123 ✗ ret = GATE_RESULT_OK;
124 }
125 ✗ return ret;
126 }
127
128 ✗ gate_uint32_t gate_ui_layout_get_rows(gate_ui_layout_t* layout)
129 {
130 ✗ gate_uint32_t ret = 0;
131 ✗ if (layout->rows != NULL)
132 {
133 ✗ ret = (gate_uint32_t)gate_arraylist_length(layout->rows);
134 }
135 ✗ return ret;
136 }
137 ✗ gate_uint32_t gate_ui_layout_get_columns(gate_ui_layout_t* layout)
138 {
139 ✗ gate_uint32_t ret = 0;
140 ✗ if (layout->rows != NULL)
141 {
142 ✗ ret = (gate_uint32_t)gate_arraylist_length(layout->columns);
143 }
144 ✗ return ret;
145 }
146
147
148 ✗ gate_result_t gate_ui_layout_set_control(gate_ui_layout_t* layout,
149 gate_ui_ctrl_t* ctrl, gate_uint32_t row, gate_uint32_t col,
150 gate_uint32_t rowspan, gate_uint32_t colspan
151 )
152 {
153 gate_size_t rowcount;
154 gate_size_t colcount;
155 gate_arraylist_t* collist;
156 gate_arraylist_t newlist;
157 gate_ui_layout_cell_t* cell;
158
159 ✗ rowcount = gate_arraylist_length(layout->cells);
160 ✗ for (; rowcount <= row; ++rowcount)
161 {
162 ✗ newlist = gate_arraylist_create(sizeof(gate_ui_layout_empty_cell), NULL, 0, NULL, NULL);
163 ✗ if (newlist == NULL)
164 {
165 ✗ return GATE_RESULT_OUTOFMEMORY;
166 }
167 ✗ if (NULL == gate_arraylist_add(layout->cells, &newlist))
168 {
169 ✗ gate_arraylist_release(newlist);
170 ✗ return GATE_RESULT_OUTOFMEMORY;
171 }
172 }
173 ✗ collist = (gate_arraylist_t*)gate_arraylist_get(layout->cells, row);
174 ✗ if (collist == NULL)
175 {
176 ✗ return GATE_RESULT_FAILED;
177 }
178 ✗ colcount = gate_arraylist_length(*collist);
179 ✗ for (; colcount <= col; ++colcount)
180 {
181 ✗ if (NULL == gate_arraylist_add(*collist, &gate_ui_layout_empty_cell))
182 {
183 ✗ return GATE_RESULT_OUTOFMEMORY;
184 }
185 }
186 ✗ cell = (gate_ui_layout_cell_t*)gate_arraylist_get(*collist, col);
187 ✗ if (cell == NULL)
188 {
189 ✗ return GATE_RESULT_FAILED;
190 }
191 ✗ cell->ctrl = ctrl;
192 ✗ cell->rowspan = rowspan;
193 ✗ cell->colspan = colspan;
194
195 ✗ return GATE_RESULT_OK;
196 }
197 ✗ gate_result_t gate_ui_layout_apply(gate_ui_layout_t const* layout, gate_uint32_t unitLength, gate_ui_position_t const* pose)
198 {
199 gate_int32_t rowheights[256];
200 gate_int32_t colwidths[256];
201 gate_size_t rowcount;
202 gate_size_t colcount;
203
204 gate_int32_t width;
205 gate_int32_t height;
206 gate_int32_t remainwidth;
207 gate_int32_t remainheight;
208
209 gate_size_t ndx;
210 gate_size_t autocnt;
211 gate_ui_layout_def_t* currentdef;
212 gate_int32_t x, y, w, h;
213 gate_size_t row, col;
214 gate_arraylist_t* currentcollist;
215 gate_ui_layout_cell_t* currentcell;
216 gate_ui_point_t ctrlpoint;
217 gate_ui_size_t ctrlsize;
218
219 ✗ if (!layout || !pose)
220 {
221 ✗ return GATE_RESULT_INVALIDDATA;
222 }
223
224 ✗ rowcount = gate_arraylist_length(layout->rows);
225 ✗ colcount = gate_arraylist_length(layout->columns);
226
227 ✗ width = pose->size.width - layout->border * 2;
228 ✗ height = pose->size.height - layout->border * 2;
229
230 ✗ if (rowcount > sizeof(rowheights) / sizeof(rowheights[0])) rowcount = sizeof(rowheights) / sizeof(rowheights[0]);
231 ✗ if (colcount > sizeof(colwidths) / sizeof(colwidths[0])) colcount = sizeof(colwidths) / sizeof(colwidths[0]);
232
233 ✗ if (colcount > 0) width -= (gate_int32_t)(colcount) * (gate_int32_t)layout->colspace;
234 ✗ if (rowcount > 0) height -= (gate_int32_t)(rowcount) * (gate_int32_t)layout->rowspace;
235 ✗ remainwidth = width;
236 ✗ remainheight = height;
237
238
239 /* calculating cell widths */
240 ✗ autocnt = 0;
241 ✗ for (ndx = 0; ndx != colcount; ++ndx)
242 {
243 ✗ currentdef = (gate_ui_layout_def_t*)gate_arraylist_get(layout->columns, ndx);
244 ✗ switch (currentdef->type)
245 {
246 ✗ case GATE_UI_LAYOUT_TYPE_PIXEL: colwidths[ndx] = (gate_int32_t)currentdef->value; break;
247 ✗ case GATE_UI_LAYOUT_TYPE_PERCENT: colwidths[ndx] = (gate_int32_t)((gate_real32_t)width * currentdef->value * 0.01f); break;
248 ✗ case GATE_UI_LAYOUT_TYPE_UNITSCALE: colwidths[ndx] = (gate_int32_t)((gate_real32_t)unitLength * currentdef->value); break;
249 ✗ default:
250 ✗ case GATE_UI_LAYOUT_TYPE_AUTO: colwidths[ndx] = 0; ++autocnt; break;
251 }
252 ✗ remainwidth -= colwidths[ndx];
253 }
254 ✗ if (autocnt > 0)
255 {
256 ✗ for (ndx = 0; ndx != colcount; ++ndx)
257 {
258 ✗ currentdef = (gate_ui_layout_def_t*)gate_arraylist_get(layout->columns, ndx);
259 ✗ switch (currentdef->type)
260 {
261 ✗ case GATE_UI_LAYOUT_TYPE_PIXEL:
262 case GATE_UI_LAYOUT_TYPE_PERCENT:
263 case GATE_UI_LAYOUT_TYPE_UNITSCALE:
264 ✗ break;
265 ✗ default:
266 case GATE_UI_LAYOUT_TYPE_AUTO:
267 ✗ colwidths[ndx] = remainwidth / (gate_int32_t)autocnt;
268 ✗ break;
269 }
270 }
271 }
272
273 /* calculating cell heights */
274 ✗ autocnt = 0;
275 ✗ for (ndx = 0; ndx != rowcount; ++ndx)
276 {
277 ✗ currentdef = (gate_ui_layout_def_t*)gate_arraylist_get(layout->rows, ndx);
278 ✗ switch (currentdef->type)
279 {
280 ✗ case GATE_UI_LAYOUT_TYPE_PIXEL: rowheights[ndx] = (gate_int32_t)currentdef->value; break;
281 ✗ case GATE_UI_LAYOUT_TYPE_PERCENT: rowheights[ndx] = (gate_int32_t)((gate_real32_t)height * currentdef->value * 0.01f); break;
282 ✗ case GATE_UI_LAYOUT_TYPE_UNITSCALE: rowheights[ndx] = (gate_int32_t)((gate_real32_t)unitLength * currentdef->value); break;
283 ✗ default:
284 ✗ case GATE_UI_LAYOUT_TYPE_AUTO: rowheights[ndx] = 0; ++autocnt; break;
285 }
286 ✗ remainheight -= rowheights[ndx];
287 }
288 ✗ if (autocnt > 0)
289 {
290 ✗ for (ndx = 0; ndx != rowcount; ++ndx)
291 {
292 ✗ currentdef = (gate_ui_layout_def_t*)gate_arraylist_get(layout->rows, ndx);
293 ✗ switch (currentdef->type)
294 {
295 ✗ case GATE_UI_LAYOUT_TYPE_PIXEL:
296 case GATE_UI_LAYOUT_TYPE_PERCENT:
297 case GATE_UI_LAYOUT_TYPE_UNITSCALE:
298 ✗ break;
299 ✗ default:
300 case GATE_UI_LAYOUT_TYPE_AUTO:
301 ✗ rowheights[ndx] = remainheight / (gate_int32_t)autocnt;
302 ✗ break;
303 }
304 }
305 }
306
307 /**/
308 ✗ y = pose->pos.y + layout->border + layout->rowspace / 2;
309 ✗ for (row = 0; row < rowcount; ++row)
310 {
311 ✗ h = rowheights[row];
312 ✗ if (row >= gate_arraylist_length(layout->cells))
313 {
314 /* there are no further rows with column cells, so we can cancel further processing */
315 ✗ break;
316 }
317 ✗ currentcollist = (gate_arraylist_t*)gate_arraylist_get(layout->cells, row);
318 ✗ if (currentcollist != NULL)
319 {
320 ✗ x = pose->pos.x + layout->border + layout->colspace / 2;
321 ✗ for (col = 0; col < colcount; ++col)
322 {
323 ✗ w = colwidths[col];
324
325 ✗ if (col >= gate_arraylist_length(*currentcollist))
326 {
327 /* there are no more cells in the current row, so we can skip all remaining columns */
328 ✗ break;
329 }
330 ✗ currentcell = (gate_ui_layout_cell_t*)gate_arraylist_get(*currentcollist, col);
331 ✗ if (currentcell != NULL)
332 {
333 ✗ if (currentcell->ctrl != NULL)
334 {
335 ✗ if (gate_ui_ctrl_is_created(currentcell->ctrl))
336 {
337 ✗ ctrlpoint.x = x;
338 ✗ ctrlpoint.y = y;
339 ✗ ctrlsize.width = w;
340 ✗ ctrlsize.height = h;
341 ✗ for (ndx = 1; ndx < currentcell->colspan; ++ndx)
342 {
343 ✗ ctrlsize.width += colwidths[col + ndx] + layout->colspace;
344 }
345 ✗ for (ndx = 1; ndx < currentcell->rowspan; ++ndx)
346 {
347 ✗ ctrlsize.height += rowheights[col + ndx] + layout->rowspace;
348 }
349 ✗ if (ctrlsize.width < 2) ctrlsize.width = 2;
350 ✗ if (ctrlsize.height < 2) ctrlsize.height = 2;
351 ✗ gate_ui_ctrl_set_position(currentcell->ctrl, &ctrlpoint, &ctrlsize);
352 ✗ gate_ui_ctrl_refresh(currentcell->ctrl);
353 }
354 }
355 }
356 ✗ x += (w + layout->colspace);
357 }
358 }
359
360 ✗ y += (h + layout->rowspace);
361 }
362
363 ✗ return GATE_RESULT_OK;
364 }
365
366
367
368
369 #if defined(GATE_UI_WINAPI)
370
371 #include "gate/platforms.h"
372 #include "gate/ui/gateui_winapi.h"
373
374
375
376
377
378 gate_result_t gate_ui_host_init(gate_ui_host_t* host, gate_uintptr_t apphandle, void* userparam)
379 {
380 return gate_ui_winapi_host_init(host, apphandle, userparam);
381 }
382 gate_result_t gate_ui_host_uninit(gate_ui_host_t* host)
383 {
384 return gate_ui_winapi_host_uninit(host);
385 }
386 gate_result_t gate_ui_host_run(gate_ui_host_t* host)
387 {
388 gate_result_t ret = GATE_RESULT_OK;
389 while (GATE_SUCCEEDED(ret))
390 {
391 ret = gate_ui_winapi_host_process_msg(host);
392 }
393 if (ret == GATE_RESULT_CANCELED)
394 {
395 /* ui host has received a quit message, which is OK too */
396 ret = GATE_RESULT_OK;
397 }
398 return ret;
399 }
400 gate_result_t gate_ui_host_quit(gate_ui_host_t* host)
401 {
402 gate_result_t ret = GATE_RESULT_OK;
403 #if defined(GATE_SYS_WIN16)
404 GATE_UNUSED_ARG(host);
405 PostQuitMessage(0);
406 #else
407 DWORD threadId = GATE_UI_WINAPI_GET_HOST_THREADID(host);
408 if (PostThreadMessage(threadId, WM_QUIT, 0, 0))
409 {
410 ret = GATE_RESULT_OK;
411 }
412 else
413 {
414 gate_win32_print_lasterror(&ret, NULL, 0);
415 }
416 #endif
417 return ret;
418 }
419 void* gate_ui_host_get_userparam(gate_ui_host_t* host)
420 {
421 return GATE_UI_WINAPI_GET_HOST_USER_PARAM(host);
422 }
423 gate_uintptr_t gate_ui_host_get_apphandle(gate_ui_host_t* host)
424 {
425 return GATE_UI_WINAPI_GET_HOST_APPHANDLE(host);
426 }
427 gate_uint32_t gate_ui_host_default_line_height(gate_ui_host_t* host)
428 {
429 return GATE_UI_WINAPI_GET_HOST_LINEHEIGHT(host);
430 }
431 gate_uint32_t gate_ui_host_default_control_height(gate_ui_host_t* host, gate_uint32_t line_count)
432 {
433 const gate_uint32_t line_height = GATE_UI_WINAPI_GET_HOST_LINEHEIGHT(host);
434 gate_uint32_t height = line_height * 14 / 8;
435 if (line_count > 1)
436 {
437 height += (line_count - 1) * line_height;
438 }
439 ++height;
440 return height;
441 }
442
443
444
445 void* gate_ui_ctrl_get_userparam(gate_ui_ctrl_t* ctrl)
446 {
447 void* ret = NULL;
448 if (ctrl != NULL)
449 {
450 ret = GATE_UI_WINAPI_GET_USER_PARAM(ctrl);
451 }
452 return ret;
453 }
454 gate_ui_host_t* gate_ui_ctrl_get_host(gate_ui_ctrl_t* ctrl)
455 {
456 gate_ui_host_t* host = NULL;
457 if (ctrl != NULL)
458 {
459 host = GATE_UI_WINAPI_GET_HOST(ctrl);
460 }
461 return host;
462 }
463 gate_ui_ctrl_t* gate_ui_ctrl_get_parent(gate_ui_ctrl_t* ctrl)
464 {
465 gate_ui_ctrl_t* ret = NULL;
466 gate_ui_host_t* host;
467 HWND hwndParent;
468 if (ctrl != NULL)
469 {
470 host = GATE_UI_WINAPI_GET_HOST(ctrl);
471 hwndParent = GATE_UI_WINAPI_GET_HWND_PARENT(ctrl);
472 if ((host) && (hwndParent))
473 {
474 ret = gate_ui_winapi_resolve_ctrl(host, (void*)hwndParent);
475 }
476 }
477 return ret;
478 }
479
480
481
482 gate_result_t gate_ui_ctrl_destroy(gate_ui_ctrl_t* ctrl)
483 {
484 gate_ui_winapi_dispatchers_t* disp;
485 gate_array_t children;
486 gate_result_t ret;
487 gate_size_t children_count;
488 gate_ui_ctrl_t* const* ptr_child;
489 HWND hwnd = (HWND)NULL;
490
491 do
492 {
493 if (ctrl == NULL)
494 {
495 ret = GATE_RESULT_NULLPOINTER;
496 break;
497 }
498 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
499 if ((disp == NULL) || (disp->destroy == NULL))
500 {
501 hwnd = GATE_UI_WINAPI_GET_HWND(ctrl);
502 if (!hwnd)
503 {
504 ret = GATE_RESULT_OK; /* already destroyed, nothing to do */
505 }
506 else
507 {
508 ret = gate_ui_ctrl_get_children(ctrl, &children);
509 if (GATE_SUCCEEDED(ret))
510 {
511 children_count = gate_array_length(&children);
512 ptr_child = (gate_ui_ctrl_t* const*)gate_array_get(&children, 0);
513 while (children_count-- != 0)
514 {
515 gate_ui_ctrl_destroy(*ptr_child);
516 ++ptr_child;
517 }
518 gate_array_release(&children);
519 }
520
521 ret = gate_ui_winapi_destroy_with_font(ctrl);
522 }
523 }
524 else
525 {
526 ret = disp->destroy(ctrl);
527 }
528
529 GATE_UI_WINAPI_SET_HWND(ctrl, NULL);
530 GATE_UI_WINAPI_SET_HWND_PARENT(ctrl, NULL);
531 GATE_UI_WINAPI_SET_HOST(ctrl, NULL);
532 GATE_UI_WINAPI_SET_HWND_PROC(ctrl, NULL);
533 GATE_UI_WINAPI_SET_USER_PARAM(ctrl, NULL);
534 GATE_UI_WINAPI_SET_DISPATCHER(ctrl, NULL);
535 GATE_UI_WINAPI_SET_CTRL_PARAM(ctrl, NULL);
536 } while (0);
537 return ret;
538 }
539 gate_bool_t gate_ui_ctrl_is_created(gate_ui_ctrl_t* ctrl)
540 {
541 return gate_ui_winapi_is_created(ctrl);
542 }
543 gate_bool_t gate_ui_ctrl_is_enabled(gate_ui_ctrl_t* ctrl)
544 {
545 gate_ui_winapi_dispatchers_t* disp;
546 if (ctrl == NULL)
547 {
548 return false;
549 }
550 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
551 if ((disp == NULL) || (disp->is_enabled == NULL))
552 {
553 return gate_ui_winapi_is_enabled(ctrl);
554 }
555 return disp->is_enabled(ctrl);
556 }
557 gate_bool_t gate_ui_ctrl_is_visible(gate_ui_ctrl_t* ctrl)
558 {
559 gate_ui_winapi_dispatchers_t* disp;
560 if (ctrl == NULL)
561 {
562 return false;
563 }
564 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
565 if ((disp == NULL) || (disp->is_visible == NULL))
566 {
567 return gate_ui_winapi_is_visible(ctrl);
568 }
569 return disp->is_visible(ctrl);
570
571 }
572 gate_bool_t gate_ui_ctrl_is_focused(gate_ui_ctrl_t* ctrl)
573 {
574 gate_ui_winapi_dispatchers_t* disp;
575 if (ctrl == NULL)
576 {
577 return false;
578 }
579 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
580 if ((disp == NULL) || (disp->is_focused == NULL))
581 {
582 return gate_ui_winapi_is_focused(ctrl);
583 }
584 return disp->is_focused(ctrl);
585
586 }
587 gate_result_t gate_ui_ctrl_get_position(gate_ui_ctrl_t* ctrl, gate_ui_position_t* position)
588 {
589 gate_ui_winapi_dispatchers_t* disp;
590 if (ctrl == NULL)
591 {
592 return GATE_RESULT_NULLPOINTER;
593 }
594 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
595 if ((disp == NULL) || (disp->get_position == NULL))
596 {
597 return gate_ui_winapi_get_position(ctrl, position);
598 }
599 return disp->get_position(ctrl, position);
600 }
601 gate_result_t gate_ui_ctrl_get_size(gate_ui_ctrl_t* ctrl, gate_ui_size_t* size)
602 {
603 gate_ui_winapi_dispatchers_t* disp;
604 if (ctrl == NULL)
605 {
606 return GATE_RESULT_NULLPOINTER;
607 }
608 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
609 if ((disp == NULL) || (disp->get_size == NULL))
610 {
611 return gate_ui_winapi_get_size(ctrl, size);
612 }
613 return disp->get_size(ctrl, size);
614 }
615 gate_result_t gate_ui_ctrl_get_children(gate_ui_ctrl_t* ctrl, gate_array_t* children)
616 {
617 gate_ui_winapi_dispatchers_t* disp;
618 if (ctrl == NULL)
619 {
620 return GATE_RESULT_NULLPOINTER;
621 }
622 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
623 if ((disp == NULL) || (disp->get_children == NULL))
624 {
625 return gate_ui_winapi_get_children(ctrl, children);
626 }
627 return disp->get_children(ctrl, children);
628 }
629 gate_result_t gate_ui_ctrl_get_text_length(gate_ui_ctrl_t* ctrl, gate_uint32_t* length)
630 {
631 gate_ui_winapi_dispatchers_t* disp;
632 if (ctrl == NULL)
633 {
634 return GATE_RESULT_NULLPOINTER;
635 }
636 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
637 if ((disp == NULL) || (disp->get_text == NULL))
638 {
639 return gate_ui_winapi_get_text_length(ctrl, length);
640 }
641 return disp->get_text_length(ctrl, length);
642 }
643
644 gate_result_t gate_ui_ctrl_get_text(gate_ui_ctrl_t* ctrl, gate_string_t* text)
645 {
646 gate_ui_winapi_dispatchers_t* disp;
647 if (ctrl == NULL)
648 {
649 return GATE_RESULT_NULLPOINTER;
650 }
651 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
652 if ((disp == NULL) || (disp->get_text == NULL))
653 {
654 return gate_ui_winapi_get_text(ctrl, text);
655 }
656 return disp->get_text(ctrl, text);
657 }
658 gate_result_t gate_ui_ctrl_get_state(gate_ui_ctrl_t* ctrl, gate_int32_t* state)
659 {
660 gate_ui_winapi_dispatchers_t* disp;
661 if (ctrl == NULL)
662 {
663 return GATE_RESULT_NULLPOINTER;
664 }
665 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
666 if ((disp == NULL) || (disp->get_state == NULL))
667 {
668 return gate_ui_winapi_get_state(ctrl, state);
669 }
670 return disp->get_state(ctrl, state);
671 }
672
673 gate_result_t gate_ui_ctrl_set_enabled(gate_ui_ctrl_t* ctrl, gate_bool_t enabledstate)
674 {
675 gate_ui_winapi_dispatchers_t* disp;
676 if (ctrl == NULL)
677 {
678 return GATE_RESULT_NULLPOINTER;
679 }
680 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
681 if ((disp == NULL) || (disp->set_enabled == NULL))
682 {
683 return gate_ui_winapi_set_enabled(ctrl, enabledstate);
684 }
685 return disp->set_enabled(ctrl, enabledstate);
686 }
687 gate_result_t gate_ui_ctrl_set_visible(gate_ui_ctrl_t* ctrl, gate_bool_t visibility)
688 {
689 gate_ui_winapi_dispatchers_t* disp;
690 if (ctrl == NULL)
691 {
692 return GATE_RESULT_NULLPOINTER;
693 }
694 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
695 if ((disp == NULL) || (disp->set_visible == NULL))
696 {
697 return gate_ui_winapi_set_visible(ctrl, visibility);
698 }
699 return disp->set_visible(ctrl, visibility);
700 }
701 gate_result_t gate_ui_ctrl_set_focus(gate_ui_ctrl_t* ctrl)
702 {
703 gate_ui_winapi_dispatchers_t* disp;
704 if (ctrl == NULL)
705 {
706 return GATE_RESULT_NULLPOINTER;
707 }
708 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
709 if ((disp == NULL) || (disp->set_focus == NULL))
710 {
711 return gate_ui_winapi_set_focus(ctrl);
712 }
713 return disp->set_focus(ctrl);
714 }
715 gate_result_t gate_ui_ctrl_set_position(gate_ui_ctrl_t* ctrl, gate_ui_point_t const* position, gate_ui_size_t const* size)
716 {
717 gate_ui_winapi_dispatchers_t* disp;
718 if (ctrl == NULL)
719 {
720 return GATE_RESULT_NULLPOINTER;
721 }
722 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
723 if ((disp == NULL) || (disp->set_position == NULL))
724 {
725 return gate_ui_winapi_set_position(ctrl, position, size);
726 }
727 return disp->set_position(ctrl, position, size);
728 }
729 gate_result_t gate_ui_ctrl_set_text(gate_ui_ctrl_t* ctrl, gate_string_t const* text)
730 {
731 gate_ui_winapi_dispatchers_t* disp;
732 if (ctrl == NULL)
733 {
734 return GATE_RESULT_NULLPOINTER;
735 }
736 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
737 if ((disp == NULL) || (disp->set_text == NULL))
738 {
739 return gate_ui_winapi_set_text(ctrl, text);
740 }
741 return disp->set_text(ctrl, text);
742 }
743 gate_result_t gate_ui_ctrl_set_state(gate_ui_ctrl_t* ctrl, gate_int32_t state)
744 {
745 gate_ui_winapi_dispatchers_t* disp;
746 if (ctrl == NULL)
747 {
748 return GATE_RESULT_NULLPOINTER;
749 }
750 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
751 if ((disp == NULL) || (disp->set_state == NULL))
752 {
753 return gate_ui_winapi_set_state(ctrl, state);
754 }
755 return disp->set_state(ctrl, state);
756 }
757
758 gate_result_t gate_ui_ctrl_refresh(gate_ui_ctrl_t* ctrl)
759 {
760 gate_ui_winapi_dispatchers_t* disp;
761 if (ctrl == NULL)
762 {
763 return GATE_RESULT_NULLPOINTER;
764 }
765 disp = GATE_UI_WINAPI_GET_DISPATCHER(ctrl);
766 if ((disp == NULL) || (disp->refresh == NULL))
767 {
768 return gate_ui_winapi_refresh(ctrl);
769 }
770 return disp->refresh(ctrl);
771
772 }
773
774 typedef struct gate_ui_host_enum_fonts_helper
775 {
776 gate_ui_enum_fontnames_callback_t cb;
777 void* userparam;
778 } gate_ui_host_enum_fonts_helper_t;
779
780 #if defined(GATE_SYS_WIN16)
781 static int CALLBACK gate_ui_host_enum_fonts_callback(LOGFONT const FAR* lplf, TEXTMETRIC const FAR* lptm, int dwType, LPARAM lpData)
782 #else
783 static int CALLBACK gate_ui_host_enum_fonts_callback(LOGFONT const* lplf, TEXTMETRIC const* lptm, DWORD dwType, LPARAM lpData)
784 #endif
785 {
786 gate_ui_host_enum_fonts_helper_t* helper = (gate_ui_host_enum_fonts_helper_t*)(void*)(gate_intptr_t)lpData;
787 char fontname[128];
788
789 GATE_UNUSED_ARG(lptm);
790 GATE_UNUSED_ARG(dwType);
791 gate_win32_winstr_2_utf8(lplf->lfFaceName, gate_win32_str_len(lplf->lfFaceName), fontname, sizeof(fontname));
792
793 helper->cb(fontname, helper->userparam);
794 return TRUE;
795 }
796
797 gate_result_t gate_ui_host_enum_fonts(gate_ui_host_t* host, gate_ui_enum_fontnames_callback_t callback, void* userparam)
798 {
799 gate_result_t ret;
800 gate_ui_host_enum_fonts_helper_t helper;
801 HDC hdc;
802 GATE_UNUSED_ARG(host);
803 hdc = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
804 if (!hdc)
805 {
806 ret = GATE_RESULT_OUTOFRESOURCES;
807 }
808 else
809 {
810 helper.cb = callback;
811 helper.userparam = userparam;
812 EnumFonts(hdc, NULL, &gate_ui_host_enum_fonts_callback, (LPARAM)(gate_intptr_t)(void*)&helper);
813 ret = GATE_RESULT_OK;
814 }
815 return ret;
816
817 }
818 gate_result_t gate_ui_host_default_font(gate_ui_host_t* host, gate_uint32_t fonttype, gate_ui_font_t* font)
819 {
820 gate_result_t ret = GATE_RESULT_OK;
821 GATE_UNUSED_ARG(host);
822
823 ret = gate_ui_winapi_get_default_font(font);
824 if (GATE_SUCCEEDED(ret))
825 {
826 switch (fonttype)
827 {
828 case GATE_UI_FONT_TYPE_STANDARD:
829 {
830 break;
831 }
832 case GATE_UI_FONT_TYPE_SANSSERIF:
833 {
834 gate_mem_copy(&font->font_name[0], "Arial", 6);
835 break;
836 }
837 case GATE_UI_FONT_TYPE_SERIF:
838 {
839 gate_mem_copy(&font->font_name[0], "Times New Roman", 16);
840 break;
841 }
842 case GATE_UI_FONT_TYPE_MONOSPACE:
843 {
844 gate_mem_copy(&font->font_name[0], "Courier New", 12);
845 break;
846 }
847 default:
848 {
849 ret = GATE_RESULT_INVALIDARG;
850 break;
851 }
852 }
853 }
854 return ret;
855 }
856
857 #define GATE_UI_HOST_DEFAULT_DPI_VALUE 96
858
859 static gate_int32_t gate_ui_host_get_default_dpi()
860 {
861 static gate_int32_t cached_dpi_value = 0;
862 gate_int32_t ret = GATE_UI_HOST_DEFAULT_DPI_VALUE;
863 int tmp;
864 HDC hdc_screen;
865
866 if (cached_dpi_value == 0)
867 {
868 tmp = GATE_UI_HOST_DEFAULT_DPI_VALUE;
869 hdc_screen = GetDC(NULL);
870 if (hdc_screen)
871 {
872 tmp = GetDeviceCaps(hdc_screen, LOGPIXELSY);
873 if (tmp == 0)
874 {
875 tmp = GATE_UI_HOST_DEFAULT_DPI_VALUE;
876 }
877 ReleaseDC(NULL, hdc_screen);
878 }
879 cached_dpi_value = tmp;
880 ret = tmp;
881 }
882 else
883 {
884 ret = cached_dpi_value;
885 }
886 return ret;
887 }
888
889 gate_int32_t gate_ui_host_get_pixels_in_points(gate_ui_host_t* host, gate_real32_t points)
890 {
891 gate_int32_t dpi = gate_ui_host_get_default_dpi();
892 (void)host;
893 return (gate_int32_t)((points * (gate_real32_t)dpi / 72.0f) + 0.5f);
894 }
895 gate_real32_t gate_ui_host_get_points_in_pixels(gate_ui_host_t* host, gate_int32_t pixels)
896 {
897 gate_int32_t dpi = gate_ui_host_get_default_dpi();
898 gate_int32_t tmp = (gate_int32_t)((pixels * 72.0f / (gate_real32_t)dpi) + 0.5f);
899 (void)host;
900 return (gate_real32_t)tmp;
901 }
902
903 #if defined(GATE_UI_WINAPI_DARKMODE_SUPPORT)
904 static gate_ui_color_t dark_color_window_background = { 0x00, 0x00, 0x00, 0xff };
905 static gate_ui_color_t dark_color_window_text = { 0xff, 0xff, 0xff, 0xff };
906 static gate_ui_color_t dark_color_window_text_disabled = { 0xcc, 0xcc, 0xcc, 0xff };
907
908 static gate_ui_color_t dark_color_menu_background = { 0x2b, 0x2b, 0x2b, 0xff };
909 static gate_ui_color_t dark_color_menu_selected = { 0x41, 0x41, 0x41, 0xff };
910 static gate_ui_color_t dark_color_menu_text = { 0xff, 0xff, 0xff, 0xff };
911
912 static gate_ui_color_t dark_color_content_background = { 0x19, 0x19, 0x19, 0xff };
913 static gate_ui_color_t dark_color_content_text = { 0xff, 0xff, 0xff, 0xff };
914 static gate_ui_color_t dark_color_content_text_disabled = { 0xcc, 0xcc, 0xcc, 0xff };
915 static gate_ui_color_t dark_color_content_selected = { 0x33, 0x33, 0x33, 0xff };
916 static gate_ui_color_t dark_color_content_focus = { 0x62, 0x62, 0x62, 0xff };
917 static gate_ui_color_t dark_color_content_hilight = { 0x77, 0x77, 0x77, 0xff };
918
919 static gate_ui_color_t dark_color_control_background = { 0x20, 0x20, 0x20, 0xff };
920 static gate_ui_color_t dark_color_control_text = { 0xff, 0xff, 0xff, 0xff };
921 static gate_ui_color_t dark_color_control_text_disabled = { 0xcc, 0xcc, 0xcc, 0xff };
922
923 static gate_ui_color_t dark_color_border_light = { 0xa0, 0xa0, 0xa0, 0xff };
924 static gate_ui_color_t dark_color_border_dark = { 0x12, 0x12, 0x12, 0xff };
925
926 /* Content - Hilight : 4d4d4d */
927
928 #endif
929
930 gate_result_t gate_ui_host_default_color(gate_ui_host_t* host, gate_uint32_t colortype, gate_ui_color_t* col)
931 {
932 int syscolor;
933 COLORREF color;
934 /*gate_result_t result; */
935 /*wchar_t const* theme_color_name = NULL;*/
936 #if !defined(GATE_SYS_WIN16)
937 gate_ui_color_t* ptr_col = NULL;
938 #endif
939 GATE_UNUSED_ARG(host);
940
941 #if defined(GATE_UI_WINAPI_DARKMODE_SUPPORT)
942 if (gate_ui_winapi_darkmode_enabled())
943 {
944 switch (colortype)
945 {
946 case GATE_UI_COLOR_BACKGROUND:
947 case GATE_UI_COLOR_WORKSPACE:
948 case GATE_UI_COLOR_WINDOW: ptr_col = &dark_color_window_background; break;
949 case GATE_UI_COLOR_WINDOWTEXT: ptr_col = &dark_color_window_text; break;
950 case GATE_UI_COLOR_WINDOWTEXTDISABLED: ptr_col = &dark_color_window_text_disabled; break;
951
952 case GATE_UI_COLOR_DIALOG: ptr_col = &dark_color_control_background; break;
953 case GATE_UI_COLOR_DIALOGTEXT: ptr_col = &dark_color_control_text; break;
954 case GATE_UI_COLOR_DIALOGTEXTDISABLED: ptr_col = &dark_color_control_text_disabled;break;
955
956 case GATE_UI_COLOR_CONTROL: ptr_col = &dark_color_control_background; break;
957 case GATE_UI_COLOR_CONTROLTEXT: ptr_col = &dark_color_control_text; break;
958 case GATE_UI_COLOR_CONTROLTEXTDISABLED: ptr_col = &dark_color_control_text_disabled;break;
959
960 case GATE_UI_COLOR_CONTROLBORDERLIGHT: ptr_col = &dark_color_border_light; break;
961 case GATE_UI_COLOR_CONTROLBORDERHILIGHT: ptr_col = &dark_color_border_light; break;
962 case GATE_UI_COLOR_CONTROLBORDERSHADOW: ptr_col = &dark_color_border_dark; break;
963 case GATE_UI_COLOR_CONTROLBORDERDARKSHADOW: ptr_col = &dark_color_border_dark; break;
964
965 case GATE_UI_COLOR_MENUBACKGROUND: ptr_col = &dark_color_menu_background; break;
966 case GATE_UI_COLOR_MENUTEXT: ptr_col = &dark_color_menu_text; break;
967 case GATE_UI_COLOR_SELECTEDMENUBACKGROUND: ptr_col = &dark_color_menu_selected; break;
968 case GATE_UI_COLOR_SELECTEDMENUTEXT: ptr_col = &dark_color_menu_text; break;
969 case GATE_UI_COLOR_HOVERMENUBACKGROUND: ptr_col = &dark_color_menu_selected; break;
970 case GATE_UI_COLOR_HOVERMENUTEXT: ptr_col = &dark_color_menu_text; break;
971
972 case GATE_UI_COLOR_CONTENTBACKGROUND: ptr_col = &dark_color_content_background; break;
973 case GATE_UI_COLOR_CONTENTTEXT: ptr_col = &dark_color_content_text; break;
974 case GATE_UI_COLOR_CONTENTTEXTDISABLED: ptr_col = &dark_color_content_text_disabled;break;
975 case GATE_UI_COLOR_CONTENTSELECTEDBACKGROUND: ptr_col = &dark_color_content_selected; break;
976 case GATE_UI_COLOR_CONTENTSELECTEDTEXT: ptr_col = &dark_color_content_text; break;
977 case GATE_UI_COLOR_CONTENTBORDERLIGHT: ptr_col = &dark_color_border_light; break;
978 case GATE_UI_COLOR_CONTENTBORDERHILIGHT: ptr_col = &dark_color_border_light; break;
979 case GATE_UI_COLOR_CONTENTBORDERSHADOW: ptr_col = &dark_color_border_dark; break;
980 case GATE_UI_COLOR_CONTENTBORDERDARKSHADOW: ptr_col = &dark_color_border_dark; break;
981 }
982
983 if (ptr_col != NULL)
984 {
985 if (col)
986 {
987 *col = *ptr_col;
988 }
989 return GATE_RESULT_OK;
990 }
991 }
992 #endif /* GATE_UI_WINAPI_DARKMODE_SUPPORT */
993
994 /* default win32 colors */
995 syscolor = gate_ui_winapi_get_syscolor_index(colortype);
996
997 if (syscolor == -1)
998 {
999 return GATE_RESULT_NOTSUPPORTED;
1000 }
1001 else
1002 {
1003 color = GetSysColor(syscolor);
1004 if (col != NULL)
1005 {
1006 col->r = GetRValue(color);
1007 col->g = GetGValue(color);
1008 col->b = GetBValue(color);
1009 col->a = 255;
1010 }
1011 return GATE_RESULT_OK;
1012 }
1013 }
1014
1015 gate_result_t gate_ui_host_clipboard_get_text(gate_ui_host_t* host, gate_string_t* text)
1016 {
1017 gate_result_t ret;
1018 HWND appwnd = GATE_UI_WINAPI_GET_HOST_APPWND(host);
1019 HANDLE hdata;
1020 LPVOID ptrdata;
1021 gate_strbuilder_t builder;
1022 do
1023 {
1024 if (!appwnd)
1025 {
1026 ret = GATE_RESULT_NOTAVAILABLE;
1027 break;
1028 }
1029
1030 if (IsClipboardFormatAvailable(CF_TEXT))
1031 {
1032 if (!OpenClipboard(appwnd))
1033 {
1034 ret = GATE_RESULT_NOTAVAILABLE;
1035 break;
1036 }
1037
1038 ret = GATE_RESULT_OK;
1039 hdata = GetClipboardData(CF_TEXT);
1040
1041 if (hdata == NULL)
1042 {
1043 gate_string_create_empty(text);
1044 }
1045 else
1046 {
1047 ptrdata = GlobalLock(hdata);
1048 if (ptrdata == NULL)
1049 {
1050 gate_string_create_empty(text);
1051 }
1052 else
1053 {
1054 gate_string_create(text, (gate_char8_t const*)ptrdata, gate_str_length((gate_char8_t const*)ptrdata));
1055 }
1056 GlobalUnlock(hdata);
1057 }
1058 CloseClipboard();
1059 }
1060 else if (IsClipboardFormatAvailable(CF_OEMTEXT))
1061 {
1062 if (!OpenClipboard(appwnd))
1063 {
1064 ret = GATE_RESULT_NOTAVAILABLE;
1065 break;
1066 }
1067
1068 ret = GATE_RESULT_OK;
1069 hdata = GetClipboardData(CF_OEMTEXT);
1070
1071 if (hdata == NULL)
1072 {
1073 gate_string_create_empty(text);
1074 }
1075 else
1076 {
1077 ptrdata = GlobalLock(hdata);
1078 if (ptrdata == NULL)
1079 {
1080 gate_string_create_empty(text);
1081 }
1082 else
1083 {
1084 gate_string_create(text, (gate_char8_t const*)ptrdata, gate_str_length((gate_char8_t const*)ptrdata));
1085 }
1086 GlobalUnlock(hdata);
1087 }
1088 CloseClipboard();
1089 }
1090 #if !defined(GATE_SYS_WIN16)
1091 else if (IsClipboardFormatAvailable(CF_UNICODETEXT))
1092 {
1093 if (!OpenClipboard(appwnd))
1094 {
1095 ret = GATE_RESULT_NOTAVAILABLE;
1096 break;
1097 }
1098
1099 ret = GATE_RESULT_OK;
1100 hdata = GetClipboardData(CF_UNICODETEXT);
1101
1102 if (hdata == NULL)
1103 {
1104 gate_string_create_empty(text);
1105 }
1106 else
1107 {
1108 ptrdata = GlobalLock(hdata);
1109 if (ptrdata == NULL)
1110 {
1111 gate_string_create_empty(text);
1112 }
1113 else
1114 {
1115 gate_strbuilder_create(&builder, 0);
1116 gate_strbuilder_append_text16(&builder, (wchar_t const*)ptrdata, gate_str16_length((wchar_t const*)ptrdata));
1117 gate_strbuilder_to_string(&builder, text);
1118 gate_strbuilder_release(&builder);
1119 }
1120 GlobalUnlock(hdata);
1121 }
1122 CloseClipboard();
1123 }
1124 #endif /* GATE_SYS_WIN16 */
1125 else
1126 {
1127 ret = GATE_RESULT_INVALIDCONTENT;
1128 break;
1129 }
1130 } while (0);
1131
1132 return ret;
1133 }
1134 gate_result_t gate_ui_host_clipboard_set_text(gate_ui_host_t* host, gate_string_t const* text)
1135 {
1136 gate_result_t ret;
1137 HWND appwnd = GATE_UI_WINAPI_GET_HOST_APPWND(host);
1138 gate_size_t textlen;
1139 HGLOBAL memhandle;
1140 LPVOID memptr;
1141
1142 do
1143 {
1144 if (appwnd == NULL)
1145 {
1146 ret = GATE_RESULT_NOTAVAILABLE;
1147 break;
1148 }
1149 if (!OpenClipboard(appwnd))
1150 {
1151 ret = GATE_RESULT_NOTAVAILABLE;
1152 break;
1153 }
1154
1155 EmptyClipboard();
1156
1157 do
1158 {
1159 textlen = gate_string_length(text);
1160 if (textlen == 0)
1161 {
1162 ret = GATE_RESULT_OK;
1163 break; /* we are done */
1164 }
1165
1166 #if !defined(GATE_SYS_WIN16)
1167 /* write UTF16 text */
1168 memhandle = GlobalAlloc(GMEM_MOVEABLE, ((textlen + 2) * sizeof(gate_char16_t)));
1169 if (memhandle == NULL)
1170 {
1171 CloseClipboard();
1172 ret = GATE_RESULT_OUTOFMEMORY;
1173 break;
1174 }
1175 memptr = GlobalLock(memhandle);
1176 gate_str_utf8_2_utf16(text->str, text->length, memptr, textlen + 1);
1177 GlobalUnlock(memhandle);
1178 if (SetClipboardData(CF_UNICODETEXT, memhandle))
1179 {
1180 ret = GATE_RESULT_OK;
1181 break;
1182 }
1183 else
1184 {
1185 ret = GATE_RESULT_FAILED;
1186 GlobalFree(memhandle);
1187 }
1188 #endif /* GATE_SYS_WIN16 */
1189
1190 /* write plain text */
1191 memhandle = GlobalAlloc(GMEM_MOVEABLE, ((textlen + 2) * sizeof(gate_char8_t)));
1192 if (memhandle == NULL)
1193 {
1194 CloseClipboard();
1195 ret = GATE_RESULT_OUTOFMEMORY;
1196 break;
1197 }
1198 memptr = GlobalLock(memhandle);
1199 gate_str_print_text((gate_char8_t*)memptr, textlen + 2, text->str, text->length);
1200 GlobalUnlock(memhandle);
1201 if (SetClipboardData(CF_OEMTEXT, memhandle))
1202 {
1203 ret = GATE_RESULT_OK;
1204 }
1205 else
1206 {
1207 GlobalFree(memhandle);
1208 ret = GATE_RESULT_FAILED;
1209 }
1210 } while (0);
1211 CloseClipboard();
1212 } while (0);
1213
1214 return ret;
1215 }
1216
1217 gate_result_t gate_ui_host_default_workarea(gate_ui_host_t* host, gate_ui_position_t* area)
1218 {
1219 RECT r = GATE_INIT_EMPTY;
1220 #if !defined(GATE_SYS_WIN16)
1221 gate_win32_userapi_t const* const userapi = gate_win32_userapi();
1222 /* try param info first */
1223 if (userapi->UserSystemParametersInfo)
1224 {
1225 if (userapi->UserSystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0))
1226 {
1227 area->pos.x = r.left;
1228 area->pos.y = r.top;
1229 area->size.width = r.right - r.left;
1230 area->size.height = r.bottom - r.top;
1231 return GATE_RESULT_OK;
1232 }
1233 }
1234 #endif
1235 /* fallback: */
1236 return gate_ui_host_total_workarea(host, area);
1237 }
1238
1239 #ifndef SM_XVIRTUALSCREEN
1240 #define SM_XVIRTUALSCREEN 76
1241 #endif
1242 #ifndef SM_YVIRTUALSCREEN
1243 #define SM_YVIRTUALSCREEN 77
1244 #endif
1245 #ifndef SM_CXVIRTUALSCREEN
1246 #define SM_CXVIRTUALSCREEN 78
1247 #endif
1248 #ifndef SM_CYVIRTUALSCREEN
1249 #define SM_CYVIRTUALSCREEN 79
1250 #endif
1251
1252 gate_result_t gate_ui_host_total_workarea(gate_ui_host_t* host, gate_ui_position_t* area)
1253 {
1254 GATE_UNUSED_ARG(host);
1255 area->pos.x = GetSystemMetrics(SM_XVIRTUALSCREEN);
1256 area->pos.y = GetSystemMetrics(SM_YVIRTUALSCREEN);
1257 area->size.width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
1258 area->size.height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
1259 if (area->size.width == 0)
1260 {
1261 area->size.width = GetSystemMetrics(SM_CXSCREEN);
1262 }
1263 if (area->size.height == 0)
1264 {
1265 area->size.height = GetSystemMetrics(SM_CYSCREEN);
1266 }
1267 return GATE_RESULT_OK;
1268 }
1269
1270 gate_result_t gate_ui_host_execute(gate_ui_host_t* host, gate_runnable_t* code)
1271 {
1272 return gate_ui_winapi_host_post_runner(host, code, true, true);
1273 }
1274
1275 gate_result_t gate_ui_host_process_events(gate_ui_host_t* host)
1276 {
1277 return gate_ui_winapi_host_process_msg(host);
1278 }
1279
1280
1281
1282 #endif /* GATE_SYS_WIN */
1283
1284
1285
1286 #if defined(GATE_UI_GTK)
1287
1288 #include "gate/ui/gateui_gtk.h"
1289
1290 gate_result_t gate_ui_host_init(gate_ui_host_t* host, gate_uintptr_t apphandle, void* userparam)
1291 {
1292 return gate_ui_gtk_host_init(host, apphandle, userparam);
1293 }
1294 gate_result_t gate_ui_host_uninit(gate_ui_host_t* host)
1295 {
1296 return gate_ui_gtk_host_uninit(host);
1297 }
1298 gate_result_t gate_ui_host_run(gate_ui_host_t* host)
1299 {
1300 return gate_ui_gtk_host_run(host);
1301 }
1302 gate_result_t gate_ui_host_quit(gate_ui_host_t* host)
1303 {
1304 return gate_ui_gtk_host_quit(host);
1305 }
1306 void* gate_ui_host_get_userparam(gate_ui_host_t* host)
1307 {
1308 return GATE_UI_GTK_GET_HOST_USER_PARAM(host);
1309 }
1310 gate_uintptr_t gate_ui_host_get_apphandle(gate_ui_host_t* host)
1311 {
1312 return GATE_UI_GTK_GET_HOST_APPHANDLE(host);
1313 }
1314 gate_uint32_t gate_ui_host_default_line_height(gate_ui_host_t* host)
1315 {
1316 return 16;
1317 }
1318 gate_uint32_t gate_ui_host_default_control_height(gate_ui_host_t* host, gate_uint32_t line_count)
1319 {
1320 gate_uint32_t height = 14 + line_count * gate_ui_host_default_line_height(host);
1321 return height;
1322 }
1323
1324 gate_result_t gate_ui_host_enum_fonts(gate_ui_host_t* host, gate_ui_enum_fontnames_callback_t callback, void* userparam)
1325 {
1326 gate_result_t ret = GATE_RESULT_FAILED;
1327 PangoFontMap* font_map = pango_cairo_font_map_get_default(); /* must not be freed */
1328 PangoFontFamily** families = NULL;
1329 int families_count = 0;
1330 int index;
1331 char const* name = NULL;
1332
1333 do
1334 {
1335 if (!font_map)
1336 {
1337 ret = GATE_RESULT_OUTOFRESOURCES;
1338 break;
1339 }
1340 pango_font_map_list_families(font_map, &families, &families_count);
1341
1342 if (families_count <= 0)
1343 {
1344 ret = GATE_RESULT_NOTAVAILABLE;
1345 break;
1346 }
1347
1348 ret = GATE_RESULT_OK;
1349
1350 for (index = 0; index != families_count; ++index)
1351 {
1352 name = pango_font_family_get_name(families[index]);
1353 if (!name)
1354 {
1355 continue;
1356 }
1357 pango_font_family_is_monospace(families[index]);
1358
1359 if (callback)
1360 {
1361 if (!callback(name, userparam))
1362 {
1363 /* cancelled by user */
1364 break;
1365 }
1366 }
1367 }
1368
1369 } while (0);
1370
1371 if (families)
1372 {
1373 g_free(families);
1374 }
1375
1376 return ret;
1377 }
1378
1379 static gate_bool_t gate_ui_enum_fontnames_callback_test(char const* font_name, void* userparam)
1380 {
1381 return true;
1382 }
1383
1384 gate_result_t gate_ui_host_default_font(gate_ui_host_t* host, gate_uint32_t fonttype, gate_ui_font_t* font)
1385 {
1386 gate_ui_host_enum_fonts(host, &gate_ui_enum_fontnames_callback_test, NULL);
1387 gate_str_print_text(font->font_name, sizeof(font->font_name), "Monospace", 9);
1388 font->size = 12;
1389 font->orientation = 0;
1390 font->bold = false;
1391 font->italic = false;
1392 font->underline = false;
1393 font->strikeout = false;
1394
1395 return GATE_RESULT_OK;
1396 }
1397 gate_int32_t gate_ui_host_get_pixels_in_points(gate_ui_host_t* host, gate_real32_t points)
1398 {
1399 gate_int32_t dpi = 96;
1400 gate_int32_t fppi = 72;
1401 return (gate_int32_t)(points * dpi / fppi);
1402 }
1403 gate_real32_t gate_ui_host_get_points_in_pixels(gate_ui_host_t* host, gate_int32_t pixels)
1404 {
1405 gate_real32_t dpi = 96.0f;
1406 gate_real32_t fppi = 72.0f;
1407 return (gate_real32_t)pixels * fppi / dpi;
1408 }
1409
1410 gate_result_t gate_ui_host_default_color(gate_ui_host_t* host, gate_uint32_t colortype, gate_ui_color_t* col)
1411 {
1412 return GATE_RESULT_NOTIMPLEMENTED;
1413 }
1414 gate_result_t gate_ui_host_clipboard_get_text(gate_ui_host_t* host, gate_string_t* text)
1415 {
1416 return GATE_RESULT_NOTIMPLEMENTED;
1417 }
1418 gate_result_t gate_ui_host_clipboard_set_text(gate_ui_host_t* host, gate_string_t const* text)
1419 {
1420 return GATE_RESULT_NOTIMPLEMENTED;
1421 }
1422 gate_result_t gate_ui_host_default_workarea(gate_ui_host_t* host, gate_ui_position_t* area)
1423 {
1424 return GATE_RESULT_NOTIMPLEMENTED;
1425 }
1426 gate_result_t gate_ui_host_total_workarea(gate_ui_host_t* host, gate_ui_position_t* area)
1427 {
1428 return GATE_RESULT_NOTIMPLEMENTED;
1429 }
1430 gate_result_t gate_ui_host_process_events(gate_ui_host_t* host)
1431 {
1432 /* TODO */
1433 return GATE_RESULT_OK;
1434 }
1435
1436
1437
1438
1439
1440 void* gate_ui_ctrl_get_userparam(gate_ui_ctrl_t* ctrl)
1441 {
1442 if (ctrl != NULL)
1443 {
1444 return GATE_UI_GTK_GET_CTRL_USER_PARAM(ctrl);
1445 }
1446 return NULL;
1447 }
1448 gate_ui_host_t* gate_ui_ctrl_get_host(gate_ui_ctrl_t* ctrl)
1449 {
1450 if (ctrl != NULL)
1451 {
1452 return GATE_UI_GTK_GET_CTRL_HOST(ctrl);
1453 }
1454 return NULL;
1455 }
1456 gate_ui_ctrl_t* gate_ui_ctrl_get_parent(gate_ui_ctrl_t* ctrl)
1457 {
1458 if (ctrl != NULL)
1459 {
1460
1461 }
1462 return NULL;
1463 }
1464
1465 gate_result_t gate_ui_ctrl_destroy(gate_ui_ctrl_t* ctrl)
1466 {
1467 gate_array_t children;
1468 gate_result_t ret;
1469 gate_size_t children_count;
1470 gate_ui_ctrl_t* const* ptr_child;
1471
1472 do
1473 {
1474 if (ctrl == NULL)
1475 {
1476 ret = GATE_RESULT_NULLPOINTER;
1477 break;
1478 }
1479 ret = gate_ui_ctrl_get_children(ctrl, &children);
1480 if (GATE_SUCCEEDED(ret))
1481 {
1482 children_count = gate_array_length(&children);
1483 ptr_child = (gate_ui_ctrl_t* const*)gate_array_get(&children, 0);
1484 while (children_count-- != 0)
1485 {
1486 if (*ptr_child)
1487 {
1488 gate_ui_ctrl_destroy(*ptr_child);
1489 }
1490 ++ptr_child;
1491 }
1492 gate_array_release(&children);
1493 }
1494
1495 ret = gate_ui_gtk_ctrl_destroy(ctrl);
1496 } while (0);
1497 return ret;
1498 }
1499 gate_bool_t gate_ui_ctrl_is_created(gate_ui_ctrl_t* ctrl)
1500 {
1501 gate_bool_t ret = false;
1502 if (ctrl != NULL)
1503 {
1504 ret = GATE_UI_GTK_GET_CTRL_WIDGET(ctrl) != NULL;
1505 }
1506 return ret;
1507 }
1508 gate_bool_t gate_ui_ctrl_is_enabled(gate_ui_ctrl_t* ctrl)
1509 {
1510 gate_bool_t ret = false;
1511 if (ctrl != NULL)
1512 {
1513 ret = gate_ui_gtk_ctrl_is_enabled(ctrl);
1514 }
1515 return ret;
1516 }
1517 gate_bool_t gate_ui_ctrl_is_visible(gate_ui_ctrl_t* ctrl)
1518 {
1519 gate_bool_t ret = false;
1520 if (ctrl != NULL)
1521 {
1522 ret = gate_ui_gtk_ctrl_is_visible(ctrl);
1523 }
1524 return ret;
1525 }
1526 gate_bool_t gate_ui_ctrl_is_focused(gate_ui_ctrl_t* ctrl)
1527 {
1528 gate_bool_t ret = false;
1529 if (ctrl != NULL)
1530 {
1531 ret = gate_ui_gtk_ctrl_has_focus(ctrl);
1532 }
1533 return ret;
1534 }
1535 gate_result_t gate_ui_ctrl_get_position(gate_ui_ctrl_t* ctrl, gate_ui_position_t* position)
1536 {
1537 if (ctrl != NULL)
1538 {
1539 return gate_ui_gtk_ctrl_get_position(ctrl, position);
1540 }
1541 return GATE_RESULT_NULLPOINTER;
1542 }
1543 gate_result_t gate_ui_ctrl_get_size(gate_ui_ctrl_t* ctrl, gate_ui_size_t* size)
1544 {
1545 if (ctrl != NULL)
1546 {
1547 return gate_ui_gtk_ctrl_get_size(ctrl, size);
1548 }
1549 return GATE_RESULT_NULLPOINTER;
1550 }
1551 gate_result_t gate_ui_ctrl_get_children(gate_ui_ctrl_t* ctrl, gate_array_t* children)
1552 {
1553 if ((ctrl == NULL) || (children == NULL))
1554 {
1555 return GATE_RESULT_NULLPOINTER;
1556 }
1557
1558 return gate_ui_gtk_ctrl_get_children(ctrl, children);
1559 }
1560 gate_result_t gate_ui_ctrl_get_text(gate_ui_ctrl_t* ctrl, gate_string_t* text)
1561 {
1562 gate_ui_gtk_dispatcher_t* disp;
1563 if (ctrl == NULL)
1564 {
1565 return GATE_RESULT_NULLPOINTER;
1566 }
1567 disp = GATE_UI_GTK_GET_CTRL_DISP(ctrl);
1568 if ((disp == NULL) || (disp->get_text == NULL))
1569 {
1570 return GATE_RESULT_NOTSUPPORTED;
1571 }
1572 return disp->get_text(ctrl, text);
1573 }
1574 gate_result_t gate_ui_ctrl_get_text_length(gate_ui_ctrl_t* ctrl, gate_uint32_t* length)
1575 {
1576 gate_ui_gtk_dispatcher_t* disp;
1577 gate_uint32_t l;
1578 if (ctrl == NULL)
1579 {
1580 return GATE_RESULT_NULLPOINTER;
1581 }
1582 disp = GATE_UI_GTK_GET_CTRL_DISP(ctrl);
1583 if ((disp == NULL) || (disp->get_text_length == NULL))
1584 {
1585 return GATE_RESULT_NOTSUPPORTED;
1586 }
1587 l = disp->get_text_length(ctrl);
1588 if (length != NULL)
1589 {
1590 *length = l;
1591 }
1592 return GATE_RESULT_OK;
1593 }
1594 gate_result_t gate_ui_ctrl_set_text(gate_ui_ctrl_t* ctrl, gate_string_t const* text)
1595 {
1596 gate_ui_gtk_dispatcher_t* disp;
1597 if (ctrl == NULL)
1598 {
1599 return GATE_RESULT_NULLPOINTER;
1600 }
1601 disp = GATE_UI_GTK_GET_CTRL_DISP(ctrl);
1602 if ((disp == NULL) || (disp->set_text == NULL))
1603 {
1604 return GATE_RESULT_NOTSUPPORTED;
1605 }
1606 return disp->set_text(ctrl, text);
1607 }
1608 gate_result_t gate_ui_ctrl_get_state(gate_ui_ctrl_t* ctrl, gate_int32_t* state)
1609 {
1610 gate_ui_gtk_dispatcher_t* disp;
1611 if (ctrl == NULL)
1612 {
1613 return GATE_RESULT_NULLPOINTER;
1614 }
1615 disp = GATE_UI_GTK_GET_CTRL_DISP(ctrl);
1616 if ((disp == NULL) || (disp->get_state == NULL))
1617 {
1618 return GATE_RESULT_NOTSUPPORTED;
1619 }
1620 return disp->get_state(ctrl, state);
1621 }
1622 gate_result_t gate_ui_ctrl_set_state(gate_ui_ctrl_t* ctrl, gate_int32_t state)
1623 {
1624 gate_ui_gtk_dispatcher_t* disp;
1625 if (ctrl == NULL)
1626 {
1627 return GATE_RESULT_NULLPOINTER;
1628 }
1629 disp = GATE_UI_GTK_GET_CTRL_DISP(ctrl);
1630 if ((disp == NULL) || (disp->set_state == NULL))
1631 {
1632 return GATE_RESULT_NOTSUPPORTED;
1633 }
1634 return disp->set_state(ctrl, state);
1635 }
1636 gate_result_t gate_ui_ctrl_refresh(gate_ui_ctrl_t* ctrl)
1637 {
1638 gate_ui_gtk_dispatcher_t* disp;
1639 GtkWidget* widget = GATE_UI_GTK_GET_CTRL_WIDGET(ctrl);
1640 if (ctrl == NULL)
1641 {
1642 return GATE_RESULT_NULLPOINTER;
1643 }
1644 disp = GATE_UI_GTK_GET_CTRL_DISP(ctrl);
1645 if ((disp == NULL) || (disp->refresh == NULL))
1646 {
1647 return gate_ui_gtk_ctrl_refresh(ctrl);
1648 }
1649 return disp->refresh(ctrl);
1650 }
1651
1652
1653 gate_result_t gate_ui_ctrl_set_enabled(gate_ui_ctrl_t* ctrl, gate_bool_t enabledstate)
1654 {
1655 return gate_ui_gtk_ctrl_set_enabled(ctrl, enabledstate);
1656 }
1657 gate_result_t gate_ui_ctrl_set_visible(gate_ui_ctrl_t* ctrl, gate_bool_t visibility)
1658 {
1659 return gate_ui_gtk_ctrl_set_visible(ctrl, visibility);
1660 }
1661 gate_result_t gate_ui_ctrl_set_focus(gate_ui_ctrl_t* ctrl)
1662 {
1663 return gate_ui_gtk_ctrl_set_focus(ctrl);
1664 }
1665 gate_result_t gate_ui_ctrl_set_position(gate_ui_ctrl_t* ctrl, gate_ui_point_t const* position, gate_ui_size_t const* size)
1666 {
1667 return gate_ui_gtk_ctrl_set_position(ctrl, position, size);
1668 }
1669
1670 #endif /*GATE_UI_GTK*/
1671
1672
1673
1674 #if defined(GATE_UI_MOTIF)
1675
1676 #include "gate/ui/gateui_motif.h"
1677 #include "gate/memalloc.h"
1678 #include "gate/debugging.h"
1679
1680 static char gate_ui_motif_app_class[] = "GATE_UI_MOTIF_APP_CLASS";
1681 static char gate_ui_motif_app_name[] = "GATE_UI_MOTIF_APP_NAME";
1682 static char empty_str[] = "";
1683
1684 ✗ gate_result_t gate_ui_host_init(gate_ui_host_t* host, gate_uintptr_t apphandle, void* userparam)
1685 {
1686 ✗ gate_result_t ret = GATE_RESULT_FAILED;
1687 ✗ XtAppContext app = NULL;
1688 ✗ Display* disp = NULL;
1689 ✗ Widget root = NULL;
1690 ✗ char* display_name = NULL;
1691 ✗ char default_display_name[] = ":0";
1692 ✗ char* app_name = gate_ui_motif_app_name;
1693 ✗ char* app_class = gate_ui_motif_app_class;
1694 ✗ int argc = 0;
1695 ✗ char* argv[] = { empty_str };
1696
1697 do
1698 {
1699 ✗ gate_mem_clear(host, sizeof(gate_ui_host_t));
1700 ✗ XtToolkitInitialize();
1701 ✗ app = XtCreateApplicationContext();
1702 ✗ if (!app)
1703 {
1704 ✗ ret = GATE_RESULT_OUTOFMEMORY;
1705 ✗ break;
1706 }
1707 ✗ disp = XtOpenDisplay(app, NULL, app_name, app_class, NULL, 0, &argc, argv);
1708 ✗ if (!disp)
1709 {
1710 ✗ disp = XtOpenDisplay(app, default_display_name, app_name, app_class, NULL, 0, &argc, argv);
1711 }
1712 ✗ if (!disp)
1713 {
1714 ✗ ret = GATE_RESULT_OUTOFMEMORY;
1715 ✗ break;
1716 }
1717
1718 ✗ GATE_UI_MOTIF_SET_HOST_APPHANDLE(host, app);
1719 ✗ GATE_UI_MOTIF_SET_HOST_DISPLAY(host, disp);
1720 ✗ GATE_UI_MOTIF_SET_HOST_USER_PARAM(host, userparam);
1721 ✗ GATE_UI_MOTIF_SET_HOST_ROOT(host, root);
1722
1723 ✗ ret = GATE_RESULT_OK;
1724 } while (0);
1725
1726 ✗ return ret;
1727 }
1728 ✗ gate_result_t gate_ui_host_uninit(gate_ui_host_t* host)
1729 {
1730 ✗ XtAppContext ctx = (XtAppContext)GATE_UI_MOTIF_GET_HOST_APPHANDLE(host);
1731 ✗ Display* disp = GATE_UI_MOTIF_GET_HOST_DISPLAY(host);
1732 ✗ gate_ui_motif_host_dispatch_pending_events(host, true);
1733
1734 ✗ XtCloseDisplay(disp);
1735 ✗ XtDestroyApplicationContext(ctx);
1736 ✗ gate_mem_clear(host, sizeof(gate_ui_host_t));
1737 ✗ return GATE_RESULT_OK;
1738 }
1739 ✗ gate_result_t gate_ui_host_run(gate_ui_host_t* host)
1740 {
1741 ✗ return gate_ui_motif_host_dispatch_events(host);
1742 }
1743
1744 ✗ static Boolean motif_host_quit_worker(XtPointer param)
1745 {
1746 ✗ XtAppContext ctx = (XtAppContext)param;
1747 ✗ if (ctx)
1748 {
1749 ✗ XtAppSetExitFlag(ctx);
1750 }
1751 ✗ return FALSE; /* do not call this worker again */
1752 }
1753
1754 ✗ gate_result_t gate_ui_host_quit(gate_ui_host_t* host)
1755 {
1756 ✗ XtAppContext ctx = (XtAppContext)GATE_UI_MOTIF_GET_HOST_APPHANDLE(host);
1757 ✗ return gate_ui_motif_host_add_native_workproc(host, &motif_host_quit_worker, ctx);
1758 }
1759 ✗ void* gate_ui_host_get_userparam(gate_ui_host_t* host)
1760 {
1761 ✗ return GATE_UI_MOTIF_GET_HOST_USER_PARAM(host);
1762 }
1763 ✗ gate_uintptr_t gate_ui_host_get_apphandle(gate_ui_host_t* host)
1764 {
1765 ✗ return GATE_UI_MOTIF_GET_HOST_APPHANDLE(host);
1766 }
1767 ✗ gate_uint32_t gate_ui_host_default_line_height(gate_ui_host_t* host)
1768 {
1769 ✗ gate_real32_t default_font_size_pt = 10.0f;
1770 ✗ return (gate_uint32_t)gate_ui_host_get_pixels_in_points(host, default_font_size_pt);
1771 }
1772 ✗ gate_uint32_t gate_ui_host_default_control_height(gate_ui_host_t* host, gate_uint32_t line_count)
1773 {
1774 ✗ gate_uint32_t line_height = gate_ui_host_default_line_height(host);
1775 ✗ return line_height * line_count + (line_height + 5);
1776 }
1777 ✗ gate_result_t gate_ui_host_enum_fonts(gate_ui_host_t* host, gate_ui_enum_fontnames_callback_t callback, void* userparam)
1778 {
1779 ✗ return GATE_RESULT_NOTIMPLEMENTED;
1780 }
1781 ✗ gate_result_t gate_ui_host_default_font(gate_ui_host_t* host, gate_uint32_t fonttype, gate_ui_font_t* font)
1782 {
1783 //gate_ui_host_enum_fonts(host, &gate_ui_enum_fontnames_callback_test, NULL);
1784 ✗ gate_str_print_text(font->font_name, sizeof(font->font_name), "Monospace", 9);
1785 ✗ font->size = 12;
1786 ✗ font->orientation = 0;
1787 ✗ font->bold = false;
1788 ✗ font->italic = false;
1789 ✗ font->underline = false;
1790 ✗ font->strikeout = false;
1791
1792 ✗ return GATE_RESULT_OK;
1793 }
1794
1795 ✗ static gate_int32_t gate_ui_host_get_default_dpi()
1796 {
1797 ✗ return 96;
1798 }
1799 ✗ gate_int32_t gate_ui_host_get_pixels_in_points(gate_ui_host_t* host, gate_real32_t points)
1800 {
1801 ✗ gate_int32_t dpi = gate_ui_host_get_default_dpi();
1802 (void)host;
1803 ✗ return (gate_int32_t)((points * (gate_real32_t)dpi / 72.0f) + 0.5f);
1804 }
1805 ✗ gate_real32_t gate_ui_host_get_points_in_pixels(gate_ui_host_t* host, gate_int32_t pixels)
1806 {
1807 ✗ gate_int32_t dpi = gate_ui_host_get_default_dpi();
1808 ✗ gate_int32_t tmp = (gate_int32_t)((pixels * 72.0f / (gate_real32_t)dpi) + 0.5f);
1809 (void)host;
1810 ✗ return (gate_real32_t)tmp;
1811 }
1812 ✗ gate_result_t gate_ui_host_default_color(gate_ui_host_t* host, gate_uint32_t colortype, gate_ui_color_t* col)
1813 {
1814 ✗ return GATE_RESULT_NOTIMPLEMENTED;
1815 }
1816 ✗ gate_result_t gate_ui_host_clipboard_get_text(gate_ui_host_t* host, gate_string_t* text)
1817 {
1818 ✗ return GATE_RESULT_NOTIMPLEMENTED;
1819 }
1820 ✗ gate_result_t gate_ui_host_clipboard_set_text(gate_ui_host_t* host, gate_string_t const* text)
1821 {
1822 ✗ return GATE_RESULT_NOTIMPLEMENTED;
1823 }
1824 ✗ gate_result_t gate_ui_host_default_workarea(gate_ui_host_t* host, gate_ui_position_t* area)
1825 {
1826 ✗ return GATE_RESULT_NOTIMPLEMENTED;
1827 }
1828 ✗ gate_result_t gate_ui_host_total_workarea(gate_ui_host_t* host, gate_ui_position_t* area)
1829 {
1830 ✗ return GATE_RESULT_NOTIMPLEMENTED;
1831 }
1832 ✗ gate_result_t gate_ui_host_execute(gate_ui_host_t* host, gate_runnable_t* code)
1833 {
1834 ✗ return gate_ui_motif_host_add_workproc(host, code);
1835 }
1836 ✗ gate_result_t gate_ui_host_process_events(gate_ui_host_t* host)
1837 {
1838 ✗ return gate_ui_motif_host_dispatch_pending_events(host, false);
1839 }
1840
1841
1842
1843 ✗ void* gate_ui_ctrl_get_userparam(gate_ui_ctrl_t* ctrl)
1844 {
1845 ✗ return GATE_UI_MOTIF_GET_CTRL_USER_PARAM(ctrl);
1846 }
1847
1848 ✗ gate_ui_host_t* gate_ui_ctrl_get_host(gate_ui_ctrl_t* ctrl)
1849 {
1850 ✗ return GATE_UI_MOTIF_GET_CTRL_HOST(ctrl);
1851 }
1852
1853 ✗ gate_ui_ctrl_t* gate_ui_ctrl_get_parent(gate_ui_ctrl_t* ctrl)
1854 {
1855 ✗ return GATE_UI_MOTIF_GET_CTRL_PARENT(ctrl);
1856 }
1857
1858 ✗ gate_result_t gate_ui_ctrl_destroy(gate_ui_ctrl_t* ctrl)
1859 {
1860 ✗ return gate_ui_motif_ctrl_destroy(ctrl);
1861 }
1862
1863 ✗ gate_bool_t gate_ui_ctrl_is_created(gate_ui_ctrl_t* ctrl)
1864 {
1865 ✗ Widget w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
1866 ✗ return w != NULL;
1867 }
1868
1869 ✗ gate_bool_t gate_ui_ctrl_is_enabled(gate_ui_ctrl_t* ctrl)
1870 {
1871 ✗ Widget w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
1872 ✗ return XtIsSensitive(w) ? true : false;
1873 }
1874
1875 ✗ gate_bool_t gate_ui_ctrl_is_visible(gate_ui_ctrl_t* ctrl)
1876 {
1877 ✗ Widget w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
1878 ✗ return XtIsRealized(w) ? true : false;
1879 }
1880
1881 ✗ gate_bool_t gate_ui_ctrl_is_focused(gate_ui_ctrl_t* ctrl)
1882 {
1883 ✗ return false;
1884 }
1885
1886 ✗ gate_result_t gate_ui_ctrl_get_position(gate_ui_ctrl_t* ctrl, gate_ui_position_t* position)
1887 {
1888 gate_result_t ret;
1889 Dimension x, y, width, height;
1890 Widget w;
1891 do
1892 {
1893 ✗ if (!ctrl || !position)
1894 {
1895 ✗ ret = GATE_RESULT_INVALIDARG;
1896 ✗ break;
1897 }
1898
1899 ✗ w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
1900 ✗ ret = gate_ui_motif_widget_get_position(w, &position->pos, &position->size);
1901 } while (0);
1902
1903 ✗ return ret;
1904 }
1905
1906 ✗ gate_result_t gate_ui_ctrl_get_size(gate_ui_ctrl_t* ctrl, gate_ui_size_t* size)
1907 {
1908 gate_result_t ret;
1909 Dimension width, height;
1910 Widget w;
1911 do
1912 {
1913 ✗ if (!ctrl || !size)
1914 {
1915 ✗ ret = GATE_RESULT_INVALIDARG;
1916 ✗ break;
1917 }
1918
1919 ✗ w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
1920 ✗ ret = gate_ui_motif_widget_get_position(w, NULL, size);
1921 } while (0);
1922 ✗ return ret;
1923 }
1924
1925 ✗ gate_result_t gate_ui_ctrl_get_children(gate_ui_ctrl_t* ctrl, gate_array_t* children)
1926 {
1927 ✗ gate_result_t ret = GATE_RESULT_FAILED;
1928 ✗ Widget child = NULL;
1929 ✗ WidgetList list = NULL;
1930 ✗ gate_size_t list_count = 0;
1931 gate_size_t ndx;
1932 ✗ gate_ui_ctrl_t* ptr_ctrl = NULL;
1933 ✗ gate_arraylist_t arr = NULL;
1934
1935 do
1936 {
1937 ✗ arr = gate_arraylist_create(sizeof(gate_ui_ctrl_t*), NULL, 0, NULL, NULL);
1938 ✗ if (!arr)
1939 {
1940 ✗ ret = GATE_RESULT_OUTOFMEMORY;
1941 ✗ break;
1942 }
1943
1944 ✗ ret = gate_ui_motif_ctrl_get_children(ctrl, (void**)&list, &list_count);
1945 ✗ GATE_BREAK_IF_FAILED(ret);
1946
1947 ✗ for (ndx = 0; ndx != list_count; ++ndx)
1948 {
1949 ✗ child = list[ndx];
1950 ✗ if (!child)
1951 {
1952 ✗ continue;
1953 }
1954 ✗ ptr_ctrl = gate_ui_motif_widget_get_ctrl(child);
1955 ✗ if (!ptr_ctrl)
1956 {
1957 ✗ continue;
1958 }
1959 ✗ gate_arraylist_add(arr, &ptr_ctrl);
1960 }
1961
1962 ✗ if (NULL == gate_array_create(children, arr))
1963 {
1964 ✗ ret = GATE_RESULT_OUTOFMEMORY;
1965 ✗ break;
1966 }
1967 ✗ ret = GATE_RESULT_OK;
1968 } while (0);
1969
1970 ✗ gate_arraylist_release(arr);
1971 ✗ return ret;
1972 }
1973
1974 ✗ gate_result_t gate_ui_ctrl_get_text(gate_ui_ctrl_t* ctrl, gate_string_t* text)
1975 {
1976 ✗ gate_ui_motif_dispatcher_t* ptr_disp = NULL;
1977 ✗ Widget w = NULL;
1978 ✗ if (!ctrl || !text)
1979 {
1980 ✗ return GATE_RESULT_INVALIDARG;
1981 }
1982 ✗ ptr_disp = GATE_UI_MOTIF_GET_CTRL_DISP(ctrl);
1983 ✗ if (ptr_disp && ptr_disp->get_text)
1984 {
1985 ✗ return ptr_disp->get_text(ctrl, text);
1986 }
1987 ✗ w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
1988 ✗ if (!w)
1989 {
1990 ✗ return GATE_RESULT_INVALIDARG;
1991 }
1992 ✗ return gate_ui_motif_widget_get_label(w, text);
1993 }
1994
1995 ✗ gate_result_t gate_ui_ctrl_get_text_length(gate_ui_ctrl_t* ctrl, gate_uint32_t* length)
1996 {
1997 ✗ gate_string_t text = GATE_STRING_INIT_EMPTY;
1998 ✗ gate_result_t ret = gate_ui_ctrl_get_text(ctrl, &text);
1999 ✗ if (GATE_SUCCEEDED(ret) && length)
2000 {
2001 ✗ *length = (gate_uint32_t)gate_string_length(&text);
2002 }
2003 ✗ gate_string_release(&text);
2004 ✗ return ret;
2005 }
2006
2007 ✗ gate_result_t gate_ui_ctrl_get_state(gate_ui_ctrl_t* ctrl, gate_int32_t* ptr_state)
2008 {
2009 ✗ gate_ui_motif_dispatcher_t* ptr_disp = NULL;
2010 ✗ Widget w = NULL;
2011 ✗ if (!ctrl || !ptr_state)
2012 {
2013 ✗ return GATE_RESULT_INVALIDARG;
2014 }
2015 ✗ ptr_disp = GATE_UI_MOTIF_GET_CTRL_DISP(ctrl);
2016 ✗ if (ptr_disp && ptr_disp->get_state)
2017 {
2018 ✗ return ptr_disp->get_state(ctrl, ptr_state);
2019 }
2020 ✗ return GATE_RESULT_NOTSUPPORTED;
2021 }
2022
2023 ✗ gate_result_t gate_ui_ctrl_set_enabled(gate_ui_ctrl_t* ctrl, gate_bool_t enabledstate)
2024 {
2025 Widget w;
2026 ✗ if (!ctrl)
2027 {
2028 ✗ return GATE_RESULT_INVALIDARG;
2029 }
2030 ✗ w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
2031 ✗ if (!w)
2032 {
2033 ✗ return GATE_RESULT_INVALIDSTATE;
2034 }
2035 ✗ XtSetSensitive(w, enabledstate);
2036 ✗ return GATE_RESULT_OK;
2037 }
2038 ✗ gate_result_t gate_ui_ctrl_set_visible(gate_ui_ctrl_t* ctrl, gate_bool_t visibility)
2039 {
2040 Widget w;
2041 gate_ui_host_t* host;
2042 ✗ if (!ctrl)
2043 {
2044 ✗ return GATE_RESULT_INVALIDARG;
2045 }
2046 ✗ w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
2047 ✗ if (!w)
2048 {
2049 ✗ return GATE_RESULT_INVALIDSTATE;
2050 }
2051 ✗ if (visibility)
2052 {
2053 ✗ XtMapWidget(w);
2054 ✗ host = gate_ui_ctrl_get_host(ctrl);
2055 ✗ gate_ui_motif_host_dispatch_pending_events(host, false);
2056 ✗ return gate_ui_ctrl_refresh(ctrl);
2057 }
2058 else
2059 {
2060 ✗ XtUnmapWidget(w);
2061 ✗ return GATE_RESULT_OK;
2062 }
2063 }
2064 ✗ gate_result_t gate_ui_ctrl_set_focus(gate_ui_ctrl_t* ctrl)
2065 {
2066 Widget w;
2067 ✗ if (!ctrl)
2068 {
2069 ✗ return GATE_RESULT_INVALIDARG;
2070 }
2071 ✗ w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
2072 ✗ if (!w)
2073 {
2074 ✗ return GATE_RESULT_INVALIDSTATE;
2075 }
2076 ✗ XmProcessTraversal(w, XmTRAVERSE_CURRENT);
2077 ✗ return GATE_RESULT_OK;
2078 }
2079 ✗ gate_result_t gate_ui_ctrl_set_position(gate_ui_ctrl_t* ctrl, gate_ui_point_t const* position, gate_ui_size_t const* size)
2080 {
2081 Widget w;
2082 ✗ if (!ctrl)
2083 {
2084 ✗ return GATE_RESULT_INVALIDARG;
2085 }
2086 ✗ w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
2087 ✗ if (!w)
2088 {
2089 ✗ return GATE_RESULT_INVALIDSTATE;
2090 }
2091 ✗ return gate_ui_motif_widget_set_position(w, position, size);
2092 }
2093 ✗ gate_result_t gate_ui_ctrl_set_text(gate_ui_ctrl_t* ctrl, gate_string_t const* text)
2094 {
2095 ✗ gate_ui_motif_dispatcher_t* ptr_disp = NULL;
2096 Widget w;
2097 ✗ if (!ctrl || !text)
2098 {
2099 ✗ return GATE_RESULT_INVALIDARG;
2100 }
2101 ✗ ptr_disp = GATE_UI_MOTIF_GET_CTRL_DISP(ctrl);
2102 ✗ if (ptr_disp && ptr_disp->set_text)
2103 {
2104 ✗ return ptr_disp->set_text(ctrl, text);
2105 }
2106 ✗ w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
2107 ✗ if (!w)
2108 {
2109 ✗ return GATE_RESULT_INVALIDSTATE;
2110 }
2111 ✗ return gate_ui_motif_widget_set_label(w, text);
2112 }
2113 ✗ gate_result_t gate_ui_ctrl_set_state(gate_ui_ctrl_t* ctrl, gate_int32_t state)
2114 {
2115 ✗ gate_ui_motif_dispatcher_t* ptr_disp = NULL;
2116 ✗ Widget w = NULL;
2117 ✗ if (!ctrl)
2118 {
2119 ✗ return GATE_RESULT_INVALIDARG;
2120 }
2121 ✗ ptr_disp = GATE_UI_MOTIF_GET_CTRL_DISP(ctrl);
2122 ✗ if (ptr_disp && ptr_disp->set_state)
2123 {
2124 ✗ return ptr_disp->set_state(ctrl, state);
2125 }
2126 ✗ return GATE_RESULT_NOTSUPPORTED;
2127 }
2128 ✗ gate_result_t gate_ui_ctrl_refresh(gate_ui_ctrl_t* ctrl)
2129 {
2130 ✗ gate_ui_motif_dispatcher_t* disp = NULL;
2131 ✗ if (!ctrl)
2132 {
2133 ✗ return GATE_RESULT_INVALIDARG;
2134 }
2135 ✗ disp = GATE_UI_MOTIF_GET_CTRL_DISP(ctrl);
2136 ✗ if (disp && disp->refresh)
2137 {
2138 ✗ return disp->refresh(ctrl);
2139 }
2140 else
2141 {
2142 ✗ return gate_ui_motif_ctrl_refresh(ctrl);
2143 }
2144 }
2145
2146
2147 #endif /* GATE_UI_MOTIF */
2148
2149
2150
2151 #if defined(GATE_UI_WASMHTML)
2152
2153 #include "gate/ui/gateui_wasmhtml.h"
2154
2155
2156 gate_result_t gate_ui_host_init(gate_ui_host_t* host, gate_uintptr_t apphandle, void* userparam)
2157 {
2158 return gate_ui_wasm_host_init(host, apphandle, userparam);
2159 }
2160 gate_result_t gate_ui_host_uninit(gate_ui_host_t* host)
2161 {
2162 return gate_ui_wasm_host_uninit(host);
2163 }
2164 gate_result_t gate_ui_host_run(gate_ui_host_t* host)
2165 {
2166 gate_result_t ret = GATE_RESULT_OK;
2167 return ret;
2168 }
2169 gate_result_t gate_ui_host_quit(gate_ui_host_t* host)
2170 {
2171 gate_result_t ret = GATE_RESULT_OK;
2172 return ret;
2173 }
2174 void* gate_ui_host_get_userparam(gate_ui_host_t* host)
2175 {
2176 return GATE_UI_WASM_GET_HOST_USER_PARAM(host);
2177 }
2178 gate_uintptr_t gate_ui_host_get_apphandle(gate_ui_host_t* host)
2179 {
2180 return GATE_UI_WASM_GET_HOST_APPHANDLE(host);
2181 }
2182 gate_uint32_t gate_ui_host_default_line_height(gate_ui_host_t* host)
2183 {
2184 return GATE_UI_WASM_GET_HOST_LINEHEIGHT(host);
2185 }
2186 gate_uint32_t gate_ui_host_default_control_height(gate_ui_host_t* host, gate_uint32_t line_count)
2187 {
2188 const gate_uint32_t line_height = GATE_UI_WASM_GET_HOST_LINEHEIGHT(host);
2189 gate_uint32_t height = line_height * 14 / 8;
2190 if (line_count > 1)
2191 {
2192 height += (line_count - 1) * line_height;
2193 }
2194 ++height;
2195 return height;
2196 }
2197
2198 static gate_int32_t gate_ui_host_get_default_dpi()
2199 {
2200 return 96;
2201 }
2202
2203 gate_int32_t gate_ui_host_get_pixels_in_points(gate_ui_host_t* host, gate_real32_t points)
2204 {
2205 gate_int32_t dpi = gate_ui_host_get_default_dpi();
2206 (void)host;
2207 return (gate_int32_t)((points * (gate_real32_t)dpi / 72.0f) + 0.5f);
2208 }
2209 gate_real32_t gate_ui_host_get_points_in_pixels(gate_ui_host_t* host, gate_int32_t pixels)
2210 {
2211 gate_int32_t dpi = gate_ui_host_get_default_dpi();
2212 gate_int32_t tmp = (gate_int32_t)((pixels * 72.0f / (gate_real32_t)dpi) + 0.5f);
2213 (void)host;
2214 return (gate_real32_t)tmp;
2215 }
2216 gate_result_t gate_ui_host_default_color(gate_ui_host_t* host, gate_uint32_t colortype, gate_ui_color_t* col)
2217 {
2218 return GATE_RESULT_NOTIMPLEMENTED;
2219 }
2220 gate_result_t gate_ui_host_clipboard_get_text(gate_ui_host_t* host, gate_string_t* text)
2221 {
2222 return GATE_RESULT_NOTIMPLEMENTED;
2223 }
2224 gate_result_t gate_ui_host_clipboard_set_text(gate_ui_host_t* host, gate_string_t const* text)
2225 {
2226 return GATE_RESULT_NOTIMPLEMENTED;
2227 }
2228 gate_result_t gate_ui_host_default_workarea(gate_ui_host_t* host, gate_ui_position_t* area)
2229 {
2230 return GATE_RESULT_NOTIMPLEMENTED;
2231 }
2232 gate_result_t gate_ui_host_total_workarea(gate_ui_host_t* host, gate_ui_position_t* area)
2233 {
2234 return GATE_RESULT_NOTIMPLEMENTED;
2235 }
2236 gate_result_t gate_ui_host_execute(gate_ui_host_t* host, gate_runnable_t* code)
2237 {
2238 return GATE_RESULT_NOTIMPLEMENTED;
2239 }
2240 gate_result_t gate_ui_host_process_events(gate_ui_host_t* host)
2241 {
2242 return GATE_RESULT_NOTIMPLEMENTED;
2243 }
2244
2245
2246
2247 void* gate_ui_ctrl_get_userparam(gate_ui_ctrl_t* ctrl)
2248 {
2249 return GATE_UI_WASM_GET_CTRL_USER_PARAM(ctrl);
2250 }
2251
2252 gate_ui_host_t* gate_ui_ctrl_get_host(gate_ui_ctrl_t* ctrl)
2253 {
2254 return GATE_UI_WASM_GET_CTRL_HOST(ctrl);
2255 }
2256
2257 gate_ui_ctrl_t* gate_ui_ctrl_get_parent(gate_ui_ctrl_t* ctrl)
2258 {
2259 return NULL;
2260 }
2261
2262 gate_result_t gate_ui_ctrl_destroy(gate_ui_ctrl_t* ctrl)
2263 {
2264 return GATE_RESULT_NOTIMPLEMENTED;
2265 }
2266
2267 gate_bool_t gate_ui_ctrl_is_created(gate_ui_ctrl_t* ctrl)
2268 {
2269 return false;
2270 }
2271
2272 gate_bool_t gate_ui_ctrl_is_enabled(gate_ui_ctrl_t* ctrl)
2273 {
2274 return false;
2275 }
2276
2277 gate_bool_t gate_ui_ctrl_is_visible(gate_ui_ctrl_t* ctrl)
2278 {
2279 return false;
2280 }
2281
2282 gate_bool_t gate_ui_ctrl_is_focused(gate_ui_ctrl_t* ctrl)
2283 {
2284 return false;
2285 }
2286
2287 gate_result_t gate_ui_ctrl_get_position(gate_ui_ctrl_t* ctrl, gate_ui_position_t* position)
2288 {
2289 return GATE_RESULT_NOTIMPLEMENTED;
2290 }
2291
2292 gate_result_t gate_ui_ctrl_get_size(gate_ui_ctrl_t* ctrl, gate_ui_size_t* size)
2293 {
2294 return GATE_RESULT_NOTIMPLEMENTED;
2295 }
2296
2297 gate_result_t gate_ui_ctrl_get_children(gate_ui_ctrl_t* ctrl, gate_array_t* children)
2298 {
2299 return GATE_RESULT_NOTIMPLEMENTED;
2300 }
2301
2302 gate_result_t gate_ui_ctrl_get_text(gate_ui_ctrl_t* ctrl, gate_string_t* text)
2303 {
2304 return GATE_RESULT_NOTIMPLEMENTED;
2305 }
2306
2307 gate_result_t gate_ui_ctrl_get_text_length(gate_ui_ctrl_t* ctrl, gate_uint32_t* length)
2308 {
2309 return GATE_RESULT_NOTIMPLEMENTED;
2310 }
2311
2312 gate_result_t gate_ui_ctrl_get_state(gate_ui_ctrl_t* ctrl, gate_int32_t* ptr_state)
2313 {
2314 return GATE_RESULT_NOTIMPLEMENTED;
2315 }
2316
2317 gate_result_t gate_ui_ctrl_set_enabled(gate_ui_ctrl_t* ctrl, gate_bool_t enabledstate)
2318 {
2319 return GATE_RESULT_NOTIMPLEMENTED;
2320 }
2321 gate_result_t gate_ui_ctrl_set_visible(gate_ui_ctrl_t* ctrl, gate_bool_t visibility)
2322 {
2323 return GATE_RESULT_NOTIMPLEMENTED;
2324 }
2325 gate_result_t gate_ui_ctrl_set_focus(gate_ui_ctrl_t* ctrl)
2326 {
2327 return GATE_RESULT_NOTIMPLEMENTED;
2328 }
2329 gate_result_t gate_ui_ctrl_set_position(gate_ui_ctrl_t* ctrl, gate_ui_point_t const* position, gate_ui_size_t const* size)
2330 {
2331 return GATE_RESULT_NOTIMPLEMENTED;
2332 }
2333 gate_result_t gate_ui_ctrl_set_text(gate_ui_ctrl_t* ctrl, gate_string_t const* text)
2334 {
2335 return GATE_RESULT_NOTIMPLEMENTED;
2336 }
2337 gate_result_t gate_ui_ctrl_set_state(gate_ui_ctrl_t* ctrl, gate_int32_t state)
2338 {
2339 return GATE_RESULT_NOTIMPLEMENTED;
2340 }
2341
2342 gate_result_t gate_ui_ctrl_refresh(gate_ui_ctrl_t* ctrl)
2343 {
2344 return GATE_RESULT_NOTIMPLEMENTED;
2345 }
2346
2347
2348
2349 #endif
2350