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/graphics.h" |
30 |
|
|
#include "gate/results.h" |
31 |
|
|
|
32 |
|
|
#if defined(GATE_UI_WINAPI) |
33 |
|
|
|
34 |
|
|
#include "gate/ui/gateui_winapi.h" |
35 |
|
|
#include "gate/platforms.h" |
36 |
|
|
#include "gate/debugging.h" |
37 |
|
|
#include <shellapi.h> |
38 |
|
|
|
39 |
|
|
#if !defined(GATE_SYS_WIN16) |
40 |
|
|
#include <commctrl.h> |
41 |
|
|
#endif |
42 |
|
|
|
43 |
|
|
#define GATE_UI_GRAPHICS_HDC(graph) ((HDC)(graph)->resources[0]) |
44 |
|
|
#define GATE_UI_GRAPHICS_BACKUP(graph) ((HBITMAP)(graph)->resources[1]) |
45 |
|
|
#define GATE_UI_GRAPHICS_WINDOW(graph) ((HWND)(graph)->resources[2]) |
46 |
|
|
#define GATE_UI_GRAPHICS_BYTEBUFFER(graph) ((void*)(graph)->resources[3]) |
47 |
|
|
|
48 |
|
|
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) |
49 |
|
|
{ |
50 |
|
|
HWND desk = GetDesktopWindow(); |
51 |
|
|
HDC deskdc = GetDC(desk); |
52 |
|
|
HDC dc; |
53 |
|
|
HBITMAP bmp; |
54 |
|
|
gate_mem_clear(graph, sizeof(gate_ui_graphics_t)); |
55 |
|
|
dc = CreateCompatibleDC(deskdc); |
56 |
|
|
if (dc == NULL) |
57 |
|
|
{ |
58 |
|
|
ReleaseDC(desk, deskdc); |
59 |
|
|
return GATE_RESULT_FAILED; |
60 |
|
|
} |
61 |
|
|
bmp = CreateCompatibleBitmap(deskdc, (int)width, (int)height); |
62 |
|
|
ReleaseDC(desk, deskdc); |
63 |
|
|
if (bmp == NULL) |
64 |
|
|
{ |
65 |
|
|
DeleteDC(dc); |
66 |
|
|
return GATE_RESULT_OUTOFRESOURCES; |
67 |
|
|
} |
68 |
|
|
graph->host = host; |
69 |
|
|
graph->width = width; |
70 |
|
|
graph->height = height; |
71 |
|
|
graph->resources[0] = dc; |
72 |
|
|
graph->resources[1] = SelectObject(dc, (HGDIOBJ)bmp); |
73 |
|
|
return GATE_RESULT_OK; |
74 |
|
|
} |
75 |
|
|
|
76 |
|
|
typedef struct gate_ui_bitmap_header_class |
77 |
|
|
{ |
78 |
|
|
BITMAPINFO info; |
79 |
|
|
RGBQUAD palette[256]; |
80 |
|
|
} gate_ui_bitmap_header_t; |
81 |
|
|
|
82 |
|
|
static gate_size_t resolve_color_index(gate_uint8_t r, gate_uint8_t g, gate_uint8_t b) |
83 |
|
|
{ |
84 |
|
|
const gate_size_t nr = ((gate_size_t)r + 26u) / 51u; |
85 |
|
|
const gate_size_t ng = ((gate_size_t)g + 26u) / 51u; |
86 |
|
|
const gate_size_t nb = ((gate_size_t)b + 26u) / 51u; |
87 |
|
|
|
88 |
|
|
const gate_size_t ndx = nr * 36u + ng * 6u + nb; |
89 |
|
|
return ndx; |
90 |
|
|
} |
91 |
|
|
|
92 |
|
|
static DWORD create_palette_8(RGBQUAD* ptr_quad) |
93 |
|
|
{ |
94 |
|
|
unsigned short r, g, b; |
95 |
|
|
for (r = 0; r < 6; ++r) |
96 |
|
|
{ |
97 |
|
|
for (g = 0; g < 6; ++g) |
98 |
|
|
{ |
99 |
|
|
for (b = 0; b < 6; ++b) |
100 |
|
|
{ |
101 |
|
|
ptr_quad->rgbBlue = (unsigned char)(b * 51); |
102 |
|
|
ptr_quad->rgbGreen = (unsigned char)(g * 51); |
103 |
|
|
ptr_quad->rgbRed = (unsigned char)(r * 51); |
104 |
|
|
ptr_quad->rgbReserved = 0; |
105 |
|
|
++ptr_quad; |
106 |
|
|
} |
107 |
|
|
} |
108 |
|
|
} |
109 |
|
|
return 216; |
110 |
|
|
} |
111 |
|
|
|
112 |
|
|
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) |
113 |
|
|
{ |
114 |
|
|
gate_result_t ret; |
115 |
|
|
HWND desk = GetDesktopWindow(); |
116 |
|
|
HDC deskdc = GetDC(desk); |
117 |
|
|
HDC dc = NULL; |
118 |
|
|
HBITMAP hbitmap; |
119 |
|
|
HBITMAP hbackup; |
120 |
|
|
gate_ui_bitmap_header_t bitmapinfo; |
121 |
|
|
gate_uint8_t r; |
122 |
|
|
gate_size_t linelen; |
123 |
|
|
gate_size_t bufferlen; |
124 |
|
|
void* buffer; |
125 |
|
|
RGBQUAD* ptr_quad; |
126 |
|
|
|
127 |
|
|
do |
128 |
|
|
{ |
129 |
|
|
gate_mem_clear(graph, sizeof(gate_ui_graphics_t)); |
130 |
|
|
|
131 |
|
|
if (deskdc == NULL) |
132 |
|
|
{ |
133 |
|
|
ret = GATE_RESULT_OUTOFRESOURCES; |
134 |
|
|
break; |
135 |
|
|
} |
136 |
|
|
dc = CreateCompatibleDC(deskdc); |
137 |
|
|
if (dc == NULL) |
138 |
|
|
{ |
139 |
|
|
ret = GATE_RESULT_OUTOFRESOURCES; |
140 |
|
|
break; |
141 |
|
|
} |
142 |
|
|
|
143 |
|
|
|
144 |
|
|
bitmapinfo.info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
145 |
|
|
bitmapinfo.info.bmiHeader.biWidth = width; |
146 |
|
|
bitmapinfo.info.bmiHeader.biHeight = height; |
147 |
|
|
bitmapinfo.info.bmiHeader.biPlanes = 1; |
148 |
|
|
bitmapinfo.info.bmiHeader.biBitCount = depth; |
149 |
|
|
bitmapinfo.info.bmiHeader.biCompression = BI_RGB; |
150 |
|
|
bitmapinfo.info.bmiHeader.biSizeImage = 0; |
151 |
|
|
bitmapinfo.info.bmiHeader.biXPelsPerMeter = 0; |
152 |
|
|
bitmapinfo.info.bmiHeader.biYPelsPerMeter = 0; |
153 |
|
|
bitmapinfo.info.bmiHeader.biClrImportant = 0; |
154 |
|
|
|
155 |
|
|
if (depth == 1) |
156 |
|
|
{ |
157 |
|
|
bitmapinfo.info.bmiHeader.biClrUsed = 2; |
158 |
|
|
|
159 |
|
|
/* black */ |
160 |
|
|
bitmapinfo.info.bmiColors[0].rgbBlue = 0; |
161 |
|
|
bitmapinfo.info.bmiColors[0].rgbGreen = 0; |
162 |
|
|
bitmapinfo.info.bmiColors[0].rgbRed = 0; |
163 |
|
|
bitmapinfo.info.bmiColors[0].rgbReserved = 0; |
164 |
|
|
|
165 |
|
|
/* white */ |
166 |
|
|
bitmapinfo.info.bmiColors[1].rgbBlue = 255; |
167 |
|
|
bitmapinfo.info.bmiColors[1].rgbGreen = 255; |
168 |
|
|
bitmapinfo.info.bmiColors[1].rgbRed = 255; |
169 |
|
|
bitmapinfo.info.bmiColors[1].rgbReserved = 0; |
170 |
|
|
} |
171 |
|
|
else if (depth < 8) |
172 |
|
|
{ |
173 |
|
|
static gate_color_rgb_t vga_pal[16]; |
174 |
|
|
static gate_bool_t vga_pal_init = false; |
175 |
|
|
if (!vga_pal_init) |
176 |
|
|
{ |
177 |
|
|
gate_color_palette_rgb4_create(vga_pal); |
178 |
|
|
vga_pal_init = true; |
179 |
|
|
} |
180 |
|
|
|
181 |
|
|
bitmapinfo.info.bmiHeader.biClrUsed = 16; |
182 |
|
|
ptr_quad = &bitmapinfo.info.bmiColors[0]; |
183 |
|
|
for (r = 0; r < 16; ++r) |
184 |
|
|
{ |
185 |
|
|
ptr_quad->rgbBlue = vga_pal[r].b; |
186 |
|
|
ptr_quad->rgbGreen = vga_pal[r].g; |
187 |
|
|
ptr_quad->rgbRed = vga_pal[r].r; |
188 |
|
|
ptr_quad->rgbReserved = 0; |
189 |
|
|
++ptr_quad; |
190 |
|
|
} |
191 |
|
|
} |
192 |
|
|
else if (depth < 16) |
193 |
|
|
{ |
194 |
|
|
ptr_quad = &bitmapinfo.info.bmiColors[0]; |
195 |
|
|
bitmapinfo.info.bmiHeader.biClrUsed = create_palette_8(ptr_quad); |
196 |
|
|
} |
197 |
|
|
else |
198 |
|
|
{ |
199 |
|
|
bitmapinfo.info.bmiHeader.biClrUsed = 0; |
200 |
|
|
} |
201 |
|
|
|
202 |
|
|
linelen = (bitmapinfo.info.bmiHeader.biWidth * bitmapinfo.info.bmiHeader.biBitCount + 7) / 8; |
203 |
|
|
if (linelen % 4 != 0) |
204 |
|
|
{ |
205 |
|
|
linelen += (4 - (linelen % 4)); |
206 |
|
|
} |
207 |
|
|
bufferlen = linelen * bitmapinfo.info.bmiHeader.biHeight; |
208 |
|
|
#if defined(GATE_SYS_WIN16) |
209 |
|
|
buffer = gate_mem_alloc(bufferlen); |
210 |
|
|
gate_mem_clear(buffer, bufferlen); |
211 |
|
|
hbitmap = CreateDIBitmap(deskdc, &bitmapinfo.info.bmiHeader, CBM_INIT, buffer, &bitmapinfo.info, DIB_RGB_COLORS); |
212 |
|
|
#else |
213 |
|
|
buffer = NULL; |
214 |
|
|
hbitmap = CreateDIBSection(deskdc, &bitmapinfo.info, DIB_RGB_COLORS, &buffer, NULL, 0); |
215 |
|
|
#endif |
216 |
|
|
if (hbitmap == NULL) |
217 |
|
|
{ |
218 |
|
|
ret = GATE_RESULT_FAILED; |
219 |
|
|
break; |
220 |
|
|
} |
221 |
|
|
hbackup = SelectObject(dc, hbitmap); |
222 |
|
|
|
223 |
|
|
graph->width = width; |
224 |
|
|
graph->height = height; |
225 |
|
|
graph->host = host; |
226 |
|
|
graph->resources[0] = dc; |
227 |
|
|
graph->resources[1] = hbackup; |
228 |
|
|
graph->resources[2] = NULL; |
229 |
|
|
graph->resources[3] = buffer; |
230 |
|
|
ret = GATE_RESULT_OK; |
231 |
|
|
|
232 |
|
|
} while (0); |
233 |
|
|
|
234 |
|
|
if (deskdc != NULL) |
235 |
|
|
{ |
236 |
|
|
ReleaseDC(desk, deskdc); |
237 |
|
|
} |
238 |
|
|
|
239 |
|
|
return ret; |
240 |
|
|
} |
241 |
|
|
|
242 |
|
|
gate_result_t gate_ui_graphics_create_image_from(gate_ui_graphics_t* graph, gate_ui_host_t* host, gate_rasterimage_t const* rasterimage) |
243 |
|
|
{ |
244 |
|
|
gate_color_t const* ptrpixels; |
245 |
|
|
gate_uint8_t* ptrbytes; |
246 |
|
|
gate_uint32_t x, y; |
247 |
|
|
gate_result_t ret; |
248 |
|
|
#if defined(GATE_WIN32_ANSI) |
249 |
|
|
unsigned line_patch = 0; |
250 |
|
|
gate_uint16_t col16; |
251 |
|
|
|
252 |
|
|
# if 0 |
253 |
|
|
/* use 8-bit DIB */ |
254 |
|
|
ret = gate_ui_graphics_create_image(graph, host, rasterimage->width, rasterimage->height, 8); |
255 |
|
|
if (GATE_SUCCEEDED(ret)) |
256 |
|
|
{ |
257 |
|
|
ptrbytes = (gate_uint8_t*)GATE_UI_GRAPHICS_BYTEBUFFER(graph); |
258 |
|
|
line_patch = (unsigned)(rasterimage->width % 4); |
259 |
|
|
if (line_patch != 0) |
260 |
|
|
{ |
261 |
|
|
line_patch = 4 - line_patch; |
262 |
|
|
} |
263 |
|
|
for (y = 0; y != rasterimage->height; ++y) |
264 |
|
|
{ |
265 |
|
|
ptrpixels = (gate_color_t const*)gate_rasterimage_get_line_ptr(rasterimage, (rasterimage->height - 1 - y)); |
266 |
|
|
for (x = 0; x != rasterimage->width; ++x) |
267 |
|
|
{ |
268 |
|
|
col16 = (((gate_uint16_t)ptrpixels->r + 25) / 51) * 36; |
269 |
|
|
col16 += (((gate_uint16_t)ptrpixels->g + 25) / 51) * 6; |
270 |
|
|
col16 += (((gate_uint16_t)ptrpixels->b + 25) / 51); |
271 |
|
|
|
272 |
|
|
*(ptrbytes++) = (gate_uint8_t)(col16 & 0xff); |
273 |
|
|
++ptrpixels; |
274 |
|
|
} |
275 |
|
|
ptrbytes += line_patch; |
276 |
|
|
} |
277 |
|
|
} |
278 |
|
|
# else |
279 |
|
|
/* use 16-bit DIB */ |
280 |
|
|
ret = gate_ui_graphics_create_image(graph, host, rasterimage->width, rasterimage->height, 16); |
281 |
|
|
if (GATE_SUCCEEDED(ret)) |
282 |
|
|
{ |
283 |
|
|
ptrbytes = (gate_uint8_t*)GATE_UI_GRAPHICS_BYTEBUFFER(graph); |
284 |
|
|
line_patch = (unsigned)(rasterimage->width % 2) * 2; |
285 |
|
|
for (y = 0; y != rasterimage->height; ++y) |
286 |
|
|
{ |
287 |
|
|
ptrpixels = (gate_color_t const*)gate_rasterimage_get_line_ptr(rasterimage, (rasterimage->height - 1 - y)); |
288 |
|
|
for (x = 0; x != rasterimage->width; ++x) |
289 |
|
|
{ |
290 |
|
|
col16 = ((gate_uint16_t)(ptrpixels->b & 0xF8) >> 3) |
291 |
|
|
| ((gate_uint16_t)(ptrpixels->g & 0xF8) << 2) |
292 |
|
|
| ((gate_uint16_t)(ptrpixels->r & 0xF8) << 7); |
293 |
|
|
|
294 |
|
|
*(ptrbytes++) = (gate_uint8_t)(col16 & 0xff); |
295 |
|
|
*(ptrbytes++) = (gate_uint8_t)(col16 >> 8); |
296 |
|
|
++ptrpixels; |
297 |
|
|
} |
298 |
|
|
ptrbytes += line_patch; |
299 |
|
|
} |
300 |
|
|
} |
301 |
|
|
# endif |
302 |
|
|
|
303 |
|
|
#else |
304 |
|
|
ret = gate_ui_graphics_create_image(graph, host, rasterimage->width, rasterimage->height, 32); |
305 |
|
|
if (GATE_SUCCEEDED(ret)) |
306 |
|
|
{ |
307 |
|
|
ptrbytes = (gate_uint8_t*)GATE_UI_GRAPHICS_BYTEBUFFER(graph); |
308 |
|
|
for (y = 0; y != rasterimage->height; ++y) |
309 |
|
|
{ |
310 |
|
|
ptrpixels = (gate_color_t const*)gate_rasterimage_get_line_ptr(rasterimage, (rasterimage->height - 1 - y)); |
311 |
|
|
for (x = 0; x != rasterimage->width; ++x) |
312 |
|
|
{ |
313 |
|
|
*(ptrbytes++) = ptrpixels->b; |
314 |
|
|
*(ptrbytes++) = ptrpixels->g; |
315 |
|
|
*(ptrbytes++) = ptrpixels->r; |
316 |
|
|
*(ptrbytes++) = ptrpixels->a; |
317 |
|
|
++ptrpixels; |
318 |
|
|
} |
319 |
|
|
} |
320 |
|
|
} |
321 |
|
|
#endif |
322 |
|
|
return ret; |
323 |
|
|
} |
324 |
|
|
|
325 |
|
|
|
326 |
|
|
gate_result_t gate_ui_graphics_create_ctrl(gate_ui_graphics_t* graph, gate_ui_ctrl_t* ctrl) |
327 |
|
|
{ |
328 |
|
|
HWND hwnd = (HWND)GATE_UI_WINAPI_GET_HWND(ctrl); |
329 |
|
|
RECT rect; |
330 |
|
|
|
331 |
|
|
gate_mem_clear(graph, sizeof(gate_ui_graphics_t)); |
332 |
|
|
|
333 |
|
|
GetClientRect(hwnd, &rect); |
334 |
|
|
|
335 |
|
|
graph->host = GATE_UI_WINAPI_GET_HOST(ctrl); |
336 |
|
|
graph->width = rect.right - rect.left; |
337 |
|
|
graph->height = rect.bottom - rect.top; |
338 |
|
|
graph->resources[0] = GetDC(hwnd); |
339 |
|
|
graph->resources[2] = hwnd; |
340 |
|
|
return GATE_RESULT_OK; |
341 |
|
|
} |
342 |
|
|
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) |
343 |
|
|
{ |
344 |
|
|
GATE_UNUSED_ARG(param); |
345 |
|
|
gate_mem_clear(graph, sizeof(gate_ui_graphics_t)); |
346 |
|
|
graph->host = host; |
347 |
|
|
graph->resources[0] = graphics; |
348 |
|
|
graph->resources[3] = (void*)(gate_intptr_t)(-1); ///< no-release flag |
349 |
|
|
graph->width = width; |
350 |
|
|
graph->height = height; |
351 |
|
|
return GATE_RESULT_OK; |
352 |
|
|
} |
353 |
|
|
gate_result_t gate_ui_graphics_destroy(gate_ui_graphics_t* graph) |
354 |
|
|
{ |
355 |
|
|
gate_bool_t success = true; |
356 |
|
|
HDC hdc = GATE_UI_GRAPHICS_HDC(graph); |
357 |
|
|
HBITMAP hbmp = GATE_UI_GRAPHICS_BACKUP(graph); |
358 |
|
|
HWND hwnd = GATE_UI_GRAPHICS_WINDOW(graph); |
359 |
|
|
void* buffer_ptr = GATE_UI_GRAPHICS_BYTEBUFFER(graph); |
360 |
|
|
|
361 |
|
|
if (-1 == (gate_intptr_t)buffer_ptr) |
362 |
|
|
{ |
363 |
|
|
// no-release flag is active |
364 |
|
|
} |
365 |
|
|
else |
366 |
|
|
{ |
367 |
|
|
if (hbmp != NULL) |
368 |
|
|
{ |
369 |
|
|
success &= (FALSE != DeleteObject(SelectObject(hdc, (HGDIOBJ)hbmp))); |
370 |
|
|
} |
371 |
|
|
|
372 |
|
|
if (hwnd != NULL) |
373 |
|
|
{ |
374 |
|
|
success &= (0 != ReleaseDC(hwnd, hdc)); |
375 |
|
|
} |
376 |
|
|
else |
377 |
|
|
{ |
378 |
|
|
success &= (FALSE != DeleteDC(hdc)); |
379 |
|
|
} |
380 |
|
|
|
381 |
|
|
if (buffer_ptr != NULL) |
382 |
|
|
{ |
383 |
|
|
#if defined(GATE_SYS_WIN16) |
384 |
|
|
gate_mem_dealloc(buffer_ptr); |
385 |
|
|
#else |
386 |
|
|
/* win32 dib section will release the buffer bits automatically */ |
387 |
|
|
#endif |
388 |
|
|
} |
389 |
|
|
|
390 |
|
|
} |
391 |
|
|
|
392 |
|
|
return success ? GATE_RESULT_OK : GATE_RESULT_FAILED; |
393 |
|
|
} |
394 |
|
|
|
395 |
|
|
gate_int32_t gate_ui_graphics_width(gate_ui_graphics_t* graph) |
396 |
|
|
{ |
397 |
|
|
return (graph != NULL) ? graph->width : 0; |
398 |
|
|
} |
399 |
|
|
gate_int32_t gate_ui_graphics_height(gate_ui_graphics_t* graph) |
400 |
|
|
{ |
401 |
|
|
return (graph != NULL) ? graph->height : 0; |
402 |
|
|
} |
403 |
|
|
|
404 |
|
|
#ifndef CLR_INVALID |
405 |
|
|
#define CLR_INVALID 0xffffffff |
406 |
|
|
#endif |
407 |
|
|
|
408 |
|
|
gate_result_t gate_ui_graphics_set_pixel(gate_ui_graphics_t* graph, gate_ui_point_t pos, gate_ui_color_t col) |
409 |
|
|
{ |
410 |
|
|
HDC hdc = GATE_UI_GRAPHICS_HDC(graph); |
411 |
|
|
COLORREF colref = RGB(col.r, col.g, col.b); |
412 |
|
|
COLORREF result = SetPixel(hdc, (int)pos.x, (int)pos.y, colref); |
413 |
|
|
if (result == CLR_INVALID) |
414 |
|
|
{ |
415 |
|
|
return GATE_RESULT_FAILED; |
416 |
|
|
} |
417 |
|
|
else |
418 |
|
|
{ |
419 |
|
|
return GATE_RESULT_OK; |
420 |
|
|
} |
421 |
|
|
} |
422 |
|
|
gate_result_t gate_ui_graphics_get_pixel(gate_ui_graphics_t* graph, gate_ui_point_t pos, gate_ui_color_t* col) |
423 |
|
|
{ |
424 |
|
|
HDC hdc = GATE_UI_GRAPHICS_HDC(graph); |
425 |
|
|
COLORREF colref = GetPixel(hdc, (int)pos.x, (int)pos.y); |
426 |
|
|
if (colref == CLR_INVALID) |
427 |
|
|
{ |
428 |
|
|
return GATE_RESULT_FAILED; |
429 |
|
|
} |
430 |
|
|
else |
431 |
|
|
{ |
432 |
|
|
col->r = GetRValue(colref); |
433 |
|
|
col->g = GetGValue(colref); |
434 |
|
|
col->b = GetBValue(colref); |
435 |
|
|
col->a = 255; |
436 |
|
|
return GATE_RESULT_OK; |
437 |
|
|
} |
438 |
|
|
} |
439 |
|
|
gate_result_t gate_ui_graphics_draw(gate_ui_graphics_t* graph, gate_ui_graphics_t* srcgraph, |
440 |
|
|
gate_ui_point_t const* dst, gate_ui_size_t const* size, gate_ui_point_t const* srcpos) |
441 |
|
|
{ |
442 |
|
|
HDC hdc_dst = GATE_UI_GRAPHICS_HDC(graph); |
443 |
|
|
HDC hdc_src = GATE_UI_GRAPHICS_HDC(srcgraph); |
444 |
|
|
int dst_x = dst ? dst->x : 0; |
445 |
|
|
int dst_y = dst ? dst->y : 0; |
446 |
|
|
int width = size ? size->width : -1; |
447 |
|
|
int height = size ? size->height : -1; |
448 |
|
|
int src_x = srcpos ? srcpos->x : 0; |
449 |
|
|
int src_y = srcpos ? srcpos->y : 0; |
450 |
|
|
|
451 |
|
|
if (width < 0) |
452 |
|
|
{ |
453 |
|
|
width += gate_ui_graphics_width(srcgraph) + 1; |
454 |
|
|
} |
455 |
|
|
if (height < 0) |
456 |
|
|
{ |
457 |
|
|
height += gate_ui_graphics_height(srcgraph) + 1; |
458 |
|
|
} |
459 |
|
|
|
460 |
|
|
if (FALSE == BitBlt(hdc_dst, dst_x, dst_y, width, height, hdc_src, src_x, src_y, SRCCOPY)) |
461 |
|
|
{ |
462 |
|
|
return GATE_RESULT_FAILED; |
463 |
|
|
} |
464 |
|
|
else |
465 |
|
|
{ |
466 |
|
|
return GATE_RESULT_OK; |
467 |
|
|
} |
468 |
|
|
} |
469 |
|
|
|
470 |
|
|
gate_result_t gate_ui_graphics_draw_ex(gate_ui_graphics_t* graph, gate_ui_graphics_t* src_graph, |
471 |
|
|
gate_ui_position_t const* dest_rect, gate_ui_position_t const* src_rect) |
472 |
|
|
{ |
473 |
|
|
HDC hdc_dst = GATE_UI_GRAPHICS_HDC(graph); |
474 |
|
|
HDC hdc_src = GATE_UI_GRAPHICS_HDC(src_graph); |
475 |
|
|
int dst_x = dest_rect ? dest_rect->pos.x : 0; |
476 |
|
|
int dst_y = dest_rect ? dest_rect->pos.y : 0; |
477 |
|
|
int dst_width = dest_rect ? dest_rect->size.width : -1; |
478 |
|
|
int dst_height = dest_rect ? dest_rect->size.height : -1; |
479 |
|
|
int src_x = src_rect ? src_rect->pos.x : 0; |
480 |
|
|
int src_y = src_rect ? src_rect->pos.y : 0; |
481 |
|
|
int src_width = src_rect ? src_rect->size.width : -1; |
482 |
|
|
int src_height = src_rect ? src_rect->size.height : -1; |
483 |
|
|
|
484 |
|
|
if (dst_width < 0) |
485 |
|
|
{ |
486 |
|
|
dst_width += gate_ui_graphics_width(graph) + 1; |
487 |
|
|
} |
488 |
|
|
if (dst_height < 0) |
489 |
|
|
{ |
490 |
|
|
dst_height += gate_ui_graphics_height(graph) + 1; |
491 |
|
|
} |
492 |
|
|
|
493 |
|
|
if (src_width < 0) |
494 |
|
|
{ |
495 |
|
|
src_width += gate_ui_graphics_width(src_graph) + 1; |
496 |
|
|
} |
497 |
|
|
if (src_height < 0) |
498 |
|
|
{ |
499 |
|
|
src_height += gate_ui_graphics_height(src_graph) + 1; |
500 |
|
|
} |
501 |
|
|
#if defined(COLORONCOLOR) && !defined(__MINGW32CE__) |
502 |
|
|
SetStretchBltMode(hdc_dst, COLORONCOLOR); |
503 |
|
|
#endif |
504 |
|
|
|
505 |
|
|
if (FALSE == StretchBlt(hdc_dst, dst_x, dst_y, dst_width, dst_height, hdc_src, |
506 |
|
|
src_x, src_y, src_width, src_height, SRCCOPY)) |
507 |
|
|
{ |
508 |
|
|
return GATE_RESULT_FAILED; |
509 |
|
|
} |
510 |
|
|
else |
511 |
|
|
{ |
512 |
|
|
return GATE_RESULT_OK; |
513 |
|
|
} |
514 |
|
|
} |
515 |
|
|
|
516 |
|
|
gate_result_t gate_ui_graphics_draw_image(gate_ui_graphics_t* graph, gate_rasterimage_t const* srcimage, |
517 |
|
|
gate_ui_point_t const* dst, gate_ui_size_t const* size, gate_ui_point_t const* srcpos) |
518 |
|
|
{ |
519 |
|
|
gate_ui_graphics_t src_graph; |
520 |
|
|
gate_result_t ret = gate_ui_graphics_create_image_from(&src_graph, graph->host, srcimage); |
521 |
|
|
if (GATE_SUCCEEDED(ret)) |
522 |
|
|
{ |
523 |
|
|
ret = gate_ui_graphics_draw(graph, &src_graph, dst, size, srcpos); |
524 |
|
|
gate_ui_graphics_destroy(&src_graph); |
525 |
|
|
} |
526 |
|
|
return ret; |
527 |
|
|
} |
528 |
|
|
|
529 |
|
|
|
530 |
|
|
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) |
531 |
|
|
{ |
532 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
533 |
|
|
HDC hdc = GATE_UI_GRAPHICS_HDC(graph); |
534 |
|
|
COLORREF colref = RGB(col.r, col.g, col.b); |
535 |
|
|
HPEN hpen = CreatePen(PS_SOLID, linewidth, colref); |
536 |
|
|
HGDIOBJ hselpen = SelectObject(hdc, (HGDIOBJ)hpen); |
537 |
|
|
if (MoveToEx(hdc, (int)from.x, (int)from.y, NULL)) |
538 |
|
|
{ |
539 |
|
|
if (LineTo(hdc, (int)to.x, (int)to.y)) |
540 |
|
|
{ |
541 |
|
|
SetPixel(hdc, (int)to.x, (int)to.y, colref); |
542 |
|
|
ret = GATE_RESULT_OK; |
543 |
|
|
} |
544 |
|
|
} |
545 |
|
|
DeleteObject(SelectObject(hdc, hselpen)); |
546 |
|
|
return ret; |
547 |
|
|
} |
548 |
|
|
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) |
549 |
|
|
{ |
550 |
|
|
gate_result_t success = true; |
551 |
|
|
HDC hdc = GATE_UI_GRAPHICS_HDC(graph); |
552 |
|
|
RECT r; |
553 |
|
|
HGDIOBJ hbackup; |
554 |
|
|
HBRUSH hbrush; |
555 |
|
|
HPEN hpen; |
556 |
|
|
COLORREF colref; |
557 |
|
|
|
558 |
|
|
if (colfill != NULL) |
559 |
|
|
{ |
560 |
|
|
colref = RGB(colfill->r, colfill->g, colfill->b); |
561 |
|
|
hbrush = CreateSolidBrush(colref); |
562 |
|
|
r.left = rect.pos.x; |
563 |
|
|
r.top = rect.pos.y; |
564 |
|
|
r.right = rect.pos.x + rect.size.width + 1; |
565 |
|
|
r.bottom = rect.pos.y + rect.size.height + 1; |
566 |
|
|
success &= (0 != FillRect(hdc, &r, hbrush)); |
567 |
|
|
DeleteObject(hbrush); |
568 |
|
|
} |
569 |
|
|
if (colline != NULL) |
570 |
|
|
{ |
571 |
|
|
colref = RGB(colline->r, colline->g, colline->b); |
572 |
|
|
hpen = CreatePen(PS_SOLID, (int)linewidth, colref); |
573 |
|
|
hbackup = SelectObject(hdc, hpen); |
574 |
|
|
success &= (FALSE != MoveToEx(hdc, rect.pos.x, rect.pos.y, NULL)); |
575 |
|
|
success &= (FALSE != LineTo(hdc, rect.pos.x + rect.size.width, rect.pos.y)); |
576 |
|
|
success &= (FALSE != LineTo(hdc, rect.pos.x + rect.size.width, rect.pos.y + rect.size.height)); |
577 |
|
|
success &= (FALSE != LineTo(hdc, rect.pos.x, rect.pos.y + rect.size.height)); |
578 |
|
|
success &= (FALSE != LineTo(hdc, rect.pos.x, rect.pos.y)); |
579 |
|
|
DeleteObject(SelectObject(hdc, hbackup)); |
580 |
|
|
} |
581 |
|
|
return success ? GATE_RESULT_OK : GATE_RESULT_FAILED; |
582 |
|
|
} |
583 |
|
|
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) |
584 |
|
|
{ |
585 |
|
|
gate_result_t success = true; |
586 |
|
|
HDC hdc = GATE_UI_GRAPHICS_HDC(graph); |
587 |
|
|
HGDIOBJ hbackup; |
588 |
|
|
HGDIOBJ hbackup2; |
589 |
|
|
HPEN hpen; |
590 |
|
|
HBRUSH hbrush; |
591 |
|
|
COLORREF colref; |
592 |
|
|
gate_size_t ndx; |
593 |
|
|
POINT pnts[1024]; |
594 |
|
|
|
595 |
|
|
if (colfill != NULL) |
596 |
|
|
{ |
597 |
|
|
colref = RGB(colfill->r, colfill->g, colfill->b); |
598 |
|
|
if (pointcount > sizeof(pnts) / sizeof(pnts[0])) |
599 |
|
|
{ |
600 |
|
|
pointcount = sizeof(pnts) / sizeof(pnts[0]); |
601 |
|
|
} |
602 |
|
|
for (ndx = 0; ndx < pointcount; ++ndx) |
603 |
|
|
{ |
604 |
|
|
pnts[ndx].x = (int)points[ndx].x; |
605 |
|
|
pnts[ndx].y = (int)points[ndx].y; |
606 |
|
|
} |
607 |
|
|
hpen = CreatePen(PS_NULL, 0, 0); |
608 |
|
|
hbackup = SelectObject(hdc, (HGDIOBJ)hpen); |
609 |
|
|
hbrush = CreateSolidBrush(colref); |
610 |
|
|
hbackup2 = SelectObject(hdc, (HGDIOBJ)hbrush); |
611 |
|
|
|
612 |
|
|
success &= (FALSE != Polygon(hdc, pnts, (int)pointcount)); |
613 |
|
|
|
614 |
|
|
DeleteObject(SelectObject(hdc, hbackup2)); |
615 |
|
|
DeleteObject(SelectObject(hdc, hbackup)); |
616 |
|
|
} |
617 |
|
|
|
618 |
|
|
if (colline != NULL) |
619 |
|
|
{ |
620 |
|
|
colref = RGB(colline->r, colline->g, colline->b); |
621 |
|
|
hpen = CreatePen(PS_SOLID, linewidth, colref); |
622 |
|
|
hbackup = SelectObject(hdc, (HGDIOBJ)hpen); |
623 |
|
|
success &= (FALSE != MoveToEx(hdc, (int)points[0].x, (int)points[0].y, NULL)); |
624 |
|
|
for (ndx = 1; ndx != pointcount; ++ndx) |
625 |
|
|
{ |
626 |
|
|
success &= (FALSE != LineTo(hdc, (int)points[ndx].x, (int)points[ndx].y)); |
627 |
|
|
} |
628 |
|
|
success &= (FALSE != LineTo(hdc, (int)points[0].x, (int)points[0].y)); |
629 |
|
|
DeleteObject(SelectObject(hdc, hbackup)); |
630 |
|
|
} |
631 |
|
|
return success ? GATE_RESULT_OK : GATE_RESULT_FAILED; |
632 |
|
|
} |
633 |
|
|
|
634 |
|
|
#if defined(GATE_SYS_WIN16) |
635 |
|
|
|
636 |
|
|
static BOOL GetTextExtentExPoint(HDC hdc, LPCSTR lpszString, int cchString, int nMaxExtent, LPINT lpnFit, LPINT lpnDx, LPSIZE lpSize) |
637 |
|
|
{ |
638 |
|
|
SIZE sz; |
639 |
|
|
SIZE szchr; |
640 |
|
|
GATE_UNUSED_ARG(nMaxExtent); |
641 |
|
|
GATE_UNUSED_ARG(lpnFit); |
642 |
|
|
sz.cx = 0; |
643 |
|
|
sz.cy = 0; |
644 |
|
|
while (cchString-- > 0) |
645 |
|
|
{ |
646 |
|
|
GetTextExtentPoint(hdc, lpszString, 1, &szchr); |
647 |
|
|
sz.cx += szchr.cx; |
648 |
|
|
*lpnDx = szchr.cx; |
649 |
|
|
|
650 |
|
|
++lpszString; |
651 |
|
|
++lpnDx; |
652 |
|
|
} |
653 |
|
|
lpSize->cx = sz.cx; |
654 |
|
|
lpSize->cy = sz.cy; |
655 |
|
|
return TRUE; |
656 |
|
|
} |
657 |
|
|
|
658 |
|
|
#define GetTextExtentPoint32 GetTextExtentPoint |
659 |
|
|
|
660 |
|
|
#endif |
661 |
|
|
|
662 |
|
|
gate_result_t gate_ui_graphics_get_char_size(gate_ui_graphics_t* graph, gate_ui_font_t const* font, |
663 |
|
|
gate_char32_t const* chars, gate_size_t charcount, gate_int32_t* charlens) |
664 |
|
|
{ |
665 |
|
|
/* NOTICE: this function only supports up to 2048 characters! */ |
666 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
667 |
|
|
HDC hdc = GATE_UI_GRAPHICS_HDC(graph); |
668 |
|
|
TCHAR buffer[2048]; |
669 |
|
|
int lengths[2048]; |
670 |
|
|
gate_size_t bufferused = gate_win32_utf32_2_winstr(chars, charcount, buffer, sizeof(buffer) / sizeof(buffer[0])); |
671 |
|
|
HGDIOBJ hbackup; |
672 |
|
|
HFONT hfont = (HFONT)gate_ui_winapi_create_font(font); |
673 |
|
|
SIZE sz = { 0, 0 }; |
674 |
|
|
gate_size_t index; |
675 |
|
|
|
676 |
|
|
hbackup = SelectObject(hdc, (HGDIOBJ)hfont); |
677 |
|
|
|
678 |
|
|
if (FALSE == GetTextExtentExPoint(hdc, buffer, (int)bufferused, 0, NULL, lengths, &sz)) |
679 |
|
|
{ |
680 |
|
|
gate_win32_print_lasterror(&ret, NULL, 0); |
681 |
|
|
} |
682 |
|
|
else |
683 |
|
|
{ |
684 |
|
|
for (index = 0; index != bufferused; ++index) |
685 |
|
|
{ |
686 |
|
|
charlens[index] = lengths[index]; |
687 |
|
|
} |
688 |
|
|
ret = GATE_RESULT_OK; |
689 |
|
|
} |
690 |
|
|
|
691 |
|
|
DeleteObject(SelectObject(hdc, hbackup)); |
692 |
|
|
return ret; |
693 |
|
|
} |
694 |
|
|
gate_result_t gate_ui_graphics_get_text_size(gate_ui_graphics_t* graph, gate_ui_font_t const* font, |
695 |
|
|
gate_string_t const* txt, gate_int32_t* width, gate_int32_t* height) |
696 |
|
|
{ |
697 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
698 |
|
|
HDC hdc = GATE_UI_GRAPHICS_HDC(graph); |
699 |
|
|
HGDIOBJ hbackup = NULL; |
700 |
|
|
TCHAR buffer[4096]; |
701 |
|
|
gate_size_t bufferused = gate_win32_utf8_2_winstr(txt->str, txt->length, buffer, sizeof(buffer) / sizeof(buffer[0])); |
702 |
|
|
HFONT hfont = (HFONT)gate_ui_winapi_create_font(font); |
703 |
|
|
SIZE sz = { 0, 0 }; |
704 |
|
|
|
705 |
|
|
hbackup = SelectObject(hdc, (HGDIOBJ)hfont); |
706 |
|
|
|
707 |
|
|
if (FALSE == GetTextExtentPoint32(hdc, buffer, (int)bufferused, &sz)) |
708 |
|
|
{ |
709 |
|
|
gate_win32_print_lasterror(&ret, NULL, 0); |
710 |
|
|
} |
711 |
|
|
else |
712 |
|
|
{ |
713 |
|
|
if (width) |
714 |
|
|
{ |
715 |
|
|
*width = (gate_int32_t)sz.cx; |
716 |
|
|
} |
717 |
|
|
if (height) |
718 |
|
|
{ |
719 |
|
|
*height = (gate_int32_t)sz.cy; |
720 |
|
|
} |
721 |
|
|
ret = GATE_RESULT_OK; |
722 |
|
|
} |
723 |
|
|
|
724 |
|
|
DeleteObject(SelectObject(hdc, hbackup)); |
725 |
|
|
return ret; |
726 |
|
|
} |
727 |
|
|
gate_result_t gate_ui_graphics_print(gate_ui_graphics_t* graph, gate_ui_font_t const* font, |
728 |
|
|
gate_string_t const* text, gate_ui_position_t const* pos) |
729 |
|
|
{ |
730 |
|
|
gate_bool_t success = true; |
731 |
|
|
HDC hdc = GATE_UI_GRAPHICS_HDC(graph); |
732 |
|
|
HGDIOBJ hbackup; |
733 |
|
|
HFONT hfont = (HFONT)gate_ui_winapi_create_font(font); |
734 |
|
|
TCHAR buffer[4096]; |
735 |
|
|
RECT rect; |
736 |
|
|
UINT flags = DT_LEFT | DT_NOPREFIX | DT_NOCLIP; |
737 |
|
|
gate_size_t bufferused = gate_win32_utf8_2_winstr(text->str, text->length, buffer, sizeof(buffer) / sizeof(buffer[0])); |
738 |
|
|
rect.left = pos->pos.x; |
739 |
|
|
rect.top = pos->pos.y; |
740 |
|
|
if ((pos->size.width == 0) && (pos->size.height == 0)) |
741 |
|
|
{ |
742 |
|
|
rect.bottom = graph->width; |
743 |
|
|
rect.right = graph->height; |
744 |
|
|
} |
745 |
|
|
else |
746 |
|
|
{ |
747 |
|
|
rect.bottom = pos->pos.x + pos->size.width + 1; |
748 |
|
|
rect.right = pos->pos.y + pos->size.height + 1; |
749 |
|
|
flags |= DT_VCENTER; |
750 |
|
|
} |
751 |
|
|
SetTextColor(hdc, RGB(font->color.r, font->color.g, font->color.b)); |
752 |
|
|
SetBkMode(hdc, TRANSPARENT); |
753 |
|
|
hbackup = SelectObject(hdc, (HGDIOBJ)hfont); |
754 |
|
|
success &= ((0 != DrawText(hdc, buffer, (int)bufferused, &rect, flags)) ? true : false); |
755 |
|
|
DeleteObject(SelectObject(hdc, hbackup)); |
756 |
|
|
return success ? GATE_RESULT_OK : GATE_RESULT_FAILED; |
757 |
|
|
} |
758 |
|
|
|
759 |
|
|
void* gate_ui_graphics_handle(gate_ui_graphics_t* graph) |
760 |
|
|
{ |
761 |
|
|
return (void*)GATE_UI_GRAPHICS_HDC(graph); |
762 |
|
|
} |
763 |
|
|
void* gate_ui_graphics_surface(gate_ui_graphics_t* graph) |
764 |
|
|
{ |
765 |
|
|
return (void*)GATE_UI_GRAPHICS_WINDOW(graph); |
766 |
|
|
} |
767 |
|
|
|
768 |
|
|
|
769 |
|
|
/***************************** |
770 |
|
|
* icon WIN32 implementation * |
771 |
|
|
*****************************/ |
772 |
|
|
|
773 |
|
|
gate_result_t gate_ui_icon_create_native(gate_ui_icon_t* icon, gate_ui_host_t* host, void* handle, gate_uint32_t flags) |
774 |
|
|
{ |
775 |
|
|
icon->host = host; |
776 |
|
|
icon->resources[0] = handle; |
777 |
|
|
icon->flags = flags; |
778 |
|
|
return GATE_RESULT_OK; |
779 |
|
|
} |
780 |
|
|
|
781 |
|
|
typedef UINT(WINAPI* ExtractIconEx_funcptr_t)(LPCTSTR lpszFile, int nIconIndex, HICON* phiconLarge, HICON* phiconSmall, UINT nIcons); |
782 |
|
|
static ExtractIconEx_funcptr_t ExtractIconEx_function = NULL; |
783 |
|
|
|
784 |
|
|
static HICON gate_ui_extract_icon(LPCTSTR file, int icon_index, gate_uint32_t flags) |
785 |
|
|
{ |
786 |
|
|
gate_bool_t is_small = GATE_FLAG_ENABLED(flags, GATE_UI_ICON_FLAG_SMALL); |
787 |
|
|
HICON hicon = NULL; |
788 |
|
|
HMODULE hmod; |
789 |
|
|
UINT extracted; |
790 |
|
|
do |
791 |
|
|
{ |
792 |
|
|
if (ExtractIconEx_function == NULL) |
793 |
|
|
{ |
794 |
|
|
hmod = gate_win32_get_shell_module(); |
795 |
|
|
if (hmod != NULL) |
796 |
|
|
{ |
797 |
|
|
gate_win32_get_proc_address(hmod, GATE_WINAPI_DUAL_NAME("ExtractIconEx"), &ExtractIconEx_function); |
798 |
|
|
} |
799 |
|
|
} |
800 |
|
|
if (ExtractIconEx_function != NULL) |
801 |
|
|
{ |
802 |
|
|
extracted = ExtractIconEx_function(file, icon_index, is_small ? NULL : &hicon, is_small ? &hicon : NULL, 1); |
803 |
|
|
if (extracted == 0) |
804 |
|
|
{ |
805 |
|
|
hicon = NULL; |
806 |
|
|
} |
807 |
|
|
} |
808 |
|
|
} while (0); |
809 |
|
|
return hicon; |
810 |
|
|
} |
811 |
|
|
|
812 |
|
|
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) |
813 |
|
|
{ |
814 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
815 |
|
|
HICON hicon = NULL; |
816 |
|
|
|
817 |
|
|
#if defined(GATE_SYS_WINCE) |
818 |
|
|
hicon = LoadCursor(NULL, IDC_APPSTARTING); |
819 |
|
|
#else |
820 |
|
|
LPCTSTR icon_source_file = _T("shell32.dll"); |
821 |
|
|
int icon_source_index = -1; |
822 |
|
|
int icon_source_index_alt = -1; |
823 |
|
|
|
824 |
|
|
switch (stock_id) |
825 |
|
|
{ |
826 |
|
|
case GATE_UI_ICON_STOCK_APP: icon_source_index = 2; break; |
827 |
|
|
case GATE_UI_ICON_STOCK_DOCUMENT: icon_source_index = 1; break; |
828 |
|
|
case GATE_UI_ICON_STOCK_FOLDER: icon_source_index = 3; break; |
829 |
|
|
case GATE_UI_ICON_STOCK_FOLDEROPEN: icon_source_index = 4; break; |
830 |
|
|
case GATE_UI_ICON_STOCK_NEWFILE: icon_source_index = 70; icon_source_index_alt = 1; break; |
831 |
|
|
case GATE_UI_ICON_STOCK_OPENFILE: icon_source_index = 126; icon_source_index_alt = 85; break; |
832 |
|
|
case GATE_UI_ICON_STOCK_SAVEFILE: icon_source_index = 258; icon_source_index_alt = 6; break; |
833 |
|
|
case GATE_UI_ICON_STOCK_PRINTER: icon_source_index = 16; break; |
834 |
|
|
case GATE_UI_ICON_STOCK_CUT: icon_source_index = 259; icon_source_index_alt = 65; break; |
835 |
|
|
case GATE_UI_ICON_STOCK_COPY: icon_source_index = 134; icon_source_index_alt = 54; break; |
836 |
|
|
case GATE_UI_ICON_STOCK_PASTE: icon_source_index = 260; icon_source_index_alt = 66; break; |
837 |
|
|
case GATE_UI_ICON_STOCK_DELETE: icon_source_index = 131; icon_source_index_alt = 105; break; |
838 |
|
|
case GATE_UI_ICON_STOCK_FIND: icon_source_index = 22; break; |
839 |
|
|
case GATE_UI_ICON_STOCK_HELP: icon_source_index = 23; break; |
840 |
|
|
|
841 |
|
|
case GATE_UI_ICON_STOCK_STORAGE: icon_source_index = 8; icon_source_index_alt = 8; break; |
842 |
|
|
case GATE_UI_ICON_STOCK_COMPUTER: icon_source_index = 15; icon_source_index_alt = 15; break; |
843 |
|
|
case GATE_UI_ICON_STOCK_NETWORK: icon_source_index = 18; icon_source_index_alt = 18; break; |
844 |
|
|
case GATE_UI_ICON_STOCK_GLOBE: icon_source_index = 13; icon_source_index_alt = 13; break; |
845 |
|
|
case GATE_UI_ICON_STOCK_SETTINGS: icon_source_index = 90; icon_source_index_alt = 21; break; |
846 |
|
|
case GATE_UI_ICON_STOCK_HOME: icon_source_index = 150; icon_source_index_alt = 39; break; |
847 |
|
|
case GATE_UI_ICON_STOCK_IMAGE: icon_source_index = 117; icon_source_index_alt = 34; break; |
848 |
|
|
case GATE_UI_ICON_STOCK_AUDIO: icon_source_index = 116; icon_source_index_alt = 40; break; |
849 |
|
|
case GATE_UI_ICON_STOCK_VIDEO: icon_source_index = 115; icon_source_index_alt = 79; break; |
850 |
|
|
case GATE_UI_ICON_STOCK_MAIL: icon_source_index = 156; icon_source_index_alt = 91; break; |
851 |
|
|
|
852 |
|
|
default: break; |
853 |
|
|
} |
854 |
|
|
|
855 |
|
|
if (icon_source_index < 0) |
856 |
|
|
{ |
857 |
|
|
return GATE_RESULT_NOMATCH; |
858 |
|
|
} |
859 |
|
|
|
860 |
|
|
hicon = gate_ui_extract_icon(icon_source_file, icon_source_index, flags); |
861 |
|
|
if ((hicon == NULL) && (icon_source_index_alt >= 0)) |
862 |
|
|
{ |
863 |
|
|
hicon = gate_ui_extract_icon(icon_source_file, icon_source_index_alt, flags); |
864 |
|
|
} |
865 |
|
|
|
866 |
|
|
|
867 |
|
|
if (icon_source_index >= 0) |
868 |
|
|
{ |
869 |
|
|
} |
870 |
|
|
else |
871 |
|
|
{ |
872 |
|
|
ret = GATE_RESULT_NOMATCH; |
873 |
|
|
} |
874 |
|
|
#endif |
875 |
|
|
|
876 |
|
|
if (hicon != NULL) |
877 |
|
|
{ |
878 |
|
|
ret = gate_ui_icon_create_native(icon, host, (void*)hicon, (flags & GATE_UI_ICON_FLAG_SMALL) | GATE_UI_ICON_FLAG_STOCK); |
879 |
|
|
if (GATE_FAILED(ret)) |
880 |
|
|
{ |
881 |
|
|
DestroyIcon(hicon); |
882 |
|
|
} |
883 |
|
|
icon->resources[1] = (void*)(gate_uintptr_t)stock_id; |
884 |
|
|
} |
885 |
|
|
else |
886 |
|
|
{ |
887 |
|
|
ret = GATE_RESULT_NOTAVAILABLE; |
888 |
|
|
} |
889 |
|
|
return ret; |
890 |
|
|
} |
891 |
|
|
|
892 |
|
|
#if defined(GATE_SYS_WIN16) |
893 |
|
|
|
894 |
|
|
static HICON gate_ui_icon_create_from_image(gate_ui_host_t* host, gate_rasterimage_t const* image, gate_uint32_t hx, gate_uint32_t hy) |
895 |
|
|
{ |
896 |
|
|
/* TODO */ |
897 |
|
|
return CreateIcon(NULL, 32, 32, 2, 2, NULL, NULL); |
898 |
|
|
} |
899 |
|
|
|
900 |
|
|
#else /* GATE_SYS_WIN16 */ |
901 |
|
|
|
902 |
|
|
static HICON gate_ui_icon_create_from_image(gate_ui_host_t* host, gate_rasterimage_t const* image, gate_uint32_t hx, gate_uint32_t hy) |
903 |
|
|
{ |
904 |
|
|
HICON ret = NULL; |
905 |
|
|
gate_ui_position_t imagerect; |
906 |
|
|
gate_ui_color_t maskcolor = { 255, 255, 255, 255 }; |
907 |
|
|
gate_color_t const* ptrpixels; |
908 |
|
|
gate_ui_point_t pos; |
909 |
|
|
gate_uint32_t icon_flags = 0; |
910 |
|
|
static COLORREF color_black = RGB(0, 0, 0); |
911 |
|
|
static COLORREF color_white = RGB(255, 255, 255); |
912 |
|
|
COLORREF color_bg = GetSysColor(COLOR_3DFACE); |
913 |
|
|
|
914 |
|
|
ICONINFO iconinfo; |
915 |
|
|
|
916 |
|
|
HBITMAP hbmptmp1 = NULL; |
917 |
|
|
HBITMAP hbmptmp2 = NULL; |
918 |
|
|
HBITMAP bmpmask = NULL; |
919 |
|
|
HBITMAP bmpimage = NULL; |
920 |
|
|
HDC desk = NULL; |
921 |
|
|
HDC hmask = NULL; |
922 |
|
|
HDC himage = NULL; |
923 |
|
|
|
924 |
|
|
do |
925 |
|
|
{ |
926 |
|
|
iconinfo.fIcon = TRUE; |
927 |
|
|
iconinfo.xHotspot = hx; |
928 |
|
|
iconinfo.yHotspot = hy; |
929 |
|
|
iconinfo.hbmMask = NULL; |
930 |
|
|
iconinfo.hbmColor = NULL; |
931 |
|
|
|
932 |
|
|
imagerect.pos.x = 0; |
933 |
|
|
imagerect.pos.y = 0; |
934 |
|
|
imagerect.size.width = image->width; |
935 |
|
|
imagerect.size.height = image->height; |
936 |
|
|
|
937 |
|
|
desk = GetDC(NULL); |
938 |
|
|
hmask = CreateCompatibleDC(desk); |
939 |
|
|
himage = CreateCompatibleDC(desk); |
940 |
|
|
|
941 |
|
|
bmpmask = CreateBitmap(image->width, image->height, 1, 1, NULL); |
942 |
|
|
bmpimage = CreateCompatibleBitmap(desk, image->width, image->height); |
943 |
|
|
|
944 |
|
|
hbmptmp1 = (HBITMAP)SelectObject(hmask, bmpmask); |
945 |
|
|
hbmptmp2 = (HBITMAP)SelectObject(himage, bmpimage); |
946 |
|
|
|
947 |
|
|
ptrpixels = (gate_color_t const*)gate_rasterimage_get_line_ptr(image, 0); |
948 |
|
|
for (pos.y = 0; pos.y != image->height; ++pos.y) |
949 |
|
|
{ |
950 |
|
|
for (pos.x = 0; pos.x != image->width; ++pos.x) |
951 |
|
|
{ |
952 |
|
|
SetPixel(hmask, pos.x, pos.y, (ptrpixels->a > 127) ? color_black : color_white); |
953 |
|
|
SetPixel(himage, pos.x, pos.y, (ptrpixels->a > 127) ? RGB(ptrpixels->r, ptrpixels->g, ptrpixels->b) : color_black); |
954 |
|
|
++ptrpixels; |
955 |
|
|
} |
956 |
|
|
} |
957 |
|
|
SelectObject(hmask, hbmptmp1); |
958 |
|
|
SelectObject(himage, hbmptmp2); |
959 |
|
|
DeleteDC(hmask); |
960 |
|
|
DeleteDC(himage); |
961 |
|
|
ReleaseDC(NULL, desk); |
962 |
|
|
|
963 |
|
|
if (image->height < 24) |
964 |
|
|
{ |
965 |
|
|
icon_flags |= GATE_UI_ICON_FLAG_SMALL; |
966 |
|
|
} |
967 |
|
|
if (image->height > 40) |
968 |
|
|
{ |
969 |
|
|
icon_flags |= GATE_UI_ICON_FLAG_LARGE; |
970 |
|
|
} |
971 |
|
|
|
972 |
|
|
iconinfo.hbmMask = bmpmask; |
973 |
|
|
iconinfo.hbmColor = bmpimage; |
974 |
|
|
|
975 |
|
|
ret = CreateIconIndirect(&iconinfo); |
976 |
|
|
GATE_DEBUG_ASSERT(ret != NULL); |
977 |
|
|
|
978 |
|
|
DeleteObject(bmpmask); |
979 |
|
|
DeleteObject(bmpimage); |
980 |
|
|
} while (0); |
981 |
|
|
|
982 |
|
|
return ret; |
983 |
|
|
} |
984 |
|
|
|
985 |
|
|
#endif /* GATE_SYS_WIN16 */ |
986 |
|
|
|
987 |
|
|
gate_result_t gate_ui_icon_create_image(gate_ui_icon_t* icon, gate_ui_host_t* host, gate_rasterimage_t const* image) |
988 |
|
|
{ |
989 |
|
|
gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED; |
990 |
|
|
HICON hicon = gate_ui_icon_create_from_image(host, image, 0, 0); |
991 |
|
|
if (hicon == NULL) |
992 |
|
|
{ |
993 |
|
|
ret = GATE_RESULT_FAILED; |
994 |
|
|
} |
995 |
|
|
else |
996 |
|
|
{ |
997 |
|
|
icon->resources[0] = hicon; |
998 |
|
|
icon->resources[1] = NULL; |
999 |
|
|
icon->host = host; |
1000 |
|
|
if (image->height < 28) |
1001 |
|
|
{ |
1002 |
|
|
icon->flags = GATE_UI_ICON_FLAG_SMALL; |
1003 |
|
|
} |
1004 |
|
|
else if (image->height > 36) |
1005 |
|
|
{ |
1006 |
|
|
icon->flags = GATE_UI_ICON_FLAG_LARGE; |
1007 |
|
|
} |
1008 |
|
|
|
1009 |
|
|
ret = GATE_RESULT_OK; |
1010 |
|
|
} |
1011 |
|
|
return ret; |
1012 |
|
|
} |
1013 |
|
|
gate_result_t gate_ui_icon_create_file(gate_ui_icon_t* icon, gate_ui_host_t* host, gate_string_t const* filepath) |
1014 |
|
|
{ |
1015 |
|
|
gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED; |
1016 |
|
|
/* TODO */ |
1017 |
|
|
return ret; |
1018 |
|
|
} |
1019 |
|
|
gate_result_t gate_ui_icon_copy(gate_ui_icon_t* dsticon, gate_ui_icon_t const* srcicon) |
1020 |
|
|
{ |
1021 |
|
|
gate_result_t ret = GATE_RESULT_OK; |
1022 |
|
|
dsticon->host = srcicon->host; |
1023 |
|
|
|
1024 |
|
|
#if !defined(GATE_SYS_WINCE) |
1025 |
|
|
if (!GATE_FLAG_ENABLED(srcicon->flags, GATE_UI_ICON_FLAG_STOCK)) |
1026 |
|
|
{ |
1027 |
|
|
/* managed icon */ |
1028 |
|
|
dsticon->flags = srcicon->flags; |
1029 |
|
|
#if defined(GATE_SYS_WIN16) |
1030 |
|
|
dsticon->resources[0] = (void*)CopyIcon(NULL, (HICON)srcicon->resources[0]); |
1031 |
|
|
#else |
1032 |
|
|
dsticon->resources[0] = (void*)CopyIcon((HICON)srcicon->resources[0]); |
1033 |
|
|
#endif |
1034 |
|
|
if (dsticon->resources[0] == NULL) |
1035 |
|
|
{ |
1036 |
|
|
ret = GATE_RESULT_FAILED; |
1037 |
|
|
} |
1038 |
|
|
dsticon->resources[1] = NULL; |
1039 |
|
|
} |
1040 |
|
|
else |
1041 |
|
|
#endif |
1042 |
|
|
{ |
1043 |
|
|
dsticon->resources[0] = srcicon->resources[0]; |
1044 |
|
|
dsticon->resources[1] = srcicon->resources[1]; |
1045 |
|
|
} |
1046 |
|
|
return ret; |
1047 |
|
|
} |
1048 |
|
|
|
1049 |
|
|
gate_result_t gate_ui_icon_destroy(gate_ui_icon_t* icon) |
1050 |
|
|
{ |
1051 |
|
|
gate_result_t ret = GATE_RESULT_OK; |
1052 |
|
|
if (!GATE_FLAG_ENABLED(icon->flags, GATE_UI_ICON_FLAG_STOCK)) |
1053 |
|
|
{ |
1054 |
|
|
/* managed icon */ |
1055 |
|
|
if (!DestroyIcon((HICON)icon->resources[0])) |
1056 |
|
|
{ |
1057 |
|
|
ret = GATE_RESULT_FAILED; |
1058 |
|
|
} |
1059 |
|
|
} |
1060 |
|
|
return ret; |
1061 |
|
|
} |
1062 |
|
|
|
1063 |
|
|
|
1064 |
|
|
|
1065 |
|
|
/****************** |
1066 |
|
|
* iconlist WIN32 * |
1067 |
|
|
******************/ |
1068 |
|
|
#if !defined(ILC_COLOR16) && defined(ILC_COLOR) |
1069 |
|
|
# define ILC_COLOR16 ILC_COLOR |
1070 |
|
|
#endif |
1071 |
|
|
|
1072 |
|
|
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) |
1073 |
|
|
{ |
1074 |
|
|
#if defined(GATE_SYS_WIN16) |
1075 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1076 |
|
|
#else |
1077 |
|
|
int const x = (int)width; |
1078 |
|
|
int const y = (int)height; |
1079 |
|
|
static UINT const flags = ILC_COLOR16 | ILC_MASK; |
1080 |
|
|
HIMAGELIST hlst = (HIMAGELIST)gate_ui_winapi_imagelist_create(x, y, flags, 1, 1); |
1081 |
|
|
if (!hlst) |
1082 |
|
|
{ |
1083 |
|
|
return GATE_RESULT_FAILED; |
1084 |
|
|
} |
1085 |
|
|
gate_ui_winapi_imagelist_set_bkcolor(hlst, NULL); |
1086 |
|
|
gate_mem_clear(ilst, sizeof(gate_ui_iconlist_t)); |
1087 |
|
|
ilst->host = host; |
1088 |
|
|
ilst->flags = 0; |
1089 |
|
|
ilst->width = width; |
1090 |
|
|
ilst->height = height; |
1091 |
|
|
ilst->resources[0] = hlst; |
1092 |
|
|
return GATE_RESULT_OK; |
1093 |
|
|
#endif |
1094 |
|
|
} |
1095 |
|
|
|
1096 |
|
|
gate_result_t gate_ui_iconlist_destroy(gate_ui_iconlist_t* ilst) |
1097 |
|
|
{ |
1098 |
|
|
#if defined(GATE_SYS_WIN16) |
1099 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1100 |
|
|
#else |
1101 |
|
|
if (ilst->resources[0] != NULL) |
1102 |
|
|
{ |
1103 |
|
|
gate_ui_winapi_imagelist_destroy((HIMAGELIST)ilst->resources[0]); |
1104 |
|
|
} |
1105 |
|
|
gate_mem_clear(ilst, sizeof(gate_ui_iconlist_t)); |
1106 |
|
|
return GATE_RESULT_OK; |
1107 |
|
|
#endif |
1108 |
|
|
} |
1109 |
|
|
gate_size_t gate_ui_iconlist_count(gate_ui_iconlist_t* ilst) |
1110 |
|
|
{ |
1111 |
|
|
return 0; |
1112 |
|
|
} |
1113 |
|
|
gate_result_t gate_ui_iconlist_add(gate_ui_iconlist_t* ilst, gate_ui_icon_t const* icon, gate_intptr_t* icon_key) |
1114 |
|
|
{ |
1115 |
|
|
#if defined(GATE_SYS_WIN16) |
1116 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1117 |
|
|
#else |
1118 |
|
|
HIMAGELIST hlst = (HIMAGELIST)ilst->resources[0]; |
1119 |
|
|
int index; |
1120 |
|
|
|
1121 |
|
|
if (!hlst) |
1122 |
|
|
{ |
1123 |
|
|
return GATE_RESULT_INVALIDSTATE; |
1124 |
|
|
} |
1125 |
|
|
|
1126 |
|
|
index = gate_ui_winapi_imagelist_replace_icon(hlst, -1, (HICON)icon->resources[0]); |
1127 |
|
|
if (index < 0) |
1128 |
|
|
{ |
1129 |
|
|
return GATE_RESULT_FAILED; |
1130 |
|
|
} |
1131 |
|
|
else |
1132 |
|
|
{ |
1133 |
|
|
if (icon_key) |
1134 |
|
|
{ |
1135 |
|
|
*icon_key = index; |
1136 |
|
|
} |
1137 |
|
|
return GATE_RESULT_OK; |
1138 |
|
|
} |
1139 |
|
|
#endif |
1140 |
|
|
} |
1141 |
|
|
|
1142 |
|
|
gate_result_t gate_ui_iconlist_add_image(gate_ui_iconlist_t* ilst, gate_rasterimage_t const* image, gate_intptr_t* icon_key) |
1143 |
|
|
{ |
1144 |
|
|
#if defined(GATE_SYS_WIN16) |
1145 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1146 |
|
|
#else |
1147 |
|
|
gate_ui_icon_t icon = GATE_INIT_EMPTY; |
1148 |
|
|
gate_result_t ret = gate_ui_icon_create_image(&icon, ilst->host, image); |
1149 |
|
|
if (GATE_SUCCEEDED(ret)) |
1150 |
|
|
{ |
1151 |
|
|
ret = gate_ui_iconlist_add(ilst, &icon, icon_key); |
1152 |
|
|
gate_ui_icon_destroy(&icon); |
1153 |
|
|
} |
1154 |
|
|
return ret; |
1155 |
|
|
#endif |
1156 |
|
|
} |
1157 |
|
|
|
1158 |
|
|
gate_result_t gate_ui_iconlist_get(gate_ui_iconlist_t* ilst, gate_intptr_t icon_key, gate_ui_icon_t* icon) |
1159 |
|
|
{ |
1160 |
|
|
#if defined(GATE_SYS_WIN16) |
1161 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1162 |
|
|
#else |
1163 |
|
|
UINT flags = ILD_TRANSPARENT; |
1164 |
|
|
gate_uint32_t icon_flags; |
1165 |
|
|
HICON hicon = (HICON)gate_ui_winapi_imagelist_get_icon((HIMAGELIST)ilst->resources[0], (int)icon_key, flags); |
1166 |
|
|
if (!hicon) |
1167 |
|
|
{ |
1168 |
|
|
return GATE_RESULT_FAILED; |
1169 |
|
|
} |
1170 |
|
|
else |
1171 |
|
|
{ |
1172 |
|
|
icon_flags = GATE_UI_ICON_FLAG_STOCK; |
1173 |
|
|
if (ilst->height < 24) |
1174 |
|
|
{ |
1175 |
|
|
icon_flags |= GATE_UI_ICON_FLAG_SMALL; |
1176 |
|
|
} |
1177 |
|
|
if (ilst->height > 40) |
1178 |
|
|
{ |
1179 |
|
|
icon_flags |= GATE_UI_ICON_FLAG_LARGE; |
1180 |
|
|
} |
1181 |
|
|
return gate_ui_icon_create_native(icon, ilst->host, hicon, icon_flags); |
1182 |
|
|
} |
1183 |
|
|
#endif |
1184 |
|
|
} |
1185 |
|
|
|
1186 |
|
|
|
1187 |
|
|
|
1188 |
|
|
|
1189 |
|
|
/**************** |
1190 |
|
|
* cursor WIN32 * |
1191 |
|
|
****************/ |
1192 |
|
|
|
1193 |
|
|
#ifndef IDC_APPSTARTING |
1194 |
|
|
#define IDC_APPSTARTING IDC_WAIT |
1195 |
|
|
#endif |
1196 |
|
|
|
1197 |
|
|
#ifndef IDC_NO |
1198 |
|
|
#define IDC_NO IDC_ICON |
1199 |
|
|
#endif |
1200 |
|
|
|
1201 |
|
|
gate_result_t gate_ui_cursor_create_stock(gate_ui_cursor_t* cursor, gate_ui_host_t* host, gate_uint32_t stock_id) |
1202 |
|
|
{ |
1203 |
|
|
LPCTSTR resourceId = NULL; |
1204 |
|
|
HCURSOR hcursor = NULL; |
1205 |
|
|
|
1206 |
|
|
switch (stock_id) |
1207 |
|
|
{ |
1208 |
|
|
case GATE_UI_CURSOR_STOCK_POINTER: resourceId = IDC_ARROW; break; |
1209 |
|
|
case GATE_UI_CURSOR_STOCK_BUSY: resourceId = IDC_WAIT; break; |
1210 |
|
|
case GATE_UI_CURSOR_STOCK_STARTING: resourceId = IDC_APPSTARTING; break; |
1211 |
|
|
case GATE_UI_CURSOR_STOCK_HAND: resourceId = /*IDC_HAND*/ IDC_UPARROW; break; |
1212 |
|
|
case GATE_UI_CURSOR_STOCK_TEXT: resourceId = IDC_IBEAM; break; |
1213 |
|
|
case GATE_UI_CURSOR_STOCK_REJECTED: resourceId = IDC_NO; break; |
1214 |
|
|
case GATE_UI_CURSOR_STOCK_SIZE_ALL: resourceId = IDC_SIZE; break; |
1215 |
|
|
case GATE_UI_CURSOR_STOCK_SIZE_LEFTRIGHT: resourceId = IDC_SIZEWE; break; |
1216 |
|
|
case GATE_UI_CURSOR_STOCK_SIZE_UPDOWN: resourceId = IDC_SIZENS; break; |
1217 |
|
|
case GATE_UI_CURSOR_STOCK_SIZE_LEFTUPRIGHTDOWN: resourceId = IDC_SIZENWSE; break; |
1218 |
|
|
case GATE_UI_CURSOR_STOCK_SIZE_RIGHTUPKEFTDOWN: resourceId = IDC_SIZENESW; break; |
1219 |
|
|
default: return GATE_RESULT_INVALIDARG; |
1220 |
|
|
} |
1221 |
|
|
|
1222 |
|
|
hcursor = LoadCursor(NULL, resourceId); |
1223 |
|
|
if (NULL == hcursor) |
1224 |
|
|
{ |
1225 |
|
|
return GATE_RESULT_FAILED; |
1226 |
|
|
} |
1227 |
|
|
cursor->host = host; |
1228 |
|
|
cursor->resources[0] = (void*)hcursor; |
1229 |
|
|
cursor->resources[1] = NULL; |
1230 |
|
|
cursor->flags = GATE_UI_CURSOR_FLAG_STOCK; |
1231 |
|
|
return GATE_RESULT_OK; |
1232 |
|
|
} |
1233 |
|
|
gate_result_t gate_ui_cursor_create_native(gate_ui_cursor_t* cursor, gate_ui_host_t* host, void* handle, gate_uint32_t flags) |
1234 |
|
|
{ |
1235 |
|
|
cursor->host = host; |
1236 |
|
|
cursor->resources[0] = handle; |
1237 |
|
|
cursor->resources[1] = NULL; |
1238 |
|
|
cursor->flags = flags; |
1239 |
|
|
return GATE_RESULT_OK; |
1240 |
|
|
} |
1241 |
|
|
gate_result_t gate_ui_cursor_create_image(gate_ui_cursor_t* cursor, gate_ui_host_t* host, gate_rasterimage_t const* image, gate_uint16_t x, gate_uint16_t y) |
1242 |
|
|
{ |
1243 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
1244 |
|
|
HCURSOR hcursor = (HCURSOR)gate_ui_icon_create_from_image(host, image, x, y); |
1245 |
|
|
if (hcursor) |
1246 |
|
|
{ |
1247 |
|
|
cursor->resources[0] = (void*)hcursor; |
1248 |
|
|
cursor->resources[1] = NULL; |
1249 |
|
|
cursor->host = host; |
1250 |
|
|
cursor->flags = 0; |
1251 |
|
|
ret = GATE_RESULT_OK; |
1252 |
|
|
} |
1253 |
|
|
return ret; |
1254 |
|
|
} |
1255 |
|
|
gate_result_t gate_ui_cursor_create_file(gate_ui_cursor_t* cursor, gate_ui_host_t* host, gate_string_t const* filepath) |
1256 |
|
|
{ |
1257 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1258 |
|
|
} |
1259 |
|
|
|
1260 |
|
|
gate_result_t gate_ui_cursor_copy(gate_ui_cursor_t* dsticon, gate_ui_cursor_t const* srcicon) |
1261 |
|
|
{ |
1262 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
1263 |
|
|
#if !defined(GATE_SYS_WINCE) && !defined(GATE_SYS_WIN16) |
1264 |
|
|
if (!GATE_FLAG_ENABLED(srcicon->flags, GATE_UI_CURSOR_FLAG_STOCK)) |
1265 |
|
|
{ |
1266 |
|
|
dsticon->resources[0] = (void*)CopyImage((HANDLE)srcicon->resources[0], IMAGE_CURSOR, 0, 0, 0); |
1267 |
|
|
if (dsticon->resources[0]) |
1268 |
|
|
{ |
1269 |
|
|
dsticon->resources[1] = NULL; |
1270 |
|
|
dsticon->host = srcicon->host; |
1271 |
|
|
dsticon->flags = 0; |
1272 |
|
|
} |
1273 |
|
|
} |
1274 |
|
|
else |
1275 |
|
|
#endif /* ! GATE_SYS_WINCE */ |
1276 |
|
|
{ |
1277 |
|
|
gate_mem_copy(dsticon, srcicon, sizeof(gate_ui_cursor_t)); |
1278 |
|
|
} |
1279 |
|
|
return ret; |
1280 |
|
|
} |
1281 |
|
|
gate_result_t gate_ui_cursor_destroy(gate_ui_cursor_t* cursor) |
1282 |
|
|
{ |
1283 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
1284 |
|
|
if (cursor) |
1285 |
|
|
{ |
1286 |
|
|
ret = GATE_RESULT_OK; |
1287 |
|
|
if (!GATE_FLAG_ENABLED(cursor->flags, GATE_UI_CURSOR_FLAG_STOCK)) |
1288 |
|
|
{ |
1289 |
|
|
#if !defined(GATE_SYS_WINCE) |
1290 |
|
|
if (!DestroyCursor((HCURSOR)cursor->resources[0])) |
1291 |
|
|
{ |
1292 |
|
|
ret = GATE_RESULT_FAILED; |
1293 |
|
|
} |
1294 |
|
|
#endif |
1295 |
|
|
} |
1296 |
|
|
} |
1297 |
|
|
return ret; |
1298 |
|
|
} |
1299 |
|
|
|
1300 |
|
|
|
1301 |
|
|
|
1302 |
|
|
#endif /* GATE_UI_WINAPI */ |
1303 |
|
|
|
1304 |
|
|
|
1305 |
|
|
#if defined(GATE_UI_GTK) |
1306 |
|
|
|
1307 |
|
|
#include "gate/ui/gateui_gtk.h" |
1308 |
|
|
|
1309 |
|
|
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) |
1310 |
|
|
{ |
1311 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1312 |
|
|
} |
1313 |
|
|
|
1314 |
|
|
static cairo_format_t gate_ui_graphics_resolve_format(gate_uint32_t depth) |
1315 |
|
|
{ |
1316 |
|
|
if ((depth == 0) || (depth > 24)) |
1317 |
|
|
{ |
1318 |
|
|
return CAIRO_FORMAT_ARGB32; |
1319 |
|
|
} |
1320 |
|
|
else if (depth > 16) |
1321 |
|
|
{ |
1322 |
|
|
return CAIRO_FORMAT_RGB24; |
1323 |
|
|
} |
1324 |
|
|
else if (depth > 8) |
1325 |
|
|
{ |
1326 |
|
|
return CAIRO_FORMAT_RGB16_565; |
1327 |
|
|
} |
1328 |
|
|
else if (depth > 2) |
1329 |
|
|
{ |
1330 |
|
|
return CAIRO_FORMAT_A8; |
1331 |
|
|
} |
1332 |
|
|
else |
1333 |
|
|
{ |
1334 |
|
|
return CAIRO_FORMAT_A1; |
1335 |
|
|
} |
1336 |
|
|
|
1337 |
|
|
} |
1338 |
|
|
|
1339 |
|
|
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) |
1340 |
|
|
{ |
1341 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
1342 |
|
|
cairo_t* cr = NULL; |
1343 |
|
|
cairo_surface_t* surface = NULL; |
1344 |
|
|
cairo_format_t format; |
1345 |
|
|
|
1346 |
|
|
do |
1347 |
|
|
{ |
1348 |
|
|
gate_mem_clear(graph, sizeof(gate_ui_graphics_t)); |
1349 |
|
|
format = gate_ui_graphics_resolve_format(depth); |
1350 |
|
|
surface = cairo_image_surface_create(format, width, height); |
1351 |
|
|
if (surface == NULL) |
1352 |
|
|
{ |
1353 |
|
|
ret = GATE_RESULT_OUTOFRESOURCES; |
1354 |
|
|
break; |
1355 |
|
|
} |
1356 |
|
|
cr = cairo_create(surface); |
1357 |
|
|
if (cr == NULL) |
1358 |
|
|
{ |
1359 |
|
|
cairo_surface_destroy(surface); |
1360 |
|
|
ret = GATE_RESULT_OUTOFRESOURCES; |
1361 |
|
|
break; |
1362 |
|
|
} |
1363 |
|
|
|
1364 |
|
|
graph->host = host; |
1365 |
|
|
graph->width = width; |
1366 |
|
|
graph->height = height; |
1367 |
|
|
graph->resources[0] = cr; |
1368 |
|
|
graph->resources[1] = surface; |
1369 |
|
|
|
1370 |
|
|
ret = GATE_RESULT_OK; |
1371 |
|
|
} while (0); |
1372 |
|
|
|
1373 |
|
|
return ret; |
1374 |
|
|
} |
1375 |
|
|
gate_result_t gate_ui_graphics_create_image_from(gate_ui_graphics_t* graph, gate_ui_host_t* host, gate_rasterimage_t const* rasterimage) |
1376 |
|
|
{ |
1377 |
|
|
gate_result_t ret = gate_ui_graphics_create_image(graph, host, rasterimage->width, rasterimage->height, 32); |
1378 |
|
|
gate_ui_point_t pnt = { 0, 0 }; |
1379 |
|
|
gate_ui_size_t sz = { rasterimage->width, rasterimage->height }; |
1380 |
|
|
|
1381 |
|
|
if (GATE_SUCCEEDED(ret)) |
1382 |
|
|
{ |
1383 |
|
|
ret = gate_ui_graphics_draw_image(graph, rasterimage, &pnt, &sz, &pnt); |
1384 |
|
|
if (GATE_FAILED(ret)) |
1385 |
|
|
{ |
1386 |
|
|
gate_ui_graphics_destroy(graph); |
1387 |
|
|
gate_mem_clear(graph, sizeof(gate_ui_graphics_t)); |
1388 |
|
|
} |
1389 |
|
|
} |
1390 |
|
|
return ret; |
1391 |
|
|
} |
1392 |
|
|
gate_result_t gate_ui_graphics_create_ctrl(gate_ui_graphics_t* graph, gate_ui_ctrl_t* ctrl) |
1393 |
|
|
{ |
1394 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
1395 |
|
|
gate_ui_host_t* host = GATE_UI_GTK_GET_CTRL_HOST(ctrl); |
1396 |
|
|
GtkWidget* widget = GATE_UI_GTK_GET_CTRL_WIDGET(ctrl); |
1397 |
|
|
GdkWindow* window = NULL; |
1398 |
|
|
int width, height; |
1399 |
|
|
cairo_surface_t* surface = NULL; |
1400 |
|
|
cairo_t* cr = NULL; |
1401 |
|
|
|
1402 |
|
|
do |
1403 |
|
|
{ |
1404 |
|
|
if (!host || !widget) |
1405 |
|
|
{ |
1406 |
|
|
ret = GATE_RESULT_NOTAVAILABLE; |
1407 |
|
|
break; |
1408 |
|
|
} |
1409 |
|
|
|
1410 |
|
|
window = gtk_widget_get_window(widget); |
1411 |
|
|
width = gtk_widget_get_allocated_width(widget); |
1412 |
|
|
height = gtk_widget_get_allocated_height(widget); |
1413 |
|
|
surface = gdk_window_create_similar_surface(window, CAIRO_CONTENT_COLOR, width, height); |
1414 |
|
|
if (!surface) |
1415 |
|
|
{ |
1416 |
|
|
ret = GATE_RESULT_OUTOFRESOURCES; |
1417 |
|
|
break; |
1418 |
|
|
} |
1419 |
|
|
cr = cairo_create(surface); |
1420 |
|
|
if (!cr) |
1421 |
|
|
{ |
1422 |
|
|
ret = GATE_RESULT_FAILED; |
1423 |
|
|
break; |
1424 |
|
|
} |
1425 |
|
|
|
1426 |
|
|
gate_mem_clear(graph, sizeof(gate_ui_graphics_t)); |
1427 |
|
|
graph->host = host; |
1428 |
|
|
graph->width = width; |
1429 |
|
|
graph->height = height; |
1430 |
|
|
graph->resources[0] = cr; |
1431 |
|
|
graph->resources[1] = surface; |
1432 |
|
|
cr = NULL; |
1433 |
|
|
surface = NULL; |
1434 |
|
|
ret = GATE_RESULT_OK; |
1435 |
|
|
} while (0); |
1436 |
|
|
|
1437 |
|
|
if (cr) |
1438 |
|
|
{ |
1439 |
|
|
cairo_destroy(cr); |
1440 |
|
|
} |
1441 |
|
|
if (surface) |
1442 |
|
|
{ |
1443 |
|
|
cairo_surface_destroy(surface); |
1444 |
|
|
} |
1445 |
|
|
return ret; |
1446 |
|
|
} |
1447 |
|
|
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) |
1448 |
|
|
{ |
1449 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
1450 |
|
|
|
1451 |
|
|
do |
1452 |
|
|
{ |
1453 |
|
|
gate_mem_clear(graph, sizeof(gate_ui_graphics_t)); |
1454 |
|
|
graph->host = host; |
1455 |
|
|
graph->resources[0] = cairo_reference((cairo_t*)graphics); /**< cairo_t */ |
1456 |
|
|
graph->resources[1] = param; /**< surface */ |
1457 |
|
|
graph->width = width; |
1458 |
|
|
graph->height = height; |
1459 |
|
|
ret = GATE_RESULT_OK; |
1460 |
|
|
} while (0); |
1461 |
|
|
|
1462 |
|
|
return ret; |
1463 |
|
|
} |
1464 |
|
|
gate_result_t gate_ui_graphics_destroy(gate_ui_graphics_t* graph) |
1465 |
|
|
{ |
1466 |
|
|
cairo_t* cr = graph->resources[0]; |
1467 |
|
|
cairo_surface_t* surface = graph->resources[1]; |
1468 |
|
|
|
1469 |
|
|
if (surface) |
1470 |
|
|
{ |
1471 |
|
|
cairo_surface_destroy(surface); |
1472 |
|
|
} |
1473 |
|
|
if (cr) |
1474 |
|
|
{ |
1475 |
|
|
cairo_destroy(cr); |
1476 |
|
|
} |
1477 |
|
|
return GATE_RESULT_OK; |
1478 |
|
|
} |
1479 |
|
|
|
1480 |
|
|
|
1481 |
|
|
gate_int32_t gate_ui_graphics_width(gate_ui_graphics_t* graph) |
1482 |
|
|
{ |
1483 |
|
|
return graph->width; |
1484 |
|
|
} |
1485 |
|
|
gate_int32_t gate_ui_graphics_height(gate_ui_graphics_t* graph) |
1486 |
|
|
{ |
1487 |
|
|
return graph->height; |
1488 |
|
|
} |
1489 |
|
|
gate_result_t gate_ui_graphics_set_pixel(gate_ui_graphics_t* graph, gate_ui_point_t pos, gate_ui_color_t col) |
1490 |
|
|
{ |
1491 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1492 |
|
|
} |
1493 |
|
|
gate_result_t gate_ui_graphics_get_pixel(gate_ui_graphics_t* graph, gate_ui_point_t pos, gate_ui_color_t* col) |
1494 |
|
|
{ |
1495 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1496 |
|
|
} |
1497 |
|
|
gate_result_t gate_ui_graphics_draw(gate_ui_graphics_t* graph, gate_ui_graphics_t* srcgraph, |
1498 |
|
|
gate_ui_point_t const* dst, gate_ui_size_t const* size, gate_ui_point_t const* src) |
1499 |
|
|
{ |
1500 |
|
|
cairo_t* cr = (cairo_t*)graph->resources[0]; |
1501 |
|
|
cairo_surface_t* src_surface = srcgraph->resources[1]; |
1502 |
|
|
if (src_surface == NULL) |
1503 |
|
|
{ |
1504 |
|
|
return GATE_RESULT_INVALIDINPUT; |
1505 |
|
|
} |
1506 |
|
|
|
1507 |
|
|
cairo_set_source_surface(cr, src_surface, dst ? dst->x : 0, dst ? dst->y : 0); |
1508 |
|
|
/* TODO: dst/src */ |
1509 |
|
|
cairo_paint(cr); |
1510 |
|
|
return GATE_RESULT_OK; |
1511 |
|
|
} |
1512 |
|
|
|
1513 |
|
|
gate_result_t gate_ui_graphics_draw_ex(gate_ui_graphics_t* graph, gate_ui_graphics_t* src_graph, |
1514 |
|
|
gate_ui_position_t const* dest_rect, gate_ui_position_t const* src_rect) |
1515 |
|
|
{ |
1516 |
|
|
cairo_t* cr = (cairo_t*)graph->resources[0]; |
1517 |
|
|
cairo_surface_t* src_surface = src_graph->resources[1]; |
1518 |
|
|
if (src_surface == NULL) |
1519 |
|
|
{ |
1520 |
|
|
return GATE_RESULT_INVALIDINPUT; |
1521 |
|
|
} |
1522 |
|
|
|
1523 |
|
|
cairo_set_source_surface(cr, src_surface, 0, 0); |
1524 |
|
|
/* TODO: dst/src */ |
1525 |
|
|
cairo_paint(cr); |
1526 |
|
|
return GATE_RESULT_OK; |
1527 |
|
|
} |
1528 |
|
|
|
1529 |
|
|
static GdkPixbuf* gate_ui_gtk_raster_to_pixbuf(gate_rasterimage_t const* srcimage, |
1530 |
|
|
gate_int32_t src_x, gate_int32_t src_y, gate_int32_t width, gate_int32_t height) |
1531 |
|
|
{ |
1532 |
|
|
GdkPixbuf* buf; |
1533 |
|
|
guchar* pixels; |
1534 |
|
|
gate_int32_t x, y; |
1535 |
|
|
guchar* dst_pixels; |
1536 |
|
|
gate_color_t const* src_pixels; |
1537 |
|
|
|
1538 |
|
|
if (src_x + width > (gate_int32_t)srcimage->width) |
1539 |
|
|
{ |
1540 |
|
|
width = (gate_int32_t)srcimage->width - src_x; |
1541 |
|
|
} |
1542 |
|
|
if (src_y + height > (gate_int32_t)srcimage->height) |
1543 |
|
|
{ |
1544 |
|
|
height = (gate_int32_t)srcimage->height - src_y; |
1545 |
|
|
} |
1546 |
|
|
|
1547 |
|
|
buf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, (int)width, (int)height); |
1548 |
|
|
if (buf != NULL) |
1549 |
|
|
{ |
1550 |
|
|
pixels = gdk_pixbuf_get_pixels(buf); |
1551 |
|
|
|
1552 |
|
|
for (y = 0; y < height; ++y) |
1553 |
|
|
{ |
1554 |
|
|
dst_pixels = pixels + (y * width) * 4; |
1555 |
|
|
src_pixels = (((gate_color_t*)gate_rasterimage_get_line_ptr(srcimage, (src_y + y))) + src_x); |
1556 |
|
|
for (x = 0; x < width; ++x) |
1557 |
|
|
{ |
1558 |
|
|
dst_pixels[0] = src_pixels->r; |
1559 |
|
|
dst_pixels[1] = src_pixels->g; |
1560 |
|
|
dst_pixels[2] = src_pixels->b; |
1561 |
|
|
dst_pixels[3] = src_pixels->a; |
1562 |
|
|
dst_pixels += 4; |
1563 |
|
|
src_pixels++; |
1564 |
|
|
} |
1565 |
|
|
} |
1566 |
|
|
} |
1567 |
|
|
return buf; |
1568 |
|
|
} |
1569 |
|
|
|
1570 |
|
|
gate_result_t gate_ui_graphics_draw_image(gate_ui_graphics_t* graph, gate_rasterimage_t const* srcimage, |
1571 |
|
|
gate_ui_point_t const* dst, gate_ui_size_t const* size, gate_ui_point_t const* srcpos) |
1572 |
|
|
{ |
1573 |
|
|
cairo_t* cr = (cairo_t*)graph->resources[0]; |
1574 |
|
|
int width, height; |
1575 |
|
|
GdkPixbuf* buf; |
1576 |
|
|
gate_int32_t src_x = 0; |
1577 |
|
|
gate_int32_t src_y = 0; |
1578 |
|
|
gate_int32_t dst_x = 0; |
1579 |
|
|
gate_int32_t dst_y = 0; |
1580 |
|
|
|
1581 |
|
|
width = srcimage->width; |
1582 |
|
|
height = srcimage->height; |
1583 |
|
|
if (size) |
1584 |
|
|
{ |
1585 |
|
|
width = size->width; |
1586 |
|
|
height = size->height; |
1587 |
|
|
} |
1588 |
|
|
if (dst) |
1589 |
|
|
{ |
1590 |
|
|
dst_x = dst->x; |
1591 |
|
|
dst_y = dst->y; |
1592 |
|
|
} |
1593 |
|
|
if (srcpos) |
1594 |
|
|
{ |
1595 |
|
|
src_x = srcpos->x; |
1596 |
|
|
src_y = srcpos->y; |
1597 |
|
|
} |
1598 |
|
|
|
1599 |
|
|
buf = gate_ui_gtk_raster_to_pixbuf(srcimage, src_x, src_y, width, height); |
1600 |
|
|
if (buf == NULL) |
1601 |
|
|
{ |
1602 |
|
|
return GATE_RESULT_OUTOFRESOURCES; |
1603 |
|
|
} |
1604 |
|
|
|
1605 |
|
|
gdk_cairo_set_source_pixbuf(cr, buf, dst_x, dst_y); |
1606 |
|
|
cairo_paint(cr); |
1607 |
|
|
g_object_unref(buf); |
1608 |
|
|
|
1609 |
|
|
return GATE_RESULT_OK; |
1610 |
|
|
} |
1611 |
|
|
|
1612 |
|
|
|
1613 |
|
|
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) |
1614 |
|
|
{ |
1615 |
|
|
cairo_t* cr = (cairo_t*)graph->resources[0]; |
1616 |
|
|
|
1617 |
|
|
cairo_set_source_rgba(cr, (double)col.r / 255.0, (double)col.g / 255.0, (double)col.b / 255.0, (double)col.a / 255.0); |
1618 |
|
|
cairo_set_line_width(cr, (double)linewidth); |
1619 |
|
|
cairo_move_to(cr, from.x, from.y); |
1620 |
|
|
cairo_line_to(cr, to.x, to.y); |
1621 |
|
|
cairo_stroke(cr); |
1622 |
|
|
return GATE_RESULT_OK; |
1623 |
|
|
} |
1624 |
|
|
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) |
1625 |
|
|
{ |
1626 |
|
|
cairo_t* cr = (cairo_t*)graph->resources[0]; |
1627 |
|
|
|
1628 |
|
|
if (colfill) |
1629 |
|
|
{ |
1630 |
|
|
cairo_set_source_rgba(cr, (double)colfill->r / 255.0, (double)colfill->g / 255.0, (double)colfill->b / 255.0, (double)colfill->a / 255.0); |
1631 |
|
|
cairo_rectangle(cr, rect.pos.x, rect.pos.y, rect.size.width, rect.size.height); |
1632 |
|
|
cairo_fill(cr); |
1633 |
|
|
} |
1634 |
|
|
|
1635 |
|
|
if (colline) |
1636 |
|
|
{ |
1637 |
|
|
cairo_set_source_rgba(cr, (double)colline->r / 255.0, (double)colline->g / 255.0, (double)colline->b / 255.0, (double)colline->a / 255.0); |
1638 |
|
|
cairo_set_line_width(cr, (double)linewidth); |
1639 |
|
|
cairo_rectangle(cr, rect.pos.x, rect.pos.y, rect.size.width, rect.size.height); |
1640 |
|
|
cairo_stroke(cr); |
1641 |
|
|
} |
1642 |
|
|
|
1643 |
|
|
return GATE_RESULT_OK; |
1644 |
|
|
} |
1645 |
|
|
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) |
1646 |
|
|
{ |
1647 |
|
|
cairo_t* cr = (cairo_t*)graph->resources[0]; |
1648 |
|
|
|
1649 |
|
|
|
1650 |
|
|
if (pointcount > 2) |
1651 |
|
|
{ |
1652 |
|
|
cairo_move_to(cr, points->x, points->y); |
1653 |
|
|
--pointcount; |
1654 |
|
|
++points; |
1655 |
|
|
|
1656 |
|
|
while (pointcount-- != 0) |
1657 |
|
|
{ |
1658 |
|
|
cairo_line_to(cr, points->x, points->y); |
1659 |
|
|
cairo_move_to(cr, points->x, points->y); |
1660 |
|
|
++points; |
1661 |
|
|
} |
1662 |
|
|
|
1663 |
|
|
if (colfill) |
1664 |
|
|
{ |
1665 |
|
|
cairo_set_source_rgba(cr, (double)colfill->r / 255.0, (double)colfill->g / 255.0, (double)colfill->b / 255.0, (double)colfill->a / 255.0); |
1666 |
|
|
if (colline) |
1667 |
|
|
{ |
1668 |
|
|
cairo_fill_preserve(cr); |
1669 |
|
|
} |
1670 |
|
|
else |
1671 |
|
|
{ |
1672 |
|
|
cairo_fill(cr); |
1673 |
|
|
} |
1674 |
|
|
} |
1675 |
|
|
|
1676 |
|
|
if (colline) |
1677 |
|
|
{ |
1678 |
|
|
cairo_set_source_rgba(cr, (double)colline->r / 255.0, (double)colline->g / 255.0, (double)colline->b / 255.0, (double)colline->a / 255.0); |
1679 |
|
|
cairo_set_line_width(cr, (double)linewidth); |
1680 |
|
|
cairo_stroke(cr); |
1681 |
|
|
} |
1682 |
|
|
|
1683 |
|
|
} |
1684 |
|
|
return GATE_RESULT_OK; |
1685 |
|
|
} |
1686 |
|
|
|
1687 |
|
|
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* textlens) |
1688 |
|
|
{ |
1689 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1690 |
|
|
} |
1691 |
|
|
|
1692 |
|
|
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) |
1693 |
|
|
{ |
1694 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1695 |
|
|
} |
1696 |
|
|
|
1697 |
|
|
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) |
1698 |
|
|
{ |
1699 |
|
|
/* |
1700 |
|
|
cairo_set_source_rgb(cr, 0.1, 0.1, 0.1); |
1701 |
|
|
|
1702 |
|
|
cairo_select_font_face(cr, "Purisa", |
1703 |
|
|
CAIRO_FONT_SLANT_NORMAL, |
1704 |
|
|
CAIRO_FONT_WEIGHT_BOLD); |
1705 |
|
|
|
1706 |
|
|
cairo_set_font_size(cr, 13); |
1707 |
|
|
|
1708 |
|
|
cairo_move_to(cr, 20, 30); |
1709 |
|
|
cairo_show_text(cr, "Most relationships seem so transitory"); |
1710 |
|
|
cairo_move_to(cr, 20, 60); |
1711 |
|
|
cairo_show_text(cr, "They're all good but not the permanent one"); |
1712 |
|
|
|
1713 |
|
|
cairo_move_to(cr, 20, 120); |
1714 |
|
|
cairo_show_text(cr, "Who doesn't long for someone to hold"); |
1715 |
|
|
|
1716 |
|
|
cairo_move_to(cr, 20, 150); |
1717 |
|
|
cairo_show_text(cr, "Who knows how to love you without being told"); |
1718 |
|
|
cairo_move_to(cr, 20, 180); |
1719 |
|
|
cairo_show_text(cr, "Somebody tell me why I'm on my own"); |
1720 |
|
|
cairo_move_to(cr, 20, 210); |
1721 |
|
|
cairo_show_text(cr, "If there's a soulmate for everyone"); |
1722 |
|
|
|
1723 |
|
|
*/ |
1724 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1725 |
|
|
} |
1726 |
|
|
|
1727 |
|
|
void* gate_ui_graphics_handle(gate_ui_graphics_t* graph) |
1728 |
|
|
{ |
1729 |
|
|
return graph->resources[0]; |
1730 |
|
|
} |
1731 |
|
|
void* gate_ui_graphics_surface(gate_ui_graphics_t* graph) |
1732 |
|
|
{ |
1733 |
|
|
return graph->resources[1]; |
1734 |
|
|
} |
1735 |
|
|
|
1736 |
|
|
|
1737 |
|
|
|
1738 |
|
|
|
1739 |
|
|
|
1740 |
|
|
/************ |
1741 |
|
|
* icon GTK * |
1742 |
|
|
************/ |
1743 |
|
|
|
1744 |
|
|
/* https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html */ |
1745 |
|
|
|
1746 |
|
|
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) |
1747 |
|
|
{ |
1748 |
|
|
gate_result_t ret = GATE_RESULT_OK; |
1749 |
|
|
char const* gtk_stock_id = NULL; |
1750 |
|
|
GtkIconTheme* theme = NULL; |
1751 |
|
|
GtkIconInfo* info = NULL; |
1752 |
|
|
gint size; |
1753 |
|
|
GError* error = NULL; |
1754 |
|
|
GdkPixbuf* pixbuf = NULL; |
1755 |
|
|
|
1756 |
|
|
do |
1757 |
|
|
{ |
1758 |
|
|
if (GATE_FLAG_ENABLED(flags, GATE_UI_ICON_FLAG_LARGE)) |
1759 |
|
|
{ |
1760 |
|
|
size = 48; |
1761 |
|
|
} |
1762 |
|
|
else if (GATE_FLAG_ENABLED(flags, GATE_UI_ICON_FLAG_SMALL)) |
1763 |
|
|
{ |
1764 |
|
|
size = 16; |
1765 |
|
|
} |
1766 |
|
|
else |
1767 |
|
|
{ |
1768 |
|
|
size = 32; |
1769 |
|
|
} |
1770 |
|
|
|
1771 |
|
|
theme = gtk_icon_theme_get_default(); |
1772 |
|
|
if (theme == NULL) |
1773 |
|
|
{ |
1774 |
|
|
ret = GATE_RESULT_NOTAVAILABLE; |
1775 |
|
|
break; |
1776 |
|
|
} |
1777 |
|
|
|
1778 |
|
|
switch (stock_id) |
1779 |
|
|
{ |
1780 |
|
|
case GATE_UI_ICON_STOCK_APP: gtk_stock_id = "system-run"; break; |
1781 |
|
|
case GATE_UI_ICON_STOCK_DOCUMENT: gtk_stock_id = "document-properties"; break; |
1782 |
|
|
case GATE_UI_ICON_STOCK_FOLDER: gtk_stock_id = "folder"; break; |
1783 |
|
|
case GATE_UI_ICON_STOCK_FOLDEROPEN: gtk_stock_id = "folder-open"; break; |
1784 |
|
|
case GATE_UI_ICON_STOCK_NEWFILE: gtk_stock_id = "document-new"; break; |
1785 |
|
|
case GATE_UI_ICON_STOCK_OPENFILE: gtk_stock_id = "document-open"; break; |
1786 |
|
|
case GATE_UI_ICON_STOCK_SAVEFILE: gtk_stock_id = "document-save"; break; |
1787 |
|
|
case GATE_UI_ICON_STOCK_PRINTER: gtk_stock_id = "document-print"; break; |
1788 |
|
|
case GATE_UI_ICON_STOCK_CUT: gtk_stock_id = "edit-cut"; break; |
1789 |
|
|
case GATE_UI_ICON_STOCK_COPY: gtk_stock_id = "edit-copy"; break; |
1790 |
|
|
case GATE_UI_ICON_STOCK_PASTE: gtk_stock_id = "edit-paste"; break; |
1791 |
|
|
case GATE_UI_ICON_STOCK_DELETE: gtk_stock_id = "edit-delete"; break; |
1792 |
|
|
|
1793 |
|
|
case GATE_UI_ICON_STOCK_FIND: gtk_stock_id = "edit-find"; break; |
1794 |
|
|
case GATE_UI_ICON_STOCK_HELP: gtk_stock_id = "help-contents"; break; |
1795 |
|
|
|
1796 |
|
|
case GATE_UI_ICON_STOCK_STORAGE: gtk_stock_id = "drive-harddisk"; break; |
1797 |
|
|
case GATE_UI_ICON_STOCK_COMPUTER: gtk_stock_id = "computer"; break; |
1798 |
|
|
case GATE_UI_ICON_STOCK_NETWORK: gtk_stock_id = "network-wired"; break; |
1799 |
|
|
case GATE_UI_ICON_STOCK_GLOBE: gtk_stock_id = "applications-internet"; break; |
1800 |
|
|
case GATE_UI_ICON_STOCK_SETTINGS: gtk_stock_id = "preferences-system"; break; |
1801 |
|
|
case GATE_UI_ICON_STOCK_HOME: gtk_stock_id = "go-home"; break; |
1802 |
|
|
case GATE_UI_ICON_STOCK_IMAGE: gtk_stock_id = "image-x-generic"; break; |
1803 |
|
|
case GATE_UI_ICON_STOCK_AUDIO: gtk_stock_id = "audio-x-generic"; break; |
1804 |
|
|
case GATE_UI_ICON_STOCK_VIDEO: gtk_stock_id = "video-x-generic"; break; |
1805 |
|
|
case GATE_UI_ICON_STOCK_MAIL: gtk_stock_id = "mail-send-receive"; break; |
1806 |
|
|
default: break; |
1807 |
|
|
} |
1808 |
|
|
|
1809 |
|
|
info = gtk_icon_theme_lookup_icon(theme, gtk_stock_id, size, GTK_ICON_LOOKUP_USE_BUILTIN | GTK_ICON_LOOKUP_GENERIC_FALLBACK); |
1810 |
|
|
if (info == NULL) |
1811 |
|
|
{ |
1812 |
|
|
ret = GATE_RESULT_NOMATCH; |
1813 |
|
|
break; |
1814 |
|
|
} |
1815 |
|
|
|
1816 |
|
|
pixbuf = gtk_icon_info_load_icon(info, &error); |
1817 |
|
|
if (pixbuf == NULL) |
1818 |
|
|
{ |
1819 |
|
|
ret = GATE_RESULT_FAILED; |
1820 |
|
|
break; |
1821 |
|
|
} |
1822 |
|
|
|
1823 |
|
|
gate_mem_clear(icon, sizeof(gate_ui_icon_t)); |
1824 |
|
|
icon->host = host; |
1825 |
|
|
icon->flags = flags & (GATE_UI_ICON_FLAG_SMALL | GATE_UI_ICON_FLAG_LARGE); |
1826 |
|
|
icon->resources[0] = pixbuf; |
1827 |
|
|
|
1828 |
|
|
ret = GATE_RESULT_OK; |
1829 |
|
|
} while (0); |
1830 |
|
|
|
1831 |
|
|
return ret; |
1832 |
|
|
} |
1833 |
|
|
gate_result_t gate_ui_icon_create_native(gate_ui_icon_t* icon, gate_ui_host_t* host, void* handle, gate_uint32_t flags) |
1834 |
|
|
{ |
1835 |
|
|
gate_mem_clear(icon, sizeof(gate_ui_icon_t)); |
1836 |
|
|
icon->host = host; |
1837 |
|
|
icon->flags = flags; |
1838 |
|
|
icon->resources[0] = handle; |
1839 |
|
|
return GATE_RESULT_OK; |
1840 |
|
|
} |
1841 |
|
|
gate_result_t gate_ui_icon_create_image(gate_ui_icon_t* icon, gate_ui_host_t* host, gate_rasterimage_t const* image) |
1842 |
|
|
{ |
1843 |
|
|
GdkPixbuf* buf = gate_ui_gtk_raster_to_pixbuf(image, 0, 0, image->width, image->height); |
1844 |
|
|
if (buf == NULL) |
1845 |
|
|
{ |
1846 |
|
|
return GATE_RESULT_OUTOFRESOURCES; |
1847 |
|
|
} |
1848 |
|
|
gate_mem_clear(icon, sizeof(gate_ui_icon_t)); |
1849 |
|
|
icon->host = host; |
1850 |
|
|
icon->flags = 0; |
1851 |
|
|
icon->resources[0] = buf; |
1852 |
|
|
return GATE_RESULT_OK; |
1853 |
|
|
} |
1854 |
|
|
gate_result_t gate_ui_icon_create_file(gate_ui_icon_t* icon, gate_ui_host_t* host, gate_string_t const* filepath) |
1855 |
|
|
{ |
1856 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
1857 |
|
|
char file_buffer[GATE_MAX_FILEPATH_LENGTH]; |
1858 |
|
|
GtkWidget* image_widget = NULL; |
1859 |
|
|
gint pix_size = 0; |
1860 |
|
|
gate_uint32_t flags = 0; |
1861 |
|
|
|
1862 |
|
|
GATE_STRING_TO_BUFFER(filepath, file_buffer); |
1863 |
|
|
image_widget = gtk_image_new_from_file(file_buffer); |
1864 |
|
|
if (image_widget != NULL) |
1865 |
|
|
{ |
1866 |
|
|
pix_size = gtk_image_get_pixel_size(GTK_IMAGE(image_widget)); |
1867 |
|
|
if (pix_size < 24) flags |= GATE_UI_ICON_FLAG_SMALL; |
1868 |
|
|
if (pix_size > 40) flags |= GATE_UI_ICON_FLAG_LARGE; |
1869 |
|
|
ret = gate_ui_icon_create_native(icon, host, image_widget, flags); |
1870 |
|
|
if (GATE_FAILED(ret)) |
1871 |
|
|
{ |
1872 |
|
|
gtk_widget_destroy(image_widget); |
1873 |
|
|
} |
1874 |
|
|
} |
1875 |
|
|
return ret; |
1876 |
|
|
} |
1877 |
|
|
gate_result_t gate_ui_icon_copy(gate_ui_icon_t* dsticon, gate_ui_icon_t const* srcicon) |
1878 |
|
|
{ |
1879 |
|
|
gate_mem_copy(dsticon, srcicon, sizeof(gate_ui_icon_t)); |
1880 |
|
|
if (!GATE_FLAG_ENABLED(srcicon->flags, GATE_UI_ICON_FLAG_STOCK)) |
1881 |
|
|
{ |
1882 |
|
|
if (srcicon->resources[0]) |
1883 |
|
|
{ |
1884 |
|
|
dsticon->resources[0] = g_object_ref((gpointer)srcicon->resources[0]); |
1885 |
|
|
} |
1886 |
|
|
} |
1887 |
|
|
return GATE_RESULT_OK; |
1888 |
|
|
} |
1889 |
|
|
gate_result_t gate_ui_icon_destroy(gate_ui_icon_t* icon) |
1890 |
|
|
{ |
1891 |
|
|
if (icon->resources[0]) |
1892 |
|
|
{ |
1893 |
|
|
g_object_unref((gpointer)icon->resources[0]); |
1894 |
|
|
} |
1895 |
|
|
gate_mem_clear(icon, sizeof(gate_ui_icon_t)); |
1896 |
|
|
return GATE_RESULT_OK; |
1897 |
|
|
} |
1898 |
|
|
|
1899 |
|
|
|
1900 |
|
|
|
1901 |
|
|
|
1902 |
|
|
|
1903 |
|
|
/**************** |
1904 |
|
|
* iconlist GTK * |
1905 |
|
|
****************/ |
1906 |
|
|
|
1907 |
|
|
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) |
1908 |
|
|
{ |
1909 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
1910 |
|
|
do |
1911 |
|
|
{ |
1912 |
|
|
gate_mem_clear(ilst, sizeof(gate_ui_iconlist_t)); |
1913 |
|
|
ilst->resources[0] = gate_arraylist_create(sizeof(gate_ui_icon_t), NULL, 8, NULL, NULL); |
1914 |
|
|
if (NULL == ilst->resources[0]) |
1915 |
|
|
{ |
1916 |
|
|
ret = GATE_RESULT_OUTOFMEMORY; |
1917 |
|
|
break; |
1918 |
|
|
} |
1919 |
|
|
ilst->host = host; |
1920 |
|
|
ilst->width = width; |
1921 |
|
|
ilst->height = height; |
1922 |
|
|
ilst->flags = 0; |
1923 |
|
|
ret = GATE_RESULT_OK; |
1924 |
|
|
} while (0); |
1925 |
|
|
return ret; |
1926 |
|
|
} |
1927 |
|
|
gate_result_t gate_ui_iconlist_destroy(gate_ui_iconlist_t* ilst) |
1928 |
|
|
{ |
1929 |
|
|
gate_result_t ret = GATE_RESULT_OK; |
1930 |
|
|
gate_ui_icon_t* ptr_icon; |
1931 |
|
|
gate_size_t count; |
1932 |
|
|
gate_arraylist_t arr; |
1933 |
|
|
do |
1934 |
|
|
{ |
1935 |
|
|
arr = (gate_arraylist_t)ilst->resources[0]; |
1936 |
|
|
if (!arr) |
1937 |
|
|
{ |
1938 |
|
|
break; |
1939 |
|
|
} |
1940 |
|
|
count = gate_arraylist_length(arr); |
1941 |
|
|
if (count != 0) |
1942 |
|
|
{ |
1943 |
|
|
ptr_icon = gate_arraylist_get(arr, 0); |
1944 |
|
|
while (count-- != 0) |
1945 |
|
|
{ |
1946 |
|
|
gate_ui_icon_destroy(ptr_icon); |
1947 |
|
|
++ptr_icon; |
1948 |
|
|
} |
1949 |
|
|
} |
1950 |
|
|
gate_arraylist_release(arr); |
1951 |
|
|
ret = GATE_RESULT_OK; |
1952 |
|
|
} while (0); |
1953 |
|
|
return ret; |
1954 |
|
|
} |
1955 |
|
|
gate_size_t gate_ui_iconlist_count(gate_ui_iconlist_t* ilst) |
1956 |
|
|
{ |
1957 |
|
|
gate_size_t ret = 0; |
1958 |
|
|
gate_arraylist_t arr = (gate_arraylist_t)ilst->resources[0]; |
1959 |
|
|
if (arr) |
1960 |
|
|
{ |
1961 |
|
|
ret = gate_arraylist_length(arr); |
1962 |
|
|
} |
1963 |
|
|
return ret; |
1964 |
|
|
} |
1965 |
|
|
gate_result_t gate_ui_iconlist_add(gate_ui_iconlist_t* ilst, gate_ui_icon_t const* icon, gate_intptr_t* icon_key) |
1966 |
|
|
{ |
1967 |
|
|
gate_ui_icon_t new_icon = GATE_INIT_EMPTY; |
1968 |
|
|
gate_arraylist_t arr = (gate_arraylist_t)ilst->resources[0]; |
1969 |
|
|
gate_result_t ret = gate_ui_icon_copy(&new_icon, icon); |
1970 |
|
|
gate_size_t index; |
1971 |
|
|
if (GATE_SUCCEEDED(ret)) |
1972 |
|
|
{ |
1973 |
|
|
index = gate_arraylist_length(arr); |
1974 |
|
|
if (NULL == gate_arraylist_add(arr, &new_icon)) |
1975 |
|
|
{ |
1976 |
|
|
ret = GATE_RESULT_OUTOFMEMORY; |
1977 |
|
|
gate_ui_icon_destroy(&new_icon); |
1978 |
|
|
} |
1979 |
|
|
else |
1980 |
|
|
{ |
1981 |
|
|
if (icon_key) |
1982 |
|
|
{ |
1983 |
|
|
*icon_key = (gate_intptr_t)index; |
1984 |
|
|
} |
1985 |
|
|
} |
1986 |
|
|
} |
1987 |
|
|
return ret; |
1988 |
|
|
} |
1989 |
|
|
gate_result_t gate_ui_iconlist_add_image(gate_ui_iconlist_t* ilst, gate_rasterimage_t const* image, gate_intptr_t* icon_key) |
1990 |
|
|
{ |
1991 |
|
|
gate_ui_icon_t new_icon = GATE_INIT_EMPTY; |
1992 |
|
|
gate_arraylist_t arr = (gate_arraylist_t)ilst->resources[0]; |
1993 |
|
|
gate_result_t ret = gate_ui_icon_create_image(&new_icon, ilst->host, image); |
1994 |
|
|
gate_size_t index; |
1995 |
|
|
if (GATE_SUCCEEDED(ret)) |
1996 |
|
|
{ |
1997 |
|
|
index = gate_arraylist_length(arr); |
1998 |
|
|
if (NULL == gate_arraylist_add(arr, &new_icon)) |
1999 |
|
|
{ |
2000 |
|
|
ret = GATE_RESULT_OUTOFMEMORY; |
2001 |
|
|
gate_ui_icon_destroy(&new_icon); |
2002 |
|
|
} |
2003 |
|
|
else |
2004 |
|
|
{ |
2005 |
|
|
if (icon_key) |
2006 |
|
|
{ |
2007 |
|
|
*icon_key = (gate_intptr_t)index; |
2008 |
|
|
} |
2009 |
|
|
} |
2010 |
|
|
} |
2011 |
|
|
return ret; |
2012 |
|
|
} |
2013 |
|
|
gate_result_t gate_ui_iconlist_get(gate_ui_iconlist_t* ilst, gate_intptr_t icon_key, gate_ui_icon_t* icon) |
2014 |
|
|
{ |
2015 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
2016 |
|
|
gate_ui_icon_t new_icon = GATE_INIT_EMPTY; |
2017 |
|
|
gate_arraylist_t arr = (gate_arraylist_t)ilst->resources[0]; |
2018 |
|
|
gate_ui_icon_t const* ptr_icon = NULL; |
2019 |
|
|
|
2020 |
|
|
ptr_icon = (gate_ui_icon_t const*)gate_arraylist_get(arr, (gate_size_t)icon_key); |
2021 |
|
|
if (NULL == ptr_icon) |
2022 |
|
|
{ |
2023 |
|
|
ret = GATE_RESULT_NOTAVAILABLE; |
2024 |
|
|
} |
2025 |
|
|
else |
2026 |
|
|
{ |
2027 |
|
|
ret = gate_ui_icon_copy(icon, ptr_icon); |
2028 |
|
|
} |
2029 |
|
|
return ret; |
2030 |
|
|
} |
2031 |
|
|
|
2032 |
|
|
|
2033 |
|
|
|
2034 |
|
|
/************** |
2035 |
|
|
* cursor GTK * |
2036 |
|
|
**************/ |
2037 |
|
|
|
2038 |
|
|
gate_result_t gate_ui_cursor_create_stock(gate_ui_cursor_t* cursor, gate_ui_host_t* host, gate_uint32_t stock_id) |
2039 |
|
|
{ |
2040 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
2041 |
|
|
char const* cursor_name = NULL; |
2042 |
|
|
GdkCursor* gdk_cursor = NULL; |
2043 |
|
|
GdkDisplay* display = NULL; |
2044 |
|
|
|
2045 |
|
|
switch (stock_id) |
2046 |
|
|
{ |
2047 |
|
|
case GATE_UI_CURSOR_STOCK_POINTER: cursor_name = "default"; break; |
2048 |
|
|
case GATE_UI_CURSOR_STOCK_BUSY: cursor_name = "wait"; break; |
2049 |
|
|
case GATE_UI_CURSOR_STOCK_STARTING: cursor_name = "progress"; break; |
2050 |
|
|
case GATE_UI_CURSOR_STOCK_HAND: cursor_name = "pointer"; break; |
2051 |
|
|
case GATE_UI_CURSOR_STOCK_TEXT: cursor_name = "text"; break; |
2052 |
|
|
case GATE_UI_CURSOR_STOCK_REJECTED: cursor_name = "not-allowed"; break; |
2053 |
|
|
case GATE_UI_CURSOR_STOCK_SIZE_ALL: cursor_name = "all-scroll"; break; |
2054 |
|
|
case GATE_UI_CURSOR_STOCK_SIZE_LEFTRIGHT: cursor_name = "ew-resize"; break; |
2055 |
|
|
case GATE_UI_CURSOR_STOCK_SIZE_UPDOWN: cursor_name = "ns-resize"; break; |
2056 |
|
|
case GATE_UI_CURSOR_STOCK_SIZE_LEFTUPRIGHTDOWN: cursor_name = "nwse-resize"; break; |
2057 |
|
|
case GATE_UI_CURSOR_STOCK_SIZE_RIGHTUPKEFTDOWN: cursor_name = "nesw-resize"; break; |
2058 |
|
|
} |
2059 |
|
|
if (cursor_name == NULL) |
2060 |
|
|
{ |
2061 |
|
|
ret = GATE_RESULT_NOTSUPPORTED; |
2062 |
|
|
} |
2063 |
|
|
else |
2064 |
|
|
{ |
2065 |
|
|
gdk_cursor = gdk_cursor_new_from_name(display, cursor_name); |
2066 |
|
|
if (NULL == gdk_cursor) |
2067 |
|
|
{ |
2068 |
|
|
ret = GATE_RESULT_FAILED; |
2069 |
|
|
} |
2070 |
|
|
else |
2071 |
|
|
{ |
2072 |
|
|
cursor->resources[0] = gdk_cursor; |
2073 |
|
|
cursor->resources[1] = display; |
2074 |
|
|
cursor->host = host; |
2075 |
|
|
cursor->flags = GATE_UI_CURSOR_FLAG_STOCK; |
2076 |
|
|
ret = GATE_RESULT_OK; |
2077 |
|
|
} |
2078 |
|
|
} |
2079 |
|
|
return ret; |
2080 |
|
|
} |
2081 |
|
|
gate_result_t gate_ui_cursor_create_native(gate_ui_cursor_t* cursor, gate_ui_host_t* host, void* handle, gate_uint32_t flags) |
2082 |
|
|
{ |
2083 |
|
|
cursor->resources[0] = handle; |
2084 |
|
|
cursor->resources[1] = gdk_cursor_get_image((GdkCursor*)handle); |
2085 |
|
|
cursor->host = host; |
2086 |
|
|
cursor->flags = flags; |
2087 |
|
|
return GATE_RESULT_OK; |
2088 |
|
|
} |
2089 |
|
|
gate_result_t gate_ui_cursor_create_image(gate_ui_cursor_t* cursor, gate_ui_host_t* host, gate_rasterimage_t const* image, |
2090 |
|
|
gate_uint16_t x, gate_uint16_t y) |
2091 |
|
|
{ |
2092 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
2093 |
|
|
} |
2094 |
|
|
gate_result_t gate_ui_cursor_create_file(gate_ui_cursor_t* cursor, gate_ui_host_t* host, gate_string_t const* filepath) |
2095 |
|
|
{ |
2096 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
2097 |
|
|
} |
2098 |
|
|
gate_result_t gate_ui_cursor_copy(gate_ui_cursor_t* dstcursor, gate_ui_cursor_t const* srccursor) |
2099 |
|
|
{ |
2100 |
|
|
GdkCursor* gdk_src_cursor = (GdkCursor*)dstcursor->resources[0]; |
2101 |
|
|
GdkCursor* gdk_dst_cursor = gdk_cursor_new_from_pixbuf((GdkDisplay*)srccursor->resources[1], gdk_cursor_get_image(gdk_src_cursor), -1, -1); |
2102 |
|
|
if (gdk_dst_cursor) |
2103 |
|
|
{ |
2104 |
|
|
dstcursor->resources[0] = gdk_dst_cursor; |
2105 |
|
|
dstcursor->resources[1] = srccursor->resources[1]; |
2106 |
|
|
dstcursor->host = srccursor->host; |
2107 |
|
|
dstcursor->flags = srccursor->flags; |
2108 |
|
|
return GATE_RESULT_OK; |
2109 |
|
|
} |
2110 |
|
|
else |
2111 |
|
|
{ |
2112 |
|
|
return GATE_RESULT_FAILED; |
2113 |
|
|
} |
2114 |
|
|
} |
2115 |
|
|
gate_result_t gate_ui_cursor_destroy(gate_ui_cursor_t* cursor) |
2116 |
|
|
{ |
2117 |
|
|
GdkCursor* gdk_cursor = (GdkCursor*)cursor->resources[0]; |
2118 |
|
|
if (gdk_cursor) |
2119 |
|
|
{ |
2120 |
|
|
g_object_unref(gdk_cursor); |
2121 |
|
|
} |
2122 |
|
|
gate_mem_clear(cursor, sizeof(gate_ui_cursor_t)); |
2123 |
|
|
return GATE_RESULT_OK; |
2124 |
|
|
} |
2125 |
|
|
|
2126 |
|
|
#endif /* GATE_UI_GTK */ |
2127 |
|
|
|
2128 |
|
|
|
2129 |
|
|
|
2130 |
|
|
#if defined(GATE_UI_MOTIF) |
2131 |
|
|
|
2132 |
|
|
#include "gate/ui/gateui_motif.h" |
2133 |
|
|
|
2134 |
|
✗ |
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) |
2135 |
|
|
{ |
2136 |
|
✗ |
return gate_ui_graphics_create_image(graph, host, width, height, 0); |
2137 |
|
|
} |
2138 |
|
✗ |
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) |
2139 |
|
|
{ |
2140 |
|
✗ |
gate_result_t ret = GATE_RESULT_FAILED; |
2141 |
|
|
Display* display; |
2142 |
|
|
int screen; |
2143 |
|
|
int xdepth; |
2144 |
|
|
Window root_window; |
2145 |
|
|
Pixmap pixmap; |
2146 |
|
|
GC context; |
2147 |
|
|
|
2148 |
|
|
do |
2149 |
|
|
{ |
2150 |
|
✗ |
gate_mem_clear(graph, sizeof(gate_ui_graphics_t)); |
2151 |
|
|
|
2152 |
|
✗ |
display = GATE_UI_MOTIF_GET_HOST_DISPLAY(host); |
2153 |
|
✗ |
screen = XDefaultScreen(display); |
2154 |
|
✗ |
xdepth = (depth == 0) ? XDefaultDepth(display, screen) : depth; |
2155 |
|
✗ |
root_window = XDefaultRootWindow(display); |
2156 |
|
✗ |
pixmap = XCreatePixmap(display, root_window, width, height, xdepth); |
2157 |
|
✗ |
context = XCreateGC(display, root_window, 0, 0); |
2158 |
|
✗ |
XFillRectangle(display, pixmap, context, 0, 0, width, height); |
2159 |
|
|
|
2160 |
|
✗ |
graph->host = host; |
2161 |
|
✗ |
graph->resources[0] = (void*)context; |
2162 |
|
✗ |
graph->resources[1] = (void*)(Drawable)pixmap; |
2163 |
|
✗ |
graph->width = width; |
2164 |
|
✗ |
graph->height = height; |
2165 |
|
|
|
2166 |
|
✗ |
XSetGraphicsExposures(display, context, 0); |
2167 |
|
✗ |
ret = GATE_RESULT_OK; |
2168 |
|
|
} while (0); |
2169 |
|
✗ |
return ret; |
2170 |
|
|
} |
2171 |
|
✗ |
gate_result_t gate_ui_graphics_create_image_from(gate_ui_graphics_t* graph, gate_ui_host_t* host, gate_rasterimage_t const* rasterimage) |
2172 |
|
|
{ |
2173 |
|
|
gate_result_t ret; |
2174 |
|
|
gate_ui_position_t pos; |
2175 |
|
|
|
2176 |
|
|
do |
2177 |
|
|
{ |
2178 |
|
✗ |
ret = gate_ui_graphics_create_image(graph, host, rasterimage->width, rasterimage->height, 0); |
2179 |
|
✗ |
GATE_BREAK_IF_FAILED(ret); |
2180 |
|
|
|
2181 |
|
✗ |
ret = gate_ui_graphics_draw_image(graph, rasterimage, NULL, NULL, NULL); |
2182 |
|
✗ |
if (GATE_FAILED(ret)) |
2183 |
|
|
{ |
2184 |
|
✗ |
gate_ui_graphics_destroy(graph); |
2185 |
|
✗ |
break; |
2186 |
|
|
} |
2187 |
|
|
|
2188 |
|
✗ |
ret = GATE_RESULT_OK; |
2189 |
|
|
} while (0); |
2190 |
|
|
|
2191 |
|
✗ |
return ret; |
2192 |
|
|
} |
2193 |
|
✗ |
gate_result_t gate_ui_graphics_create_ctrl(gate_ui_graphics_t* graph, gate_ui_ctrl_t* ctrl) |
2194 |
|
|
{ |
2195 |
|
✗ |
gate_result_t ret = GATE_RESULT_FAILED; |
2196 |
|
✗ |
gate_ui_host_t* host = GATE_UI_MOTIF_GET_CTRL_HOST(ctrl); |
2197 |
|
✗ |
Display* display = GATE_UI_MOTIF_GET_HOST_DISPLAY(host); |
2198 |
|
✗ |
Widget w = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl); |
2199 |
|
✗ |
Window wnd = XtWindow(w); |
2200 |
|
|
GC context; |
2201 |
|
✗ |
Dimension xwidth = 0, xheight = 0; |
2202 |
|
|
do |
2203 |
|
|
{ |
2204 |
|
✗ |
context = XCreateGC(display, wnd, 0, NULL); |
2205 |
|
✗ |
if (!context) |
2206 |
|
|
{ |
2207 |
|
✗ |
ret = GATE_RESULT_OUTOFRESOURCES; |
2208 |
|
✗ |
break; |
2209 |
|
|
} |
2210 |
|
✗ |
XtVaGetValues(w, XtNwidth, &xwidth, XtNheight, &xheight, NULL, NULL); |
2211 |
|
|
|
2212 |
|
✗ |
graph->host = host; |
2213 |
|
✗ |
graph->resources[0] = (void*)context; |
2214 |
|
✗ |
graph->resources[1] = (void*)(Drawable)wnd; |
2215 |
|
✗ |
graph->resources[2] = (void*)wnd; |
2216 |
|
✗ |
graph->width = xwidth; |
2217 |
|
✗ |
graph->height = xheight; |
2218 |
|
|
|
2219 |
|
✗ |
XSetGraphicsExposures(display, context, 0); |
2220 |
|
✗ |
ret = GATE_RESULT_OK; |
2221 |
|
|
} while (0); |
2222 |
|
✗ |
return ret; |
2223 |
|
|
} |
2224 |
|
✗ |
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) |
2225 |
|
|
{ |
2226 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2227 |
|
|
} |
2228 |
|
✗ |
gate_result_t gate_ui_graphics_destroy(gate_ui_graphics_t* graph) |
2229 |
|
|
{ |
2230 |
|
✗ |
Display* display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host); |
2231 |
|
✗ |
GC context = (GC)graph->resources[0]; |
2232 |
|
✗ |
Drawable drawable = (Drawable)graph->resources[1]; |
2233 |
|
✗ |
Window window = (Window)graph->resources[2]; |
2234 |
|
|
|
2235 |
|
✗ |
if (display) |
2236 |
|
|
{ |
2237 |
|
✗ |
if (window == 0) |
2238 |
|
|
{ |
2239 |
|
|
/* no window, expect a Pixmap surface */ |
2240 |
|
✗ |
if (drawable != 0) |
2241 |
|
|
{ |
2242 |
|
✗ |
XFreePixmap(display, (Pixmap)drawable); |
2243 |
|
|
} |
2244 |
|
|
} |
2245 |
|
|
else |
2246 |
|
|
{ |
2247 |
|
|
} |
2248 |
|
|
|
2249 |
|
✗ |
if (context) |
2250 |
|
|
{ |
2251 |
|
✗ |
XFreeGC(display, context); |
2252 |
|
|
} |
2253 |
|
|
} |
2254 |
|
|
|
2255 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2256 |
|
|
} |
2257 |
|
|
|
2258 |
|
✗ |
static unsigned long XGetRgbPixel(Display* display, gate_uint8_t r, gate_uint8_t g, gate_uint8_t b) |
2259 |
|
|
{ |
2260 |
|
✗ |
int screen = XDefaultScreen(display); |
2261 |
|
✗ |
Colormap cmap = XDefaultColormap(display, screen); |
2262 |
|
|
XColor col; |
2263 |
|
✗ |
col.pixel = 0; |
2264 |
|
✗ |
col.red = ((gate_uint16_t)r) << 8; |
2265 |
|
✗ |
col.green = ((gate_uint16_t)g) << 8; |
2266 |
|
✗ |
col.blue = ((gate_uint16_t)b) << 8; |
2267 |
|
✗ |
col.flags = DoRed | DoGreen | DoBlue; |
2268 |
|
✗ |
XAllocColor(display, cmap, &col); |
2269 |
|
✗ |
return col.pixel; |
2270 |
|
|
} |
2271 |
|
|
|
2272 |
|
✗ |
gate_int32_t gate_ui_graphics_width(gate_ui_graphics_t* graph) |
2273 |
|
|
{ |
2274 |
|
✗ |
return graph->width; |
2275 |
|
|
} |
2276 |
|
|
|
2277 |
|
✗ |
gate_int32_t gate_ui_graphics_height(gate_ui_graphics_t* graph) |
2278 |
|
|
{ |
2279 |
|
✗ |
return graph->height; |
2280 |
|
|
} |
2281 |
|
|
|
2282 |
|
✗ |
gate_result_t gate_ui_graphics_set_pixel(gate_ui_graphics_t* graph, gate_ui_point_t pos, gate_ui_color_t col) |
2283 |
|
|
{ |
2284 |
|
✗ |
Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host); |
2285 |
|
✗ |
GC const context = (GC)graph->resources[0]; |
2286 |
|
✗ |
Drawable const drawable = (Drawable)graph->resources[1]; |
2287 |
|
|
|
2288 |
|
✗ |
XSetForeground(display, context, XGetRgbPixel(display, col.r, col.g, col.b)); |
2289 |
|
✗ |
XDrawPoint(display, drawable, context, pos.x, pos.y); |
2290 |
|
✗ |
return GATE_RESULT_OK; |
2291 |
|
|
} |
2292 |
|
|
|
2293 |
|
✗ |
gate_result_t gate_ui_graphics_get_pixel(gate_ui_graphics_t* graph, gate_ui_point_t pos, gate_ui_color_t* col) |
2294 |
|
|
{ |
2295 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2296 |
|
|
} |
2297 |
|
|
|
2298 |
|
✗ |
gate_result_t gate_ui_graphics_draw(gate_ui_graphics_t* graph, gate_ui_graphics_t* srcgraph, |
2299 |
|
|
gate_ui_point_t const* dst, gate_ui_size_t const* size, gate_ui_point_t const* srcpos) |
2300 |
|
|
{ |
2301 |
|
✗ |
Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host); |
2302 |
|
✗ |
GC const context = (GC)graph->resources[0]; |
2303 |
|
✗ |
Drawable const target = (Drawable)graph->resources[1]; |
2304 |
|
✗ |
Drawable const source = (Drawable)srcgraph->resources[1]; |
2305 |
|
|
int src_x, src_y, width, height, dst_x, dst_y; |
2306 |
|
✗ |
dst_x = dst->x; |
2307 |
|
✗ |
dst_y = dst->y; |
2308 |
|
✗ |
src_x = srcpos->x; |
2309 |
|
✗ |
src_y = srcpos->y; |
2310 |
|
✗ |
width = size->width; |
2311 |
|
✗ |
height = size->height; |
2312 |
|
|
|
2313 |
|
✗ |
XCopyArea(display, source, target, context, src_x, src_y, width, height, dst_x, dst_y); |
2314 |
|
✗ |
return GATE_RESULT_OK; |
2315 |
|
|
} |
2316 |
|
|
|
2317 |
|
✗ |
gate_result_t gate_ui_graphics_draw_ex(gate_ui_graphics_t* graph, gate_ui_graphics_t* src_graph, |
2318 |
|
|
gate_ui_position_t const* dest_rect, gate_ui_position_t const* src_rect) |
2319 |
|
|
{ |
2320 |
|
✗ |
Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host); |
2321 |
|
✗ |
GC const context = (GC)graph->resources[0]; |
2322 |
|
✗ |
Drawable const target = (Drawable)graph->resources[1]; |
2323 |
|
✗ |
Drawable const source = (Drawable)src_graph->resources[1]; |
2324 |
|
|
int src_x, src_y, width, height, dst_x, dst_y; |
2325 |
|
✗ |
dst_x = dest_rect->pos.x; |
2326 |
|
✗ |
dst_y = dest_rect->pos.y; |
2327 |
|
✗ |
src_x = src_rect->pos.x; |
2328 |
|
✗ |
src_y = src_rect->pos.y; |
2329 |
|
|
/* TODO */ |
2330 |
|
✗ |
width = dest_rect->size.width; |
2331 |
|
✗ |
height = dest_rect->size.height; |
2332 |
|
|
|
2333 |
|
✗ |
XCopyArea(display, source, target, context, src_x, src_y, width, height, dst_x, dst_y); |
2334 |
|
✗ |
return GATE_RESULT_OK; |
2335 |
|
|
} |
2336 |
|
|
|
2337 |
|
✗ |
gate_result_t gate_ui_graphics_draw_image(gate_ui_graphics_t* graph, gate_rasterimage_t const* srcimage, |
2338 |
|
|
gate_ui_point_t const* dst, gate_ui_size_t const* size, gate_ui_point_t const* srcpos) |
2339 |
|
|
{ |
2340 |
|
✗ |
Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host); |
2341 |
|
✗ |
GC const context = (GC)graph->resources[0]; |
2342 |
|
✗ |
Drawable const drawable = (Drawable)graph->resources[1]; |
2343 |
|
|
|
2344 |
|
|
gate_color_t pixel; |
2345 |
|
✗ |
gate_uint32_t pixel_cache = 0; |
2346 |
|
✗ |
unsigned long x11_color = 0; |
2347 |
|
|
int src_x, src_y, width, height, dst_x, dst_y; |
2348 |
|
|
int x, y; |
2349 |
|
|
|
2350 |
|
✗ |
if (srcpos) |
2351 |
|
|
{ |
2352 |
|
✗ |
src_x = srcpos->x; |
2353 |
|
✗ |
src_y = srcpos->y; |
2354 |
|
|
} |
2355 |
|
|
else |
2356 |
|
|
{ |
2357 |
|
✗ |
src_x = 0; |
2358 |
|
✗ |
src_y = 0; |
2359 |
|
|
} |
2360 |
|
✗ |
if (size) |
2361 |
|
|
{ |
2362 |
|
✗ |
width = size->width; |
2363 |
|
✗ |
height = size->height; |
2364 |
|
|
} |
2365 |
|
|
else |
2366 |
|
|
{ |
2367 |
|
✗ |
width = srcimage->width; |
2368 |
|
✗ |
height = srcimage->height; |
2369 |
|
|
} |
2370 |
|
✗ |
if (dst) |
2371 |
|
|
{ |
2372 |
|
✗ |
dst_x = dst->x; |
2373 |
|
✗ |
dst_y = dst->y; |
2374 |
|
|
} |
2375 |
|
|
else |
2376 |
|
|
{ |
2377 |
|
✗ |
dst_x = 0; |
2378 |
|
✗ |
dst_y = 0; |
2379 |
|
|
} |
2380 |
|
|
|
2381 |
|
✗ |
for (y = 0; y != height; ++y) |
2382 |
|
|
{ |
2383 |
|
✗ |
for (x = 0; x != width; ++x) |
2384 |
|
|
{ |
2385 |
|
✗ |
gate_rasterimage_get_pixel(srcimage, src_x + x, src_y + y, &pixel); |
2386 |
|
✗ |
if (pixel.a > 127) |
2387 |
|
|
{ |
2388 |
|
✗ |
if (pixel.rgba != pixel_cache) |
2389 |
|
|
{ |
2390 |
|
✗ |
x11_color = XGetRgbPixel(display, pixel.r, pixel.g, pixel.b); |
2391 |
|
✗ |
pixel_cache = pixel.rgba; |
2392 |
|
✗ |
XSetForeground(display, context, x11_color); |
2393 |
|
|
} |
2394 |
|
✗ |
XDrawPoint(display, drawable, context, dst_x + x, dst_y + y); |
2395 |
|
|
} |
2396 |
|
|
} |
2397 |
|
|
} |
2398 |
|
✗ |
return GATE_RESULT_OK; |
2399 |
|
|
} |
2400 |
|
|
|
2401 |
|
✗ |
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) |
2402 |
|
|
{ |
2403 |
|
✗ |
Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host); |
2404 |
|
✗ |
GC const context = (GC)graph->resources[0]; |
2405 |
|
✗ |
Drawable const drawable = (Drawable)graph->resources[1]; |
2406 |
|
|
|
2407 |
|
✗ |
XSetForeground(display, context, XGetRgbPixel(display, col.r, col.g, col.b)); |
2408 |
|
✗ |
XDrawLine(display, drawable, context, from.x, from.y, to.x, to.y); |
2409 |
|
✗ |
return GATE_RESULT_OK; |
2410 |
|
|
} |
2411 |
|
|
|
2412 |
|
✗ |
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) |
2413 |
|
|
{ |
2414 |
|
✗ |
Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host); |
2415 |
|
✗ |
GC const context = (GC)graph->resources[0]; |
2416 |
|
✗ |
Drawable const drawable = (Drawable)graph->resources[1]; |
2417 |
|
|
unsigned long pixel; |
2418 |
|
|
|
2419 |
|
✗ |
if (colfill) |
2420 |
|
|
{ |
2421 |
|
✗ |
pixel = XGetRgbPixel(display, colfill->r, colfill->g, colfill->b); |
2422 |
|
✗ |
XSetForeground(display, context, pixel); |
2423 |
|
✗ |
XFillRectangle(display, drawable, context, rect.pos.x, rect.pos.y, rect.size.width, rect.size.height); |
2424 |
|
|
} |
2425 |
|
|
|
2426 |
|
✗ |
if (colline) |
2427 |
|
|
{ |
2428 |
|
✗ |
pixel = XGetRgbPixel(display, colline->r, colline->g, colline->b); |
2429 |
|
✗ |
XSetForeground(display, context, pixel); |
2430 |
|
✗ |
XDrawRectangle(display, drawable, context, rect.pos.x, rect.pos.y, rect.size.width, rect.size.height); |
2431 |
|
|
} |
2432 |
|
✗ |
return GATE_RESULT_OK; |
2433 |
|
|
} |
2434 |
|
|
|
2435 |
|
✗ |
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) |
2436 |
|
|
{ |
2437 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2438 |
|
|
} |
2439 |
|
|
|
2440 |
|
✗ |
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) |
2441 |
|
|
{ |
2442 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2443 |
|
|
} |
2444 |
|
✗ |
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) |
2445 |
|
|
{ |
2446 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2447 |
|
|
} |
2448 |
|
|
|
2449 |
|
✗ |
static void print_font_name(char* name_buffer, gate_size_t name_capacity, gate_ui_font_t const* font) |
2450 |
|
|
{ |
2451 |
|
|
gate_strbuilder_t builder; |
2452 |
|
|
|
2453 |
|
✗ |
gate_strbuilder_create_static(&builder, name_buffer, name_capacity, 0); |
2454 |
|
✗ |
gate_strbuilder_append_cstr(&builder, "-"); |
2455 |
|
✗ |
gate_strbuilder_append_cstr(&builder, font->font_name); |
2456 |
|
✗ |
gate_strbuilder_append_cstr(&builder, font->bold ? "-bold" : "-medium"); |
2457 |
|
✗ |
gate_strbuilder_append_cstr(&builder, font->italic ? "-i" : "-r"); |
2458 |
|
✗ |
gate_strbuilder_append_cstr(&builder, "-*-"); |
2459 |
|
✗ |
gate_strbuilder_append_int32(&builder, font->size); |
2460 |
|
✗ |
gate_strbuilder_append_cstr(&builder, "-*"); |
2461 |
|
✗ |
} |
2462 |
|
|
|
2463 |
|
✗ |
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) |
2464 |
|
|
{ |
2465 |
|
✗ |
Display* const display = GATE_UI_MOTIF_GET_HOST_DISPLAY(graph->host); |
2466 |
|
✗ |
GC const context = (GC)graph->resources[0]; |
2467 |
|
✗ |
Drawable const drawable = (Drawable)graph->resources[1]; |
2468 |
|
|
|
2469 |
|
|
char font_name[256]; |
2470 |
|
|
Font xfont; |
2471 |
|
|
XFontStruct* fontstruct; |
2472 |
|
|
|
2473 |
|
✗ |
print_font_name(font_name, sizeof(font_name), font); |
2474 |
|
✗ |
xfont = XLoadFont(display, font_name); |
2475 |
|
✗ |
XSetForeground(display, context, XGetRgbPixel(display, font->color.r, font->color.g, font->color.b)); |
2476 |
|
✗ |
XSetFont(display, context, xfont); |
2477 |
|
✗ |
fontstruct = XQueryFont(display, xfont); |
2478 |
|
✗ |
XDrawString(display, drawable, context, pos->pos.x, pos->pos.y + fontstruct->ascent, text->str, text->length); |
2479 |
|
✗ |
XFreeFontInfo(NULL, fontstruct, 1); |
2480 |
|
✗ |
XUnloadFont(display, xfont); |
2481 |
|
✗ |
return GATE_RESULT_OK; |
2482 |
|
|
} |
2483 |
|
|
|
2484 |
|
✗ |
void* gate_ui_graphics_handle(gate_ui_graphics_t* graph) |
2485 |
|
|
{ |
2486 |
|
✗ |
return graph->resources[0]; |
2487 |
|
|
} |
2488 |
|
✗ |
void* gate_ui_graphics_surface(gate_ui_graphics_t* graph) |
2489 |
|
|
{ |
2490 |
|
✗ |
return graph->resources[1]; |
2491 |
|
|
} |
2492 |
|
|
|
2493 |
|
|
|
2494 |
|
|
|
2495 |
|
|
|
2496 |
|
✗ |
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) |
2497 |
|
|
{ |
2498 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2499 |
|
|
} |
2500 |
|
✗ |
gate_result_t gate_ui_icon_create_native(gate_ui_icon_t* icon, gate_ui_host_t* host, void* handle, gate_uint32_t flags) |
2501 |
|
|
{ |
2502 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2503 |
|
|
} |
2504 |
|
✗ |
gate_result_t gate_ui_icon_create_image(gate_ui_icon_t* icon, gate_ui_host_t* host, gate_rasterimage_t const* image) |
2505 |
|
|
{ |
2506 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2507 |
|
|
} |
2508 |
|
✗ |
gate_result_t gate_ui_icon_create_file(gate_ui_icon_t* icon, gate_ui_host_t* host, gate_string_t const* filepath) |
2509 |
|
|
{ |
2510 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2511 |
|
|
} |
2512 |
|
✗ |
gate_result_t gate_ui_icon_copy(gate_ui_icon_t* dsticon, gate_ui_icon_t const* srcicon) |
2513 |
|
|
{ |
2514 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2515 |
|
|
} |
2516 |
|
✗ |
gate_result_t gate_ui_icon_destroy(gate_ui_icon_t* icon) |
2517 |
|
|
{ |
2518 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2519 |
|
|
} |
2520 |
|
|
|
2521 |
|
|
|
2522 |
|
|
|
2523 |
|
✗ |
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) |
2524 |
|
|
{ |
2525 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2526 |
|
|
} |
2527 |
|
✗ |
gate_result_t gate_ui_iconlist_destroy(gate_ui_iconlist_t* ilst) |
2528 |
|
|
{ |
2529 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2530 |
|
|
} |
2531 |
|
✗ |
gate_size_t gate_ui_iconlist_count(gate_ui_iconlist_t* ilst) |
2532 |
|
|
{ |
2533 |
|
✗ |
return 0; |
2534 |
|
|
} |
2535 |
|
✗ |
gate_result_t gate_ui_iconlist_add(gate_ui_iconlist_t* ilst, gate_ui_icon_t const* icon, gate_intptr_t* icon_key) |
2536 |
|
|
{ |
2537 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2538 |
|
|
} |
2539 |
|
✗ |
gate_result_t gate_ui_iconlist_add_image(gate_ui_iconlist_t* ilst, gate_rasterimage_t const* image, gate_intptr_t* icon_key) |
2540 |
|
|
{ |
2541 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2542 |
|
|
} |
2543 |
|
✗ |
gate_result_t gate_ui_iconlist_get(gate_ui_iconlist_t* ilst, gate_intptr_t icon_key, gate_ui_icon_t* icon) |
2544 |
|
|
{ |
2545 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2546 |
|
|
} |
2547 |
|
|
|
2548 |
|
|
|
2549 |
|
|
|
2550 |
|
|
|
2551 |
|
|
|
2552 |
|
✗ |
gate_result_t gate_ui_cursor_create_stock(gate_ui_cursor_t* cursor, gate_ui_host_t* host, gate_uint32_t stock_id) |
2553 |
|
|
{ |
2554 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2555 |
|
|
} |
2556 |
|
✗ |
gate_result_t gate_ui_cursor_create_native(gate_ui_cursor_t* cursor, gate_ui_host_t* host, void* handle, gate_uint32_t flags) |
2557 |
|
|
{ |
2558 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2559 |
|
|
} |
2560 |
|
✗ |
gate_result_t gate_ui_cursor_create_image(gate_ui_cursor_t* cursor, gate_ui_host_t* host, gate_rasterimage_t const* image, |
2561 |
|
|
gate_uint16_t x, gate_uint16_t y) |
2562 |
|
|
{ |
2563 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2564 |
|
|
} |
2565 |
|
✗ |
gate_result_t gate_ui_cursor_create_file(gate_ui_cursor_t* cursor, gate_ui_host_t* host, gate_string_t const* filepath) |
2566 |
|
|
{ |
2567 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2568 |
|
|
} |
2569 |
|
✗ |
gate_result_t gate_ui_cursor_copy(gate_ui_cursor_t* dstcursor, gate_ui_cursor_t const* srccursor) |
2570 |
|
|
{ |
2571 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2572 |
|
|
} |
2573 |
|
✗ |
gate_result_t gate_ui_cursor_destroy(gate_ui_cursor_t* cursor) |
2574 |
|
|
{ |
2575 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
2576 |
|
|
} |
2577 |
|
|
|
2578 |
|
|
|
2579 |
|
|
#endif /* GATE_UI_MOTIF */ |
2580 |
|
|
|