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