GCC Code Coverage Report


Directory: src/gate/
File: src/gate/ui/gateui_motif.c
Date: 2025-09-22 22:57:09
Exec Total Coverage
Lines: 0 348 0.0%
Functions: 0 27 0.0%
Branches: 0 162 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_motif.h"
30 #include "gate/results.h"
31 #include "gate/debugging.h"
32
33 #if defined(GATE_UI_MOTIF)
34
35 #include <Xm/Xm.h>
36 #include <Xm/Primitive.h>
37 #include <X11/Intrinsic.h>
38 #include <Xm/BulletinB.h>
39 #include <X11/IntrinsicP.h>
40
41
42 ✗ gate_result_t gate_ui_motif_ctrl_init(gate_ui_ctrl_t* ctrl, Widget widget, void* userparam,
43 gate_ui_host_t* host, gate_ui_ctrl_t* parent, Widget container,
44 gate_ui_position_t const* position, gate_uint32_t const* flags,
45 gate_ui_motif_dispatcher_t* dispatcher)
46 {
47 ✗ gate_result_t ret = GATE_RESULT_FAILED;
48 ✗ if (!host && parent)
49 {
50 ✗ host = GATE_UI_MOTIF_GET_CTRL_HOST(parent);
51 }
52
53 ✗ GATE_DEBUG_ASSERT(ctrl != NULL);
54
55 do
56 {
57 ✗ GATE_UI_MOTIF_SET_CTRL_WIDGET(ctrl, widget);
58 ✗ GATE_UI_MOTIF_SET_CTRL_HOST(ctrl, host);
59 ✗ GATE_UI_MOTIF_SET_CTRL_USER_PARAM(ctrl, userparam);
60 ✗ GATE_UI_MOTIF_SET_CTRL_PARENT(ctrl, parent);
61 ✗ GATE_UI_MOTIF_SET_CTRL_CONTAINER(ctrl, container);
62 ✗ GATE_UI_MOTIF_SET_CTRL_DISP(ctrl, dispatcher);
63
64
65 ✗ if (gate_ui_motif_widget_is_valid(widget))
66 {
67 ✗ XtSetMappedWhenManaged(widget, False);
68 ✗ if (position)
69 {
70 ✗ if ((position->size.width > 0) && (position->size.height > 0))
71 {
72 ✗ gate_ui_motif_widget_set_position(widget, &position->pos, &position->size);
73 }
74 }
75 else
76 {
77 ✗ if (parent)
78 {
79 static const gate_ui_point_t p = { 0, 0 };
80 static const gate_ui_size_t s = { 128, 48 };
81 ✗ gate_ui_motif_widget_set_position(widget, &p, &s);
82 }
83 }
84 ✗ XtVaSetValues(widget, XmNuserData, ctrl, NULL, NULL);
85 ✗ XtRealizeWidget(widget);
86 ✗ if (flags)
87 {
88 ✗ if (GATE_FLAG_ENABLED(*flags, GATE_UI_FLAG_VISIBLE))
89 {
90 ✗ XtMapWidget(widget);
91 }
92 }
93 }
94
95 ✗ if (gate_ui_motif_widget_is_valid(container))
96 {
97 ✗ XtVaSetValues(container, XmNuserData, ctrl, NULL, NULL);
98 ✗ XtRealizeWidget(container);
99 ✗ XtMapWidget(container);
100
101 ✗ ret = gate_ui_motif_host_dispatch_pending_events(host, false);
102 }
103 else
104 {
105 ✗ ret = GATE_RESULT_OK;
106 }
107 } while (0);
108
109 ✗ return ret;
110 }
111
112 static char gate_ui_motif_ctrl_widget[] = "GATE_UI_MOTIF_CTRL_WIDGET_";
113 static gate_atomic_int_t gate_ui_motif_widget_counter;
114
115 ✗ static void gate_ui_motif_generate_widget_name(char* buffer, gate_size_t buffer_capacity)
116 {
117 gate_strbuilder_t builder;
118 ✗ gate_strbuilder_create_static(&builder, buffer, buffer_capacity, 0);
119 ✗ gate_strbuilder_append_text(&builder, gate_ui_motif_ctrl_widget, sizeof(gate_ui_motif_ctrl_widget) - 1);
120 ✗ gate_strbuilder_append_int32(&builder, gate_atomic_int_inc(&gate_ui_motif_widget_counter));
121 ✗ }
122
123 ✗ gate_result_t gate_ui_motif_ctrl_create(gate_ui_ctrl_t* ctrl, WidgetClass widget_class, void* userparam,
124 gate_ui_host_t* host, gate_ui_ctrl_t* parent,
125 gate_ui_position_t const* position, gate_uint32_t const* flags,
126 gate_bool_t add_container, gate_ui_motif_dispatcher_t* dispatcher,
127 void* args, gate_size_t args_count)
128 {
129 ✗ gate_result_t ret = GATE_RESULT_OK;
130 ✗ Widget parent_widget = NULL;
131 ✗ Widget paremt_container = NULL;
132 ✗ Widget new_widget = NULL;
133 ✗ Widget new_container = NULL;
134 ✗ Display* disp = NULL;
135 char widget_name[64];
136
137 do
138 {
139 ✗ gate_ui_motif_generate_widget_name(widget_name, sizeof(widget_name));
140 ✗ if (parent)
141 {
142 ✗ parent_widget = GATE_UI_MOTIF_GET_CTRL_CONTAINER(parent);
143 ✗ if (!parent_widget)
144 {
145 ✗ parent_widget = GATE_UI_MOTIF_GET_CTRL_WIDGET(parent);
146 }
147 ✗ new_widget = XtCreateWidget(widget_name, widget_class, parent_widget,
148 (ArgList)args, args_count);
149 }
150 ✗ else if (host)
151 {
152 ✗ disp = GATE_UI_MOTIF_GET_HOST_DISPLAY(host);
153 ✗ new_widget = XtAppCreateShell(NULL, NULL, widget_class, disp,
154 (ArgList)args, args_count);
155 }
156 else
157 {
158 ✗ ret = GATE_RESULT_INVALIDARG;
159 ✗ break;
160 }
161
162 ✗ if (NULL == new_widget)
163 {
164 ✗ ret = GATE_RESULT_FAILED;
165 ✗ break;
166 }
167
168 ✗ if (parent)
169 {
170 ✗ XtManageChild(new_widget);
171 }
172 else
173 {
174 ✗ XtRealizeWidget(new_widget);
175 }
176
177 ✗ if (add_container)
178 {
179 ✗ gate_ui_motif_generate_widget_name(widget_name, sizeof(widget_name));
180 ✗ new_container = XtCreateWidget(widget_name, xmBulletinBoardWidgetClass, new_widget, NULL, 0);
181 ✗ if (!new_container)
182 {
183 ✗ XtDestroyWidget(new_widget);
184 ✗ ret = GATE_RESULT_FAILED;
185 ✗ break;
186 }
187 ✗ XtVaSetValues(new_container,
188 XmNresizePolicy, XmRESIZE_NONE,
189 XmNnoResize, True,
190 XmNmarginWidth, 0,
191 XmNmarginHeight, 0,
192 NULL);
193 ✗ XtManageChild(new_container);
194 }
195
196 ✗ if (!host && parent)
197 {
198 ✗ host = GATE_UI_MOTIF_GET_CTRL_HOST(parent);
199 }
200
201 ✗ ret = gate_ui_motif_ctrl_init(ctrl, new_widget, userparam, host, parent, new_container, position, flags, dispatcher);
202 } while (0);
203 ✗ return ret;
204 }
205
206 ✗ gate_result_t gate_ui_motif_ctrl_destroy_default(gate_ui_ctrl_t* ctrl)
207 {
208 ✗ gate_result_t result = GATE_RESULT_OK;
209 ✗ gate_ui_ctrl_t* ptr_parent = NULL;
210 ✗ gate_array_t list_children = GATE_INIT_EMPTY;
211 Widget w, c;
212 gate_size_t ndx, len;
213 ✗ gate_ui_ctrl_t** ptr_childctrl = NULL;
214
215 ✗ GATE_DEBUG_ASSERT(ctrl != NULL);
216
217 /* destroy child controls first */
218 ✗ result = gate_ui_ctrl_get_children(ctrl, &list_children);
219 ✗ if (GATE_SUCCEEDED(result))
220 {
221 ✗ len = gate_array_length(&list_children);
222 ✗ for (ndx = 0; ndx != len; ++ndx)
223 {
224 ✗ ptr_childctrl = (gate_ui_ctrl_t**)gate_array_get(&list_children, ndx);
225 ✗ if (ptr_childctrl)
226 {
227 ✗ gate_ui_motif_ctrl_destroy(*ptr_childctrl);
228 }
229 }
230 ✗ gate_array_release(&list_children);
231 }
232
233 ✗ c = GATE_UI_MOTIF_GET_CTRL_CONTAINER(ctrl);
234 ✗ if (gate_ui_motif_widget_is_valid(c))
235 {
236 ✗ if (XtIsRealized(c))
237 {
238 ✗ XtUnrealizeWidget(c);
239 }
240 ✗ XtUnmanageChild(c);
241 ✗ XtDestroyWidget(c);
242 ✗ GATE_UI_MOTIF_SET_CTRL_CONTAINER(ctrl, NULL);
243 }
244
245 ✗ w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
246 ✗ if (gate_ui_motif_widget_is_valid(w))
247 {
248 ✗ if (XtIsRealized(w))
249 {
250 ✗ XtUnrealizeWidget(w);
251 }
252 ✗ ptr_parent = GATE_UI_MOTIF_GET_CTRL_PARENT(ctrl);
253 ✗ if (ptr_parent)
254 {
255 ✗ XtUnmanageChild(w);
256 ✗ GATE_UI_MOTIF_SET_CTRL_PARENT(ctrl, NULL);
257 }
258 ✗ XtDestroyWidget(w);
259 ✗ GATE_UI_MOTIF_SET_CTRL_WIDGET(ctrl, NULL);
260 ✗ GATE_UI_MOTIF_SET_CTRL_USER_PARAM(ctrl, NULL);
261 ✗ GATE_UI_MOTIF_SET_CTRL_HOST(ctrl, NULL);
262 ✗ GATE_UI_MOTIF_SET_CTRL_DISP(ctrl, NULL);
263 }
264 ✗ return GATE_RESULT_OK;
265 }
266
267
268 ✗ gate_result_t gate_ui_motif_ctrl_destroy(gate_ui_ctrl_t* ctrl)
269 {
270 ✗ gate_result_t ret = GATE_RESULT_OK;
271 ✗ gate_ui_motif_dispatcher_t* ptr_disp = NULL;
272 ✗ gate_ui_host_t* host = NULL;
273
274 ✗ GATE_DEBUG_ASSERT(ctrl != NULL);
275 do
276 {
277 ✗ ptr_disp = GATE_UI_MOTIF_GET_CTRL_DISP(ctrl);
278 ✗ if (ptr_disp && ptr_disp->destroy)
279 {
280 ✗ ret = ptr_disp->destroy(ctrl);
281 }
282 else
283 {
284 ✗ ret = gate_ui_motif_ctrl_destroy_default(ctrl);
285 }
286 ✗ GATE_BREAK_IF_FAILED(ret);
287
288 ✗ host = GATE_UI_MOTIF_GET_CTRL_HOST(ctrl);
289 ✗ if (host)
290 {
291 ✗ ret = gate_ui_motif_host_dispatch_pending_events(host, false);
292 ✗ GATE_UI_MOTIF_SET_CTRL_HOST(ctrl, NULL);
293 }
294
295 ✗ GATE_UI_MOTIF_SET_CTRL_DISP(ctrl, NULL);
296 } while (0);
297
298 ✗ return ret;
299 }
300
301 ✗ gate_result_t gate_ui_motif_ctrl_get_text(gate_ui_ctrl_t* ctrl, gate_string_t* ptr_text)
302 {
303 ✗ gate_ui_motif_dispatcher_t* ptr_disp = NULL;
304 Widget w;
305
306 ✗ if (!ctrl)
307 {
308 ✗ return GATE_RESULT_INVALIDARG;
309 }
310 ✗ ptr_disp = GATE_UI_MOTIF_GET_CTRL_DISP(ctrl);
311 ✗ if (ptr_disp && ptr_disp->get_text)
312 {
313 ✗ return ptr_disp->get_text(ctrl, ptr_text);
314 }
315 ✗ w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
316 ✗ return gate_ui_motif_widget_get_label(w, ptr_text);
317 }
318
319 ✗ gate_result_t gate_ui_motif_ctrl_set_text(gate_ui_ctrl_t* ctrl, gate_string_t const* ptr_text)
320 {
321 ✗ gate_ui_motif_dispatcher_t* ptr_disp = NULL;
322 Widget w;
323
324 ✗ if (!ctrl)
325 {
326 ✗ return GATE_RESULT_INVALIDARG;
327 }
328 ✗ ptr_disp = GATE_UI_MOTIF_GET_CTRL_DISP(ctrl);
329 ✗ if (ptr_disp && ptr_disp->set_text)
330 {
331 ✗ return ptr_disp->set_text(ctrl, ptr_text);
332 }
333 ✗ w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
334 ✗ return gate_ui_motif_widget_set_label(w, ptr_text);
335 }
336
337
338 ✗ gate_ui_ctrl_t* gate_ui_motif_widget_get_ctrl(Widget widget)
339 {
340 ✗ gate_ui_ctrl_t* ptr_ctrl = NULL;
341 ✗ if (gate_ui_motif_widget_is_valid(widget))
342 {
343 ✗ XtVaGetValues(widget, XmNuserData, &ptr_ctrl, NULL, NULL);
344 }
345 ✗ return ptr_ctrl;
346 }
347
348
349 ✗ gate_result_t gate_ui_motif_widget_get_label(Widget widget, gate_string_t* label)
350 {
351 ✗ String str = NULL;
352 ✗ if (!gate_ui_motif_widget_is_valid(widget) || !label)
353 {
354 ✗ return GATE_RESULT_INVALIDARG;
355 }
356 ✗ XtVaGetValues(widget, XtNlabel, &str, NULL);
357 ✗ if (NULL == gate_string_create(label, str, gate_str_length(str)))
358 {
359 ✗ return GATE_RESULT_OUTOFMEMORY;
360 }
361 ✗ return GATE_RESULT_OK;
362 }
363
364 ✗ XmString gate_ui_motif_create_string(gate_string_t const* text)
365 {
366 ✗ XmString ret = NULL;
367 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
368 ✗ char* ptr_buffer = &buffer[0];
369 ✗ gate_size_t bufferlen = sizeof(buffer) / sizeof(buffer[0]);
370 ✗ gate_size_t textlen = gate_string_length(text);
371
372 do
373 {
374 ✗ if (textlen >= bufferlen)
375 {
376 ✗ bufferlen = textlen + 4;
377 ✗ ptr_buffer = (char*)gate_mem_alloc(bufferlen);
378 ✗ if (NULL == ptr_buffer)
379 {
380 ✗ break;
381 }
382 }
383
384 ✗ gate_string_to_buffer(text, ptr_buffer, bufferlen);
385 ✗ ret = XmStringCreateLocalized(ptr_buffer);
386 } while (0);
387
388 ✗ if (ptr_buffer && ptr_buffer != &buffer[0])
389 {
390 ✗ gate_mem_dealloc(ptr_buffer);
391 }
392
393 ✗ return ret;
394 }
395
396 ✗ XmString gate_ui_motif_create_chr_string(char const* text)
397 {
398 gate_string_t str;
399 ✗ gate_string_create_static(&str, text);
400 ✗ return gate_ui_motif_create_string(&str);
401 }
402
403 ✗ gate_result_t gate_ui_motif_convert_string(XmString from, gate_string_t* to)
404 {
405 ✗ gate_result_t ret = GATE_RESULT_OK;
406 ✗ char* text = (char*)XmStringUnparse(from, XmSTRING_DEFAULT_CHARSET, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL);
407 ✗ if (text)
408 {
409 ✗ if (NULL == gate_string_create(to, text, gate_str_length(text)))
410 {
411 ✗ ret = GATE_RESULT_OUTOFMEMORY;
412 }
413 ✗ XtFree(text);
414 }
415 else
416 {
417 ✗ gate_string_create_empty(to);
418 }
419 ✗ return ret;
420 }
421
422 ✗ gate_bool_t gate_ui_motif_widget_is_valid(Widget widget)
423 {
424 ✗ return (widget != NULL) && (widget != (Widget)(gate_intptr_t)-1);
425 }
426
427
428 ✗ gate_result_t gate_ui_motif_widget_set_label(Widget widget, gate_string_t const* text)
429 {
430 gate_result_t ret;
431 ✗ XmString xmstr = NULL;
432
433 do
434 {
435 ✗ if (!gate_ui_motif_widget_is_valid(widget))
436 {
437 ✗ ret = GATE_RESULT_INVALIDARG;
438 ✗ break;
439 }
440
441 ✗ xmstr = gate_ui_motif_create_string(text);
442 ✗ if (NULL == xmstr)
443 {
444 ✗ ret = GATE_RESULT_OUTOFMEMORY;
445 ✗ break;
446 }
447
448 ✗ XtVaSetValues(widget, XmNlabelString, xmstr, NULL, NULL);
449 ✗ ret = GATE_RESULT_OK;
450
451 } while (0);
452
453 ✗ if (xmstr)
454 {
455 ✗ XmStringFree(xmstr);
456 }
457
458 ✗ return ret;
459 }
460
461 ✗ void gate_ui_motif_widget_get_children(Widget widget, Widget** ptr_children, gate_size_t* ptr_count)
462 {
463 ✗ WidgetList children = NULL;
464 ✗ Cardinal num_children = 0;
465
466 ✗ GATE_DEBUG_ASSERT(widget != NULL);
467 ✗ XtVaGetValues(widget, XmNchildren, &children, XmNnumChildren, &num_children, NULL, NULL);
468 ✗ if (ptr_children)
469 {
470 ✗ *ptr_children = children;
471 }
472 ✗ if (ptr_count)
473 {
474 ✗ *ptr_count = num_children;
475 }
476 ✗ }
477
478
479 ✗ void gate_ui_motif_widget_destroy_children(Widget parent_widget, gate_bool_t destroy_parent)
480 {
481 ✗ WidgetList children = NULL;
482 Widget child_widget;
483 ✗ Cardinal num_children = 0;
484
485 ✗ GATE_DEBUG_ASSERT(parent_widget != NULL);
486 ✗ XtVaGetValues(parent_widget, XmNchildren, &children, XmNnumChildren, &num_children, NULL, NULL);
487 ✗ while (num_children-- > 0)
488 {
489 ✗ child_widget = children[num_children];
490 ✗ if (child_widget)
491 {
492 ✗ gate_ui_motif_widget_destroy_children(child_widget, true);
493 }
494 }
495 ✗ if (destroy_parent)
496 {
497 ✗ XtUnmanageChild(parent_widget);
498 ✗ XtDestroyWidget(parent_widget);
499 }
500 ✗ }
501
502 ✗ gate_result_t gate_ui_motif_widget_get_position(Widget widget, gate_ui_point_t* pos, gate_ui_size_t* sz)
503 {
504 ✗ gate_result_t ret = GATE_RESULT_FAILED;
505 Dimension x, y, width, height;
506
507 do
508 {
509 ✗ if (!gate_ui_motif_widget_is_valid(widget))
510 {
511 ✗ ret = GATE_RESULT_INVALIDARG;
512 ✗ break;
513 }
514
515 ✗ XtVaGetValues(widget, XtNx, &x, XtNy, &y, XtNwidth, &width, XtNheight, &height, NULL, NULL);
516 ✗ if (pos)
517 {
518 ✗ pos->x = x;
519 ✗ pos->y = y;
520 }
521 ✗ if (sz)
522 {
523 ✗ sz->width = width;
524 ✗ sz->height = height;
525 }
526 ✗ ret = GATE_RESULT_OK;
527 } while (0);
528 ✗ return ret;
529 }
530
531
532
533 ✗ gate_result_t gate_ui_motif_widget_set_position(Widget widget, gate_ui_point_t const* pos, gate_ui_size_t const* sz)
534 {
535 ✗ gate_result_t ret = GATE_RESULT_FAILED;
536 Dimension a, b;
537 XtWidgetGeometry geo;
538
539 do
540 {
541 ✗ if (!gate_ui_motif_widget_is_valid(widget))
542 {
543 ✗ ret = GATE_RESULT_INVALIDARG;
544 ✗ break;
545 }
546
547 ✗ if (pos)
548 {
549 ✗ a = pos->x;
550 ✗ b = pos->y;
551 ✗ XtVaSetValues(widget, XtNx, a, XtNy, b, NULL, NULL);
552 ✗ XtMoveWidget(widget, a, b);
553 }
554 ✗ if (sz)
555 {
556 ✗ a = sz->width;
557 ✗ b = sz->height;
558 ✗ XtVaSetValues(widget, XtNwidth, a, XtNheight, b, NULL, NULL);
559 ✗ XtResizeWidget(widget, a, b, 0);
560 }
561
562 ✗ XtResizeWindow(widget);
563 ✗ ret = GATE_RESULT_OK;
564 } while (0);
565 ✗ return ret;
566 }
567
568 ✗ gate_result_t gate_ui_motif_host_dispatch_events(gate_ui_host_t* host)
569 {
570 ✗ gate_result_t ret = GATE_RESULT_OK;
571 ✗ XtAppContext ctx = (XtAppContext)GATE_UI_MOTIF_GET_HOST_APPHANDLE(host);
572 ✗ XEvent xevt = GATE_INIT_EMPTY;
573
574 ✗ while (!XtAppGetExitFlag(ctx))
575 {
576 ✗ XtAppNextEvent(ctx, &xevt);
577 ✗ XtDispatchEvent(&xevt);
578 }
579 ✗ while (XtPending())
580 {
581 ✗ XtAppNextEvent(ctx, &xevt);
582 ✗ XtDispatchEvent(&xevt);
583 }
584 ✗ return ret;
585 }
586
587 ✗ gate_result_t gate_ui_motif_host_dispatch_pending_events(gate_ui_host_t* host, gate_bool_t ignore_exit_flag)
588 {
589 ✗ gate_result_t ret = GATE_RESULT_OK;
590 ✗ XtAppContext ctx = (XtAppContext)GATE_UI_MOTIF_GET_HOST_APPHANDLE(host);
591 ✗ XEvent xevt = GATE_INIT_EMPTY;
592
593 ✗ while (XtAppPending(ctx))
594 {
595 ✗ if (!ignore_exit_flag)
596 {
597 ✗ if (XtAppGetExitFlag(ctx))
598 {
599 ✗ break;
600 }
601 }
602 ✗ XtAppNextEvent(ctx, &xevt);
603 ✗ XtDispatchEvent(&xevt);
604 }
605 ✗ return ret;
606 }
607
608 ✗ gate_result_t gate_ui_motif_ctrl_get_children(gate_ui_ctrl_t* ctrl, void** ptr_to_widgetlist, gate_size_t* ptr_to_children_count)
609 {
610 ✗ WidgetList children = NULL;
611 ✗ Cardinal num_children = 0;
612 ✗ Widget w = NULL;
613 ✗ gate_ui_motif_dispatcher_t* dispatcher = NULL;
614
615 ✗ GATE_DEBUG_ASSERT(ctrl != NULL);
616
617 ✗ dispatcher = GATE_UI_MOTIF_GET_CTRL_DISP(ctrl);
618
619 ✗ if (dispatcher && dispatcher->get_children)
620 {
621 ✗ return dispatcher->get_children(ctrl, ptr_to_widgetlist, ptr_to_children_count);
622 }
623
624 ✗ w = GATE_UI_MOTIF_GET_CTRL_CONTAINER(ctrl);
625
626 ✗ if (!gate_ui_motif_widget_is_valid(w))
627 {
628 ✗ w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
629 ✗ if (!gate_ui_motif_widget_is_valid(w))
630 {
631 ✗ return GATE_RESULT_INVALIDARG;
632 }
633 }
634 ✗ XtVaGetValues(w, XmNchildren, &children, XmNnumChildren, &num_children, NULL, NULL);
635 ✗ if (ptr_to_widgetlist)
636 {
637 ✗ *ptr_to_widgetlist = children;
638 }
639 ✗ if (ptr_to_children_count)
640 {
641 ✗ *ptr_to_children_count = (gate_size_t)num_children;
642 }
643 ✗ return GATE_RESULT_OK;
644 }
645
646 ✗ gate_result_t gate_ui_motif_ctrl_refresh(gate_ui_ctrl_t* ctrl)
647 {
648 ✗ Widget w = GATE_UI_MOTIF_GET_CTRL_CONTAINER(ctrl);
649 ✗ if (!gate_ui_motif_widget_is_valid(w))
650 {
651 ✗ w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
652 ✗ if (!gate_ui_motif_widget_is_valid(w))
653 {
654 ✗ return GATE_RESULT_INVALIDARG;
655 }
656 }
657 ✗ XmUpdateDisplay(w);
658 ✗ return GATE_RESULT_OK;
659 }
660
661 ✗ gate_result_t gate_ui_motif_host_add_native_workproc(gate_ui_host_t* host, Boolean(*worker)(XtPointer ptr), XtPointer param)
662 {
663 XtAppContext appctx;
664
665 ✗ GATE_DEBUG_ASSERT(host != NULL);
666 ✗ appctx = (XtAppContext)GATE_UI_MOTIF_GET_HOST_APPHANDLE(host);
667 ✗ if (!appctx)
668 {
669 ✗ return GATE_RESULT_INVALIDSTATE;
670 }
671 ✗ if (worker)
672 {
673 ✗ XtAppAddWorkProc(appctx, worker, param);
674 }
675 ✗ return GATE_RESULT_OK;
676 }
677
678 ✗ static Boolean host_execute_workproc(XtPointer closure)
679 {
680 ✗ gate_runnable_t* code = (gate_runnable_t*)closure;
681 ✗ if (code)
682 {
683 ✗ gate_runnable_run(code);
684 ✗ gate_object_release(code);
685 }
686 ✗ return FALSE; /* workproc completed, do not call it again */
687 }
688
689 ✗ gate_result_t gate_ui_motif_host_add_workproc(gate_ui_host_t* host, gate_runnable_t* code)
690 {
691 XtAppContext appctx;
692
693 ✗ GATE_DEBUG_ASSERT(host != NULL);
694 ✗ appctx = (XtAppContext)GATE_UI_MOTIF_GET_HOST_APPHANDLE(host);
695 ✗ if (!appctx)
696 {
697 ✗ return GATE_RESULT_INVALIDSTATE;
698 }
699 ✗ if (code)
700 {
701 ✗ gate_object_retain(code);
702 ✗ XtAppAddWorkProc(appctx, &host_execute_workproc, (XtPointer)code);
703 }
704 ✗ return GATE_RESULT_OK;
705 }
706
707
708 ✗ unsigned long gate_ui_motif_rgba2pixel(gate_ui_host_t* host, gate_color_t const* rgba)
709 {
710 ✗ Display* disp = GATE_UI_MOTIF_GET_HOST_DISPLAY(host);
711 ✗ int screen = XDefaultScreen(disp);
712 ✗ Colormap colmap = XDefaultColormap(disp, screen);
713 XColor col;
714
715 ✗ gate_mem_clear(&col, sizeof(col));
716
717 ✗ col.red = ((gate_uint16_t)rgba->r << 8);
718 ✗ col.green = ((gate_uint16_t)rgba->g << 8);
719 ✗ col.blue = ((gate_uint16_t)rgba->b << 8);
720 ✗ col.flags = DoRed | DoGreen | DoBlue;
721 ✗ XAllocColor(disp, colmap, &col);
722 ✗ return col.pixel;
723 }
724
725 ✗ gate_color_t gate_ui_motif_pixel2rgba(gate_ui_host_t* host, unsigned long pixel)
726 {
727 ✗ Display* disp = GATE_UI_MOTIF_GET_HOST_DISPLAY(host);
728 ✗ int screen = XDefaultScreen(disp);
729 ✗ Colormap colmap = XDefaultColormap(disp, screen);
730 XColor col;
731 gate_color_t ret;
732
733 ✗ col.pixel = pixel;
734 ✗ col.flags = DoRed | DoGreen | DoBlue;
735
736 ✗ XQueryColor(disp, colmap, &col);
737 ✗ ret.r = (gate_uint8_t)(col.red >> 8);
738 ✗ ret.g = (gate_uint8_t)(col.green >> 8);
739 ✗ ret.b = (gate_uint8_t)(col.blue >> 8);
740 ✗ ret.a = 255;
741 ✗ return ret;
742 }
743
744 #endif /* GATE_UI_MOTIF */
745