GCC Code Coverage Report


Directory: src/gate/
File: src/gate/ui/graphics_motif.c
Date: 2026-08-06 22:46:24
Exec Total Coverage
Lines: 275 365 75.3%
Functions: 25 44 56.8%
Branches: 62 112 55.4%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright (c) 2018-2026, 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/graphics.h"
30 #include "gate/results.h"
31
32 #if defined(GATE_UI_MOTIF)
33
34 #include "gate/debugging.h"
35 #include "gate/ui/gateui_motif.h"
36
37 945 static unsigned long XGetRgbPixel(Display* display, gate_uint8_t r, gate_uint8_t g, gate_uint8_t b)
38 {
39 945 int screen = XDefaultScreen(display);
40 945 Colormap cmap = XDefaultColormap(display, screen);
41 XColor col;
42 945 col.pixel = 0;
43 945 col.red = ((gate_uint16_t)r) << 8;
44 945 col.green = ((gate_uint16_t)g) << 8;
45 945 col.blue = ((gate_uint16_t)b) << 8;
46 945 col.flags = DoRed | DoGreen | DoBlue;
47 945 XAllocColor(display, cmap, &col);
48 945 return col.pixel;
49 }
50
51 2 gate_result_t gate_ui_graphics_create_virtual(gate_ui_graphics_t* graph, gate_ui_host_t* host, gate_uint32_t width, gate_uint32_t height)
52 {
53 2 return gate_ui_graphics_create_image(graph, host, width, height, 0);
54 }
55
56 9 gate_result_t gate_ui_graphics_create_image(gate_ui_graphics_t* graph, gate_ui_host_t* host, gate_uint32_t width, gate_uint32_t height, gate_uint32_t depth)
57 {
58 9 gate_result_t ret = GATE_RESULT_FAILED;
59
60 do
61 {
62 9 Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(host);
63 9 int const screen = XDefaultScreen(display);;
64
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2 times.
9 int const xdepth = (depth == 0) ? XDefaultDepth(display, screen) : depth;
65 9 Window const root_window = XDefaultRootWindow(display);
66 9 Pixmap const pixmap = XCreatePixmap(display, root_window, width, height, xdepth);
67 9 GC context = XCreateGC(display, root_window, 0, 0);
68 9 unsigned long pixel = XGetRgbPixel(display, 0, 0, 0);
69
70 9 XSetForeground(display, context, pixel);
71 9 XFillRectangle(display, pixmap, context, 0, 0, width, height);
72
73 9 gate_mem_clear(graph, sizeof(gate_ui_graphics_t));
74 9 graph->host = host;
75 9 graph->resources[0] = (void*)context;
76 9 graph->resources[1] = (void*)(Drawable)pixmap;
77 9 graph->width = width;
78 9 graph->height = height;
79
80 9 XSetGraphicsExposures(display, context, 0);
81 9 ret = GATE_RESULT_OK;
82 } while (0);
83 9 return ret;
84 }
85
86 4 gate_result_t gate_ui_graphics_create_image_from(gate_ui_graphics_t* graph, gate_ui_host_t* host, gate_rasterimage_t const* rasterimage)
87 {
88 gate_result_t ret;
89 do
90 {
91 4 ret = gate_ui_graphics_create_image(graph, host, rasterimage->width, rasterimage->height, 0);
92
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 GATE_BREAK_IF_FAILED(ret);
93
94 4 ret = gate_ui_graphics_draw_image(graph, rasterimage, NULL, NULL, NULL);
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (GATE_FAILED(ret))
96 {
97 gate_ui_graphics_destroy(graph);
98 break;
99 }
100
101 4 ret = GATE_RESULT_OK;
102 } while (0);
103
104 4 return ret;
105 }
106
107 4 gate_result_t gate_ui_graphics_create_ctrl(gate_ui_graphics_t* graph, gate_ui_ctrl_t* ctrl)
108 {
109 4 gate_result_t ret = GATE_RESULT_FAILED;
110 do
111 {
112 4 gate_ui_host_t* host = GATE_UI_MOTIF_GET_CTRL_HOST(ctrl);
113 4 Display* display = GATE_UI_MOTIF_GET_HOST_DISPLAY(host);
114 4 Widget w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
115 4 Window wnd = XtWindow(w);
116 4 Dimension xwidth = 0, xheight = 0;
117 4 GC context = XCreateGC(display, wnd, 0, NULL);
118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!context)
119 {
120 ret = GATE_RESULT_OUTOFRESOURCES;
121 break;
122 }
123 4 XtVaGetValues(w, XtNwidth, &xwidth, XtNheight, &xheight, NULL, NULL);
124
125 4 graph->host = host;
126 4 graph->resources[0] = (void*)context;
127 4 graph->resources[1] = (void*)(Drawable)wnd;
128 4 graph->resources[2] = (void*)wnd;
129 4 graph->width = xwidth;
130 4 graph->height = xheight;
131
132 4 XSetGraphicsExposures(display, context, 0);
133 4 ret = GATE_RESULT_OK;
134 } while (0);
135 4 return ret;
136 }
137
138 gate_result_t gate_ui_graphics_create_native(gate_ui_graphics_t* graph, gate_ui_host_t* host, void* graphics, void* param, gate_int32_t width, gate_int32_t height)
139 {
140 return GATE_RESULT_NOTIMPLEMENTED;
141 }
142
143 13 gate_result_t gate_ui_graphics_destroy(gate_ui_graphics_t* graph)
144 {
145 13 Display* display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host);
146 13 GC context = (GC)graph->resources[0];
147 13 Drawable drawable = (Drawable)graph->resources[1];
148 13 Window window = (Window)graph->resources[2];
149
150
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (display)
151 {
152
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4 times.
13 if (window == 0)
153 {
154 /* no window, expect a Pixmap surface */
155
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 if (drawable != 0)
156 {
157 6 XFreePixmap(display, (Pixmap)drawable);
158 }
159 }
160 else
161 {
162 }
163
164
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (context)
165 {
166 13 XFreeGC(display, context);
167 }
168 }
169
170 13 return GATE_RESULT_NOTIMPLEMENTED;
171 }
172
173 2 gate_int32_t gate_ui_graphics_width(gate_ui_graphics_t* graph)
174 {
175 2 return graph->width;
176 }
177
178 2 gate_int32_t gate_ui_graphics_height(gate_ui_graphics_t* graph)
179 {
180 2 return graph->height;
181 }
182
183 2 gate_result_t gate_ui_graphics_set_pixel(gate_ui_graphics_t* graph, gate_ui_point_t pos, gate_ui_color_t col)
184 {
185 2 Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host);
186 2 GC const context = (GC)graph->resources[0];
187 2 Drawable const drawable = (Drawable)graph->resources[1];
188
189 2 XSetForeground(display, context, XGetRgbPixel(display, col.r, col.g, col.b));
190 2 XDrawPoint(display, drawable, context, pos.x, pos.y);
191 2 return GATE_RESULT_OK;
192 }
193
194 2 gate_result_t gate_ui_graphics_get_pixel(gate_ui_graphics_t* graph, gate_ui_point_t pos, gate_ui_color_t* col)
195 {
196 2 return GATE_RESULT_NOTIMPLEMENTED;
197 }
198
199 2 gate_result_t gate_ui_graphics_draw(gate_ui_graphics_t* graph, gate_ui_graphics_t* srcgraph,
200 gate_ui_point_t const* dst, gate_ui_size_t const* size, gate_ui_point_t const* srcpos)
201 {
202 2 Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host);
203 2 GC const context = (GC)graph->resources[0];
204 2 Drawable const target = (Drawable)graph->resources[1];
205 2 Drawable const source = (Drawable)srcgraph->resources[1];
206 int src_x, src_y, width, height, dst_x, dst_y;
207 2 dst_x = dst->x;
208 2 dst_y = dst->y;
209 2 src_x = srcpos->x;
210 2 src_y = srcpos->y;
211 2 width = size->width;
212 2 height = size->height;
213
214 2 XCopyArea(display, source, target, context, src_x, src_y, width, height, dst_x, dst_y);
215 2 return GATE_RESULT_OK;
216 }
217
218 2 gate_result_t gate_ui_graphics_draw_ex(gate_ui_graphics_t* graph, gate_ui_graphics_t* src_graph,
219 gate_ui_position_t const* dest_rect, gate_ui_position_t const* src_rect)
220 {
221 2 Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host);
222 2 GC const context = (GC)graph->resources[0];
223 2 Drawable const target = (Drawable)graph->resources[1];
224 2 Drawable const source = (Drawable)src_graph->resources[1];
225 int src_x, src_y, width, height, dst_x, dst_y;
226 2 dst_x = dest_rect->pos.x;
227 2 dst_y = dest_rect->pos.y;
228 2 src_x = src_rect->pos.x;
229 2 src_y = src_rect->pos.y;
230 /* TODO */
231 2 width = dest_rect->size.width;
232 2 height = dest_rect->size.height;
233
234 2 XCopyArea(display, source, target, context, src_x, src_y, width, height, dst_x, dst_y);
235 2 return GATE_RESULT_OK;
236 }
237
238 7 gate_result_t gate_ui_graphics_draw_image(gate_ui_graphics_t* graph, gate_rasterimage_t const* srcimage,
239 gate_ui_point_t const* dst, gate_ui_size_t const* size, gate_ui_point_t const* srcpos)
240 {
241 7 Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host);
242 7 GC const context = (GC)graph->resources[0];
243 7 Drawable const drawable = (Drawable)graph->resources[1];
244
245 gate_color_t pixel;
246 7 gate_uint32_t pixel_cache = 0;
247 int src_x, src_y, width, height, dst_x, dst_y;
248 int x, y;
249
250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (srcpos)
251 {
252 src_x = srcpos->x;
253 src_y = srcpos->y;
254 }
255 else
256 {
257 7 src_x = 0;
258 7 src_y = 0;
259 }
260
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (size)
261 {
262 width = size->width;
263 height = size->height;
264 }
265 else
266 {
267 7 width = srcimage->width;
268 7 height = srcimage->height;
269 }
270
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
7 if (dst)
271 {
272 2 dst_x = dst->x;
273 2 dst_y = dst->y;
274 }
275 else
276 {
277 5 dst_x = 0;
278 5 dst_y = 0;
279 }
280
281
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 7 times.
119 for (y = 0; y != height; ++y)
282 {
283
2/2
✓ Branch 0 taken 1792 times.
✓ Branch 1 taken 112 times.
1904 for (x = 0; x != width; ++x)
284 {
285 1792 gate_rasterimage_get_pixel(srcimage, src_x + x, src_y + y, &pixel);
286
2/2
✓ Branch 0 taken 1303 times.
✓ Branch 1 taken 489 times.
1792 if (pixel.a > 127)
287 {
288
2/2
✓ Branch 0 taken 920 times.
✓ Branch 1 taken 383 times.
1303 if (pixel.bits != pixel_cache)
289 {
290 920 unsigned long x11_color = XGetRgbPixel(display, pixel.r, pixel.g, pixel.b);
291 920 pixel_cache = pixel.bits;
292 920 XSetForeground(display, context, x11_color);
293 }
294 1303 XDrawPoint(display, drawable, context, dst_x + x, dst_y + y);
295 }
296 }
297 }
298 7 return GATE_RESULT_OK;
299 }
300
301 4 gate_result_t gate_ui_graphics_line(gate_ui_graphics_t* graph, gate_ui_point_t from, gate_ui_point_t to, gate_ui_color_t col, gate_uint32_t linewidth)
302 {
303 4 Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host);
304 4 GC const context = (GC)graph->resources[0];
305 4 Drawable const drawable = (Drawable)graph->resources[1];
306
307 4 XSetForeground(display, context, XGetRgbPixel(display, col.r, col.g, col.b));
308 4 XDrawLine(display, drawable, context, from.x, from.y, to.x, to.y);
309 4 return GATE_RESULT_OK;
310 }
311
312 5 gate_result_t gate_ui_graphics_rect(gate_ui_graphics_t* graph, gate_ui_position_t rect, gate_ui_color_t const* colline, gate_uint32_t linewidth, gate_ui_color_t const* colfill)
313 {
314 5 Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host);
315 5 GC const context = (GC)graph->resources[0];
316 5 Drawable const drawable = (Drawable)graph->resources[1];
317 unsigned long pixel;
318
319
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 if (colfill)
320 {
321 3 pixel = XGetRgbPixel(display, colfill->r, colfill->g, colfill->b);
322 3 XSetForeground(display, context, pixel);
323 3 XFillRectangle(display, drawable, context, rect.pos.x, rect.pos.y, rect.size.width, rect.size.height);
324 }
325
326
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (colline)
327 {
328 5 pixel = XGetRgbPixel(display, colline->r, colline->g, colline->b);
329 5 XSetForeground(display, context, pixel);
330 5 XDrawRectangle(display, drawable, context, rect.pos.x, rect.pos.y, rect.size.width, rect.size.height);
331 }
332 5 return GATE_RESULT_OK;
333 }
334
335 2 gate_result_t gate_ui_graphics_polygon(gate_ui_graphics_t* graph, gate_ui_point_t const* points, gate_size_t pointcount, gate_ui_color_t const* colline, gate_uint32_t linewidth, gate_ui_color_t const* colfill)
336 {
337 2 Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host);
338 2 GC const context = (GC)graph->resources[0];
339 2 Drawable const drawable = (Drawable)graph->resources[1];
340 unsigned long pixel;
341 gate_size_t ndx;
342 XPoint xp[64];
343
344
2/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 if ((pointcount < 3) || ((colline == NULL) && (colfill == NULL)))
345 {
346 /* nothing to do */
347 return GATE_RESULT_OK;
348 }
349
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (pointcount > 64)
351 {
352 pointcount = 64;
353 }
354
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2 times.
12 for (ndx = 0; ndx != pointcount; ++ndx)
355 {
356 10 xp[ndx].x = points[ndx].x;
357 10 xp[ndx].y = points[ndx].y;
358 }
359
360
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (colfill)
361 {
362 pixel = XGetRgbPixel(display, colfill->r, colfill->g, colfill->b);
363 XSetForeground(display, context, pixel);
364 XFillPolygon(display, drawable, context, xp, (int)pointcount, Complex, CoordModeOrigin);
365 }
366
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (colline)
367 {
368 2 pixel = XGetRgbPixel(display, colline->r, colline->g, colline->b);
369 2 XSetForeground(display, context, pixel);
370
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 for (ndx = 0; ndx != pointcount - 1; ++ndx)
371 {
372 8 XDrawLine(display, drawable, context, xp[ndx].x, xp[ndx].y, xp[ndx + 1].x, xp[ndx + 1].y);
373 }
374 2 XDrawLine(display, drawable, context, xp[pointcount - 1].x, xp[pointcount - 1].y, xp[0].x, xp[0].y);
375 }
376 2 return GATE_RESULT_OK;
377 }
378
379 static gate_bool_t find_best_font_name(Display* display, gate_ui_font_t* font)
380 {
381 gate_bool_t ret = false;
382 int max_fonts = 1024;
383 int fonts_returned = 0;
384 char** fonts = XListFonts(display, "*", max_fonts, &fonts_returned);
385
386 do
387 {
388 int ndx;
389 char const* pattern = font->font_name;
390 gate_size_t pattern_len = gate_str_length(font->font_name);
391
392 if (fonts == NULL)
393 {
394 break;
395 }
396 for (ndx = 0; ndx < fonts_returned; ++ndx)
397 {
398 char* font_name = fonts[ndx];
399 gate_size_t font_name_len = gate_str_length(font_name);
400 gate_size_t pos;
401 if(font_name_len == 0)
402 {
403 continue;
404 }
405 pos = gate_str_pos(font_name, font_name_len, pattern, pattern_len, 0);
406 if(pos != GATE_STR_NPOS)
407 {
408 gate_str_print_text(font->font_name, sizeof(font->font_name), font_name, font_name_len);
409 ret = true;
410 break;
411 }
412 }
413 /* code */
414 } while (0);
415
416 if(fonts != NULL)
417 {
418 XFreeFontNames(fonts);
419 }
420
421 return ret;
422 }
423
424 2 gate_result_t gate_ui_graphics_get_char_size(gate_ui_graphics_t* graph, gate_ui_font_t const* font, gate_char32_t const* chars, gate_size_t charcount, gate_int32_t* charlens)
425 {
426 2 Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host);
427 2 GC const context = (GC)graph->resources[0];
428 2 Drawable const drawable = (Drawable)graph->resources[1];
429
430 XFontStruct* fontstruct;
431 size_t ndx;
432
433 2 fontstruct = XLoadQueryFont(display, "fixed");
434
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 for(ndx = 0; ndx < charcount; ++ndx)
435 {
436 char c[8];
437 2 gate_size_t len = gate_char_write_utf8(chars[ndx], &c[0], sizeof(c) - 1);
438 2 c[len] = 0;
439 2 charlens[ndx] = XTextWidth(fontstruct, c, (int)len);
440 }
441 2 XFreeFont(display, fontstruct);
442 2 return GATE_RESULT_OK;
443 }
444
445
446
447 static void print_font_name(char* name_buffer, gate_size_t name_capacity, gate_ui_font_t const* font)
448 {
449 gate_strbuilder_t builder;
450
451 gate_strbuilder_create_static(&builder, name_buffer, name_capacity, 0);
452 gate_strbuilder_append_cstr(&builder, "-");
453 gate_strbuilder_append_cstr(&builder, font->font_name);
454 gate_strbuilder_append_cstr(&builder, font->bold ? "-bold" : "-medium");
455 gate_strbuilder_append_cstr(&builder, font->italic ? "-i" : "-r");
456 gate_strbuilder_append_cstr(&builder, "-*-");
457 gate_strbuilder_append_int32(&builder, font->size);
458 gate_strbuilder_append_cstr(&builder, "-*");
459 }
460
461 2 gate_result_t gate_ui_graphics_get_text_size(gate_ui_graphics_t* graph, gate_ui_font_t const* font, gate_string_t const* txt, gate_int32_t* width, gate_int32_t* height)
462 {
463 2 Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host);
464 2 GC const context = (GC)graph->resources[0];
465 2 Drawable const drawable = (Drawable)graph->resources[1];
466
467 XFontStruct* fontstruct;
468
469 2 fontstruct = XLoadQueryFont(display, "fixed");
470
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (width) *width = XTextWidth(fontstruct, gate_string_ptr(txt, 0), (int)gate_string_length(txt));
471
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (height) *height = fontstruct->ascent + fontstruct->descent;
472 2 XFreeFont(display, fontstruct);
473 2 return GATE_RESULT_OK;
474 }
475
476 2 gate_result_t gate_ui_graphics_print(gate_ui_graphics_t* graph, gate_ui_font_t const* font, gate_string_t const* text, gate_ui_position_t const* pos)
477 {
478 2 Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host);
479 2 GC const context = (GC)graph->resources[0];
480 2 Drawable const drawable = (Drawable)graph->resources[1];
481 gate_ui_font_t updated_font;
482
483 XFontStruct* fontstruct;
484
485 2 fontstruct = XLoadQueryFont(display, "fixed");
486
487 2 XSetFont(display, context, fontstruct->fid);
488 2 XDrawString(display, drawable, context, pos->pos.x, pos->pos.y + fontstruct->ascent, text->str, text->length);
489
490 2 XFreeFont(display, fontstruct);
491 2 return GATE_RESULT_OK;
492 }
493
494 void* gate_ui_graphics_handle(gate_ui_graphics_t* graph)
495 {
496 return graph->resources[0];
497 }
498 1 void* gate_ui_graphics_surface(gate_ui_graphics_t* graph)
499 {
500 1 return graph->resources[1];
501 }
502
503
504
505
506 gate_result_t gate_ui_icon_create_stock(gate_ui_icon_t* icon, gate_ui_host_t* host, gate_uint32_t stock_id, gate_uint32_t flags)
507 {
508 return GATE_RESULT_NOTIMPLEMENTED;
509 }
510 gate_result_t gate_ui_icon_create_native(gate_ui_icon_t* icon, gate_ui_host_t* host, void* handle, gate_uint32_t flags)
511 {
512 return GATE_RESULT_NOTIMPLEMENTED;
513 }
514 gate_result_t gate_ui_icon_create_image(gate_ui_icon_t* icon, gate_ui_host_t* host, gate_rasterimage_t const* image)
515 {
516 return GATE_RESULT_NOTIMPLEMENTED;
517 }
518 gate_result_t gate_ui_icon_create_file(gate_ui_icon_t* icon, gate_ui_host_t* host, gate_string_t const* filepath)
519 {
520 return GATE_RESULT_NOTIMPLEMENTED;
521 }
522 gate_result_t gate_ui_icon_copy(gate_ui_icon_t* dsticon, gate_ui_icon_t const* srcicon)
523 {
524 return GATE_RESULT_NOTIMPLEMENTED;
525 }
526 gate_result_t gate_ui_icon_destroy(gate_ui_icon_t* icon)
527 {
528 return GATE_RESULT_NOTIMPLEMENTED;
529 }
530
531
532
533 /**
534 * A motif ICON list is an array of Pixmap instances.
535 * Each ICON entry is represented by two Pixmaps, the first is the mask pixmap,
536 * the second one holds the icon pixels
537 *
538 */
539
540 3 gate_result_t gate_ui_iconlist_create(gate_ui_iconlist_t* ilst, gate_ui_host_t* host, gate_int32_t width, gate_int32_t height)
541 {
542 gate_arraylist_t pixmap_list;
543
544
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATE_DEBUG_ASSERT(ilst !=NULL);
545
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATE_DEBUG_ASSERT(host != NULL);
546
547 3 gate_mem_clear(ilst, sizeof(gate_ui_iconlist_t));
548 3 ilst->host = host;
549 3 ilst->flags = 0;
550 3 ilst->width = width;
551 3 ilst->height = height;
552 3 ilst->resources[0] = NULL;
553 3 return GATE_RESULT_OK;
554 }
555
556 1 gate_result_t gate_ui_iconlist_destroy(gate_ui_iconlist_t* ilst)
557 {
558 gate_arraylist_t pixmap_list;
559
560
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(ilst != NULL);
561
562 1 pixmap_list = (gate_arraylist_t)ilst->resources[0];
563
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (pixmap_list != NULL)
564 {
565 1 Display* display = GATE_UI_MOTIF_GET_HOST_DISPLAY(ilst->host);
566 gate_size_t ndx;
567 1 gate_size_t cnt = gate_arraylist_length(pixmap_list);
568
569
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 for(ndx = 0; ndx != cnt; ++ndx)
570 {
571 2 Pixmap* ptr_pixmap = gate_arraylist_get(pixmap_list, ndx);
572
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if(ptr_pixmap != NULL)
573 {
574 2 XFreePixmap(display, (Pixmap)*ptr_pixmap);
575 }
576 }
577 1 gate_arraylist_release(pixmap_list);
578 1 ilst->resources[0] = NULL;
579 }
580 1 return GATE_RESULT_OK;
581 }
582 gate_size_t gate_ui_iconlist_count(gate_ui_iconlist_t* ilst)
583 {
584 gate_size_t ret = 0;
585 gate_arraylist_t pixmap_list;
586
587 GATE_DEBUG_ASSERT(ilst != NULL);
588
589 pixmap_list = (gate_arraylist_t)ilst->resources[0];
590 if (pixmap_list != NULL)
591 {
592 gate_size_t const cnt = gate_arraylist_length(pixmap_list);
593 ret = cnt / 2;
594 }
595 return ret;
596 }
597
598 2 static Pixmap create_mask_pixmap(gate_ui_host_t* host, gate_rasterimage_t const* image)
599 {
600 2 Display* dpy = GATE_UI_MOTIF_GET_HOST_DISPLAY(host);
601 2 Window win = XDefaultRootWindow(dpy);
602 Pixmap pm;
603 GC gc;
604 gate_color_t col;
605 unsigned int x, y, width, height;
606
607 2 width = gate_rasterimage_width(image);
608 2 height = gate_rasterimage_height(image);
609
610 2 pm = XCreatePixmap(dpy, win, image->width, image->height, 1);
611 2 gc = XCreateGC(dpy, pm, 0, NULL);
612 2 XSetForeground(dpy, gc, 0);
613 2 XFillRectangle(dpy, pm, gc, 0, 0, width, height);
614 2 XSetForeground(dpy, gc, 1);
615
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 2 times.
34 for (y = 0; y != height; ++y)
616 {
617
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 32 times.
544 for (x = 0; x != width; ++x)
618 {
619 512 gate_rasterimage_get_pixel(image, x, y, &col);
620
2/2
✓ Branch 0 taken 338 times.
✓ Branch 1 taken 174 times.
512 if (col.a > 127)
621 {
622 338 XDrawPoint(dpy, pm, gc, x, y);
623 }
624 }
625 }
626 2 XFreeGC(dpy, gc);
627 2 return pm;
628 }
629
630 gate_result_t gate_ui_iconlist_add_icon(gate_ui_iconlist_t* ilst, gate_ui_icon_t const* icon, gate_intptr_t* icon_key)
631 {
632 /* TODO */
633 return GATE_RESULT_NOTIMPLEMENTED;
634 }
635
636 2 gate_result_t gate_ui_iconlist_add_image(gate_ui_iconlist_t* ilst, gate_rasterimage_t const* image, gate_intptr_t* icon_key)
637 {
638 gate_result_t ret;
639
640
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATE_DEBUG_ASSERT(ilst != NULL);
641
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATE_DEBUG_ASSERT(image != NULL);
642
643 do
644 {
645 gate_ui_graphics_t graph;
646 Pixmap pm;
647 gate_size_t len;
648 2 gate_arraylist_t pixmap_list = ilst->resources[0];
649
650
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (pixmap_list == NULL)
651 {
652 2 pixmap_list = gate_arraylist_create(sizeof(Pixmap), NULL, 16, NULL, NULL);
653
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (NULL == pixmap_list)
654 {
655 GATE_DEBUG_TRACE("Failed to allocate pixmap array");
656 ret = GATE_RESULT_OUTOFMEMORY;
657 break;
658 }
659 2 ilst->resources[0] = (void*)pixmap_list;
660 }
661
662 2 pm = create_mask_pixmap(ilst->host, image);
663
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (NULL == gate_arraylist_add(pixmap_list, &pm))
664 {
665 ret = GATE_RESULT_OUTOFMEMORY;
666 break;
667 }
668
669 2 ret = gate_ui_graphics_create_image_from(&graph, ilst->host, image);
670
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATE_BREAK_IF_FAILED(ret);
671
672 2 pm = (Pixmap)graph.resources[1];
673 2 graph.resources[1] = 0;
674 2 gate_ui_graphics_destroy(&graph);
675
676 2 gate_arraylist_add(pixmap_list, &pm);
677 2 len = gate_arraylist_length(pixmap_list);
678
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (icon_key)
679 {
680 2 *icon_key = (gate_intptr_t)len;
681 }
682 2 ret = GATE_RESULT_OK;
683 } while (0);
684 2 return ret;
685 }
686 gate_result_t gate_ui_iconlist_get_icon(gate_ui_iconlist_t* ilst, gate_intptr_t icon_key, gate_ui_icon_t* icon)
687 {
688 /* TODO */
689 return GATE_RESULT_NOTIMPLEMENTED;
690 }
691 13 void* gate_ui_iconlist_get_handle(gate_ui_iconlist_t* ilst, gate_intptr_t icon_key)
692 {
693 13 void* ret = NULL;
694
695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 GATE_DEBUG_ASSERT(ilst != NULL);
696 do
697 {
698 gate_arraylist_t pixmap_list;
699 gate_size_t cnt;
700 13 gate_size_t ndx = (gate_size_t)icon_key;
701
702
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if(ilst->resources[0] == NULL) break;
703
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if(ndx < 2) break;
704 13 ndx -= 2; /* key == length after add, we need to go two steps back to point to the first pixmap */
705
706 13 pixmap_list = ilst->resources[0];
707 13 cnt = gate_arraylist_length(pixmap_list);
708
709 13 ret = gate_arraylist_get(pixmap_list, ndx);
710 /* ret == Pixmap* to mask pixmap */
711 } while (0);
712
713 13 return ret;
714 }
715
716
717
718
719
720 gate_result_t gate_ui_cursor_create_stock(gate_ui_cursor_t* cursor, gate_ui_host_t* host, gate_uint32_t stock_id)
721 {
722 return GATE_RESULT_NOTIMPLEMENTED;
723 }
724 gate_result_t gate_ui_cursor_create_native(gate_ui_cursor_t* cursor, gate_ui_host_t* host, void* handle, gate_uint32_t flags)
725 {
726 return GATE_RESULT_NOTIMPLEMENTED;
727 }
728 gate_result_t gate_ui_cursor_create_image(gate_ui_cursor_t* cursor, gate_ui_host_t* host, gate_rasterimage_t const* image,
729 gate_uint16_t x, gate_uint16_t y)
730 {
731 return GATE_RESULT_NOTIMPLEMENTED;
732 }
733 gate_result_t gate_ui_cursor_create_file(gate_ui_cursor_t* cursor, gate_ui_host_t* host, gate_string_t const* filepath)
734 {
735 return GATE_RESULT_NOTIMPLEMENTED;
736 }
737 gate_result_t gate_ui_cursor_copy(gate_ui_cursor_t* dstcursor, gate_ui_cursor_t const* srccursor)
738 {
739 return GATE_RESULT_NOTIMPLEMENTED;
740 }
741 gate_result_t gate_ui_cursor_destroy(gate_ui_cursor_t* cursor)
742 {
743 return GATE_RESULT_NOTIMPLEMENTED;
744 }
745
746 #endif /* GATE_UI_MOTIF */
747