1 /*
2 * Copyright (C) 2000-2019 the xine project
3 *
4 * This file is part of xine, a unix video player.
5 *
6 * xine is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * xine is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 *
20 */
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <stdio.h>
26
27 #include "_xitk.h"
28
29 /*
30 *
31 */
notify_destroy(xitk_widget_t * w)32 static void notify_destroy(xitk_widget_t *w) {
33 checkbox_private_data_t *private_data;
34
35 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_CHECKBOX)) {
36 private_data = (checkbox_private_data_t *) w->private_data;
37
38 if(!private_data->skin_element_name)
39 xitk_image_free_image(private_data->imlibdata, &(private_data->skin));
40
41 XITK_FREE(private_data->skin_element_name);
42 XITK_FREE(private_data);
43 }
44 }
45
46 /*
47 *
48 */
get_skin(xitk_widget_t * w,int sk)49 static xitk_image_t *get_skin(xitk_widget_t *w, int sk) {
50 checkbox_private_data_t *private_data;
51
52 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_CHECKBOX)) {
53 private_data = (checkbox_private_data_t *) w->private_data;
54
55 if(sk == FOREGROUND_SKIN && private_data->skin) {
56 return private_data->skin;
57 }
58 }
59
60 return NULL;
61 }
62
63 /*
64 *
65 */
notify_inside(xitk_widget_t * w,int x,int y)66 static int notify_inside(xitk_widget_t *w, int x, int y) {
67 checkbox_private_data_t *private_data;
68
69 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_CHECKBOX)) {
70 private_data = (checkbox_private_data_t *) w->private_data;
71
72 if(w->visible == 1) {
73 xitk_image_t *skin = private_data->skin;
74
75 if(skin->mask)
76 return xitk_is_cursor_out_mask(private_data->imlibdata->x.disp, w, skin->mask->pixmap, x, y);
77 }
78 else
79 return 0;
80 }
81
82 return 1;
83 }
84
85 /*
86 *
87 */
paint_checkbox(xitk_widget_t * w)88 static void paint_checkbox (xitk_widget_t *w) {
89 checkbox_private_data_t *private_data;
90 GC lgc;
91 int checkbox_width;
92 xitk_image_t *skin;
93
94 if(w && (((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_CHECKBOX) && w->visible == 1)) {
95 private_data = (checkbox_private_data_t *) w->private_data;
96
97 skin = private_data->skin;
98 checkbox_width = skin->width / 3;
99
100 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
101 lgc = XCreateGC(private_data->imlibdata->x.disp, w->wl->win, None, None);
102 XCopyGC(private_data->imlibdata->x.disp, w->wl->gc, (1 << GCLastBit) - 1, lgc);
103 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
104
105 if (skin->mask) {
106 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
107 XSetClipOrigin(private_data->imlibdata->x.disp, lgc, w->x, w->y);
108 XSetClipMask(private_data->imlibdata->x.disp, lgc, skin->mask->pixmap);
109 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
110 }
111
112 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
113 if ((private_data->focus == FOCUS_RECEIVED) || (private_data->focus == FOCUS_MOUSE_IN)) {
114 if (private_data->cClicked || private_data->cState) { // focused, clicked or checked
115 XCopyArea (private_data->imlibdata->x.disp, skin->image->pixmap,
116 w->wl->win, lgc, 2*checkbox_width, 0,
117 checkbox_width, skin->height, w->x, w->y);
118 }
119 else { // focused, unchecked
120 XCopyArea (private_data->imlibdata->x.disp, skin->image->pixmap,
121 w->wl->win, lgc, checkbox_width, 0,
122 checkbox_width, skin->height, w->x, w->y);
123 }
124 }
125 else {
126 if(private_data->cState) { // unfocused, checked
127 XCopyArea (private_data->imlibdata->x.disp, skin->image->pixmap,
128 w->wl->win, lgc, 2*checkbox_width, 0,
129 checkbox_width, skin->height, w->x, w->y);
130 }
131 else { // unfocused, unchecked
132 XCopyArea (private_data->imlibdata->x.disp, skin->image->pixmap, w->wl->win, lgc, 0, 0,
133 checkbox_width, skin->height, w->x, w->y);
134 }
135 }
136 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
137
138 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
139 XFreeGC(private_data->imlibdata->x.disp, lgc);
140 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
141 }
142
143 }
144
145 /*
146 *
147 */
notify_click_checkbox(xitk_widget_t * w,int button,int cUp,int x,int y)148 static int notify_click_checkbox (xitk_widget_t *w, int button, int cUp, int x, int y) {
149 checkbox_private_data_t *private_data;
150 int ret = 0;
151
152 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_CHECKBOX)) {
153 if(button == Button1) {
154 private_data = (checkbox_private_data_t *) w->private_data;
155
156 private_data->cClicked = !cUp;
157 if (cUp && (private_data->focus == FOCUS_RECEIVED)) {
158 private_data->cState = !private_data->cState;
159
160 if(private_data->callback) {
161 private_data->callback(private_data->cWidget,
162 private_data->userdata,
163 private_data->cState);
164 }
165 }
166
167 paint_checkbox(w);
168 ret = 1;
169 }
170 }
171
172 return ret;
173 }
174
175 /*
176 *
177 */
notify_focus_checkbox(xitk_widget_t * w,int focus)178 static int notify_focus_checkbox (xitk_widget_t *w, int focus) {
179 checkbox_private_data_t *private_data;
180
181 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_CHECKBOX)) {
182 private_data = (checkbox_private_data_t *) w->private_data;
183 private_data->focus = focus;
184 }
185 return 1;
186 }
187
188 /*
189 *
190 */
notify_change_skin(xitk_widget_t * w,xitk_skin_config_t * skonfig)191 static void notify_change_skin(xitk_widget_t *w, xitk_skin_config_t *skonfig) {
192 checkbox_private_data_t *private_data;
193
194 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_CHECKBOX)) {
195 private_data = (checkbox_private_data_t *) w->private_data;
196
197 if(private_data->skin_element_name) {
198 xitk_skin_lock(skonfig);
199 private_data->skin = xitk_skin_get_image(skonfig,
200 xitk_skin_get_skin_filename(skonfig, private_data->skin_element_name));
201 w->x = xitk_skin_get_coord_x(skonfig, private_data->skin_element_name);
202 w->y = xitk_skin_get_coord_y(skonfig, private_data->skin_element_name);
203 w->width = private_data->skin->width/3;
204 w->height = private_data->skin->height;
205 w->visible = (xitk_skin_get_visibility(skonfig, private_data->skin_element_name)) ? 1: -1;
206 w->enable = xitk_skin_get_enability(skonfig, private_data->skin_element_name);
207
208 xitk_skin_unlock(skonfig);
209
210 xitk_set_widget_pos(w, w->x, w->y);
211 }
212 }
213 }
214
notify_event(xitk_widget_t * w,widget_event_t * event,widget_event_result_t * result)215 static int notify_event(xitk_widget_t *w, widget_event_t *event, widget_event_result_t *result) {
216 int retval = 0;
217
218 switch(event->type) {
219 case WIDGET_EVENT_PAINT:
220 paint_checkbox(w);
221 break;
222 case WIDGET_EVENT_CLICK:
223 result->value = notify_click_checkbox(w, event->button,
224 event->button_pressed, event->x, event->y);
225 retval = 1;
226 break;
227 case WIDGET_EVENT_FOCUS:
228 notify_focus_checkbox(w, event->focus);
229 break;
230 case WIDGET_EVENT_INSIDE:
231 result->value = notify_inside(w, event->x, event->y);
232 retval = 1;
233 break;
234 case WIDGET_EVENT_CHANGE_SKIN:
235 notify_change_skin(w, event->skonfig);
236 break;
237 case WIDGET_EVENT_DESTROY:
238 notify_destroy(w);
239 break;
240 case WIDGET_EVENT_GET_SKIN:
241 if(result) {
242 result->image = get_skin(w, event->skin_layer);
243 retval = 1;
244 }
245 break;
246 }
247
248 return retval;
249 }
250
xitk_checkbox_callback_exec(xitk_widget_t * w)251 void xitk_checkbox_callback_exec(xitk_widget_t *w) {
252 checkbox_private_data_t *private_data;
253
254 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_CHECKBOX)) {
255 private_data = (checkbox_private_data_t *) w->private_data;
256
257 if(private_data->callback) {
258 private_data->callback(private_data->cWidget,
259 private_data->userdata,
260 private_data->cState);
261 }
262 }
263 }
264
265 /*
266 *
267 */
xitk_checkbox_get_state(xitk_widget_t * w)268 int xitk_checkbox_get_state(xitk_widget_t *w) {
269 checkbox_private_data_t *private_data;
270
271 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_CHECKBOX)) {
272 private_data = (checkbox_private_data_t *) w->private_data;
273 return private_data->cState;
274 }
275
276 return 0;
277 }
278
279 /*
280 *
281 */
xitk_checkbox_set_state(xitk_widget_t * w,int state)282 void xitk_checkbox_set_state(xitk_widget_t *w, int state) {
283 checkbox_private_data_t *private_data;
284 int clk, focus;
285
286 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_CHECKBOX)) {
287 private_data = (checkbox_private_data_t *) w->private_data;
288
289 if(xitk_checkbox_get_state(w) != state) {
290
291 focus = private_data->focus;
292 clk = private_data->cClicked;
293
294 private_data->focus = FOCUS_RECEIVED;
295 private_data->cClicked = 1;
296 private_data->cState = state;
297
298 paint_checkbox(w);
299
300 private_data->focus = focus;
301 private_data->cClicked = clk;
302
303 paint_checkbox(w);
304 }
305 }
306
307 }
308
309 /*
310 *
311 */
_xitk_checkbox_create(xitk_widget_list_t * wl,xitk_skin_config_t * skonfig,xitk_checkbox_widget_t * cb,int x,int y,const char * skin_element_name,xitk_image_t * skin,int visible,int enable)312 static xitk_widget_t *_xitk_checkbox_create(xitk_widget_list_t *wl,
313 xitk_skin_config_t *skonfig,
314 xitk_checkbox_widget_t *cb, int x, int y,
315 const char *skin_element_name, xitk_image_t *skin,
316 int visible, int enable) {
317 xitk_widget_t *mywidget;
318 checkbox_private_data_t *private_data;
319
320 mywidget = (xitk_widget_t *) xitk_xmalloc (sizeof(xitk_widget_t));
321
322 private_data = (checkbox_private_data_t *)
323 xitk_xmalloc (sizeof (checkbox_private_data_t));
324
325 private_data->imlibdata = cb->imlibdata;
326 private_data->skin_element_name = (skin_element_name == NULL) ? NULL : strdup(cb->skin_element_name);
327
328 private_data->cWidget = mywidget;
329 private_data->cClicked = 0;
330 private_data->cState = 0;
331 private_data->focus = FOCUS_LOST;
332
333 private_data->skin = skin;
334 private_data->callback = cb->callback;
335 private_data->userdata = cb->userdata;
336
337 mywidget->private_data = private_data;
338
339 mywidget->wl = wl;
340
341 mywidget->enable = enable;
342 mywidget->running = 1;
343 mywidget->visible = visible;
344 mywidget->have_focus = FOCUS_LOST;
345 mywidget->imlibdata = private_data->imlibdata;
346 mywidget->x = x;
347 mywidget->y = y;
348 mywidget->width = private_data->skin->width/3;
349 mywidget->height = private_data->skin->height;
350 mywidget->type = WIDGET_TYPE_CHECKBOX | WIDGET_CLICKABLE | WIDGET_FOCUSABLE | WIDGET_KEYABLE;
351 mywidget->event = notify_event;
352 mywidget->tips_timeout = 0;
353 mywidget->tips_string = NULL;
354
355 return mywidget;
356 }
357
358 /*
359 *
360 */
xitk_checkbox_create(xitk_widget_list_t * wl,xitk_skin_config_t * skonfig,xitk_checkbox_widget_t * cb)361 xitk_widget_t *xitk_checkbox_create (xitk_widget_list_t *wl,
362 xitk_skin_config_t *skonfig, xitk_checkbox_widget_t *cb) {
363
364 XITK_CHECK_CONSTITENCY(cb);
365
366 return _xitk_checkbox_create(wl, skonfig, cb,
367 (xitk_skin_get_coord_x(skonfig, cb->skin_element_name)),
368 (xitk_skin_get_coord_y(skonfig, cb->skin_element_name)),
369 cb->skin_element_name,
370 (xitk_skin_get_image(skonfig,
371 xitk_skin_get_skin_filename(skonfig, cb->skin_element_name))),
372 (xitk_skin_get_visibility(skonfig, cb->skin_element_name)) ? 1 : -1,
373 xitk_skin_get_enability(skonfig, cb->skin_element_name));
374
375 }
376
377 /*
378 *
379 */
xitk_noskin_checkbox_create(xitk_widget_list_t * wl,xitk_checkbox_widget_t * cb,int x,int y,int width,int height)380 xitk_widget_t *xitk_noskin_checkbox_create(xitk_widget_list_t *wl,
381 xitk_checkbox_widget_t *cb,
382 int x, int y, int width, int height) {
383 xitk_image_t *i;
384
385 XITK_CHECK_CONSTITENCY(cb);
386
387 i = xitk_image_create_image(cb->imlibdata, width * 3, height);
388 draw_checkbox_check(cb->imlibdata, i);
389
390 return _xitk_checkbox_create(wl, NULL, cb, x, y, NULL, i, 0, 0);
391 }
392