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 button_private_data_t *private_data;
34
35 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_BUTTON)) {
36 private_data = (button_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 button_private_data_t *private_data;
51
52 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_BUTTON)) {
53 private_data = (button_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 button_private_data_t *private_data;
68
69 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_BUTTON)) {
70 private_data = (button_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_button(xitk_widget_t * w)88 static void paint_button (xitk_widget_t *w) {
89 button_private_data_t *private_data;
90 GC lgc;
91 int button_width;
92 xitk_image_t *skin;
93
94 if(w && (((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_BUTTON) && w->visible == 1)) {
95
96 private_data = (button_private_data_t *) w->private_data;
97 skin = private_data->skin;
98 button_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->bClicked) {
115 XCopyArea (private_data->imlibdata->x.disp, skin->image->pixmap,
116 w->wl->win, lgc, 2*button_width, 0,
117 button_width, skin->height, w->x, w->y);
118 }
119 else {
120 XCopyArea (private_data->imlibdata->x.disp, skin->image->pixmap,
121 w->wl->win, lgc, button_width, 0,
122 button_width, skin->height, w->x, w->y);
123 }
124 }
125 else {
126 XCopyArea (private_data->imlibdata->x.disp, skin->image->pixmap,
127 w->wl->win, lgc, 0, 0,
128 button_width, skin->height, w->x, w->y);
129 }
130 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
131
132 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
133 XFreeGC(private_data->imlibdata->x.disp, lgc);
134 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
135 }
136
137 }
138
139 /*
140 *
141 */
notify_change_skin(xitk_widget_t * w,xitk_skin_config_t * skonfig)142 static void notify_change_skin(xitk_widget_t *w, xitk_skin_config_t *skonfig) {
143 button_private_data_t *private_data;
144
145 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_BUTTON)) {
146 private_data = (button_private_data_t *) w->private_data;
147
148 if(private_data->skin_element_name) {
149 xitk_skin_lock(skonfig);
150 private_data->skin = xitk_skin_get_image(skonfig,
151 (xitk_skin_get_skin_filename(skonfig, private_data->skin_element_name)));
152 w->x = xitk_skin_get_coord_x(skonfig, private_data->skin_element_name);
153 w->y = xitk_skin_get_coord_y(skonfig, private_data->skin_element_name);
154 w->width = private_data->skin->width/3;
155 w->height = private_data->skin->height;
156
157 w->visible = (xitk_skin_get_visibility(skonfig, private_data->skin_element_name)) ? 1 : -1;
158 w->enable = xitk_skin_get_enability(skonfig, private_data->skin_element_name);
159
160 xitk_skin_unlock(skonfig);
161 xitk_set_widget_pos(w, w->x, w->y);
162 }
163 }
164 }
165
166 /*
167 *
168 */
notify_click_button(xitk_widget_t * w,int button,int bUp,int x,int y)169 static int notify_click_button (xitk_widget_t *w, int button, int bUp, int x, int y) {
170 button_private_data_t *private_data;
171 int ret = 0;
172
173 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_BUTTON)) {
174 if(button == Button1) {
175 private_data = (button_private_data_t *) w->private_data;
176 private_data->bClicked = !bUp;
177
178 paint_button(w);
179
180 if (bUp && (private_data->focus == FOCUS_RECEIVED)) {
181 if(private_data->callback) {
182 private_data->callback(private_data->bWidget,
183 private_data->userdata);
184 }
185 }
186 ret = 1;
187 }
188 }
189
190 return ret;
191 }
192
193 /*
194 *
195 */
notify_focus_button(xitk_widget_t * w,int focus)196 static int notify_focus_button (xitk_widget_t *w, int focus) {
197 button_private_data_t *private_data;
198
199 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_BUTTON)) {
200 private_data = (button_private_data_t *) w->private_data;
201 private_data->focus = focus;
202 }
203
204 return 1;
205 }
206
notify_event(xitk_widget_t * w,widget_event_t * event,widget_event_result_t * result)207 static int notify_event(xitk_widget_t *w, widget_event_t *event, widget_event_result_t *result) {
208 int retval = 0;
209
210 switch(event->type) {
211 case WIDGET_EVENT_PAINT:
212 paint_button(w);
213 break;
214 case WIDGET_EVENT_CLICK:
215 result->value = notify_click_button(w, event->button,
216 event->button_pressed, event->x, event->y);
217 retval = 1;
218 break;
219 case WIDGET_EVENT_FOCUS:
220 notify_focus_button(w, event->focus);
221 break;
222 case WIDGET_EVENT_INSIDE:
223 result->value = notify_inside(w, event->x, event->y);
224 retval = 1;
225 break;
226 case WIDGET_EVENT_CHANGE_SKIN:
227 notify_change_skin(w, event->skonfig);
228 break;
229 case WIDGET_EVENT_DESTROY:
230 notify_destroy(w);
231 break;
232 case WIDGET_EVENT_GET_SKIN:
233 if(result) {
234 result->image = get_skin(w, event->skin_layer);
235 retval = 1;
236 }
237 break;
238 }
239
240 return retval;
241 }
242
243 /*
244 *
245 */
_xitk_button_create(xitk_widget_list_t * wl,xitk_skin_config_t * skonfig,xitk_button_widget_t * b,int x,int y,const char * skin_element_name,xitk_image_t * skin,int visible,int enable)246 static xitk_widget_t *_xitk_button_create (xitk_widget_list_t *wl,
247 xitk_skin_config_t *skonfig, xitk_button_widget_t *b,
248 int x, int y,
249 const char *skin_element_name, xitk_image_t *skin,
250 int visible, int enable) {
251 xitk_widget_t *mywidget;
252 button_private_data_t *private_data;
253
254 mywidget = (xitk_widget_t *) xitk_xmalloc (sizeof(xitk_widget_t));
255
256 private_data = (button_private_data_t *) xitk_xmalloc(sizeof(button_private_data_t));
257
258 private_data->imlibdata = b->imlibdata;
259
260 private_data->bWidget = mywidget;
261 private_data->bClicked = 0;
262 private_data->focus = FOCUS_LOST;
263
264 private_data->skin_element_name = (skin_element_name == NULL) ? NULL : strdup(b->skin_element_name);
265 private_data->skin = skin;
266
267 private_data->callback = b->callback;
268 private_data->userdata = b->userdata;
269
270 mywidget->private_data = private_data;
271
272 mywidget->wl = wl;
273
274 mywidget->enable = enable;
275 mywidget->running = 1;
276 mywidget->visible = visible;
277 mywidget->have_focus = FOCUS_LOST;
278 mywidget->imlibdata = private_data->imlibdata;
279 mywidget->x = x;
280 mywidget->y = y;
281 mywidget->width = private_data->skin->width/3;
282 mywidget->height = private_data->skin->height;
283 mywidget->type = WIDGET_TYPE_BUTTON | WIDGET_CLICKABLE | WIDGET_FOCUSABLE | WIDGET_KEYABLE;
284 mywidget->event = notify_event;
285 mywidget->tips_timeout = 0;
286 mywidget->tips_string = NULL;
287
288 return mywidget;
289 }
290
291 /*
292 *
293 */
xitk_button_create(xitk_widget_list_t * wl,xitk_skin_config_t * skonfig,xitk_button_widget_t * b)294 xitk_widget_t *xitk_button_create (xitk_widget_list_t *wl,
295 xitk_skin_config_t *skonfig, xitk_button_widget_t *b) {
296
297 XITK_CHECK_CONSTITENCY(b);
298
299 return _xitk_button_create(wl, skonfig, b,
300 (xitk_skin_get_coord_x(skonfig, b->skin_element_name)),
301 (xitk_skin_get_coord_y(skonfig, b->skin_element_name)),
302 b->skin_element_name,
303 xitk_skin_get_image(skonfig,
304 (xitk_skin_get_skin_filename(skonfig, b->skin_element_name))),
305 (xitk_skin_get_visibility(skonfig, b->skin_element_name)) ? 1 : -1,
306 xitk_skin_get_enability(skonfig, b->skin_element_name));
307 }
308
309 /*
310 *
311 */
xitk_noskin_button_create(xitk_widget_list_t * wl,xitk_button_widget_t * b,int x,int y,int width,int height)312 xitk_widget_t *xitk_noskin_button_create (xitk_widget_list_t *wl,
313 xitk_button_widget_t *b,
314 int x, int y, int width, int height) {
315 xitk_image_t *i;
316
317 XITK_CHECK_CONSTITENCY(b);
318
319 i = xitk_image_create_image(b->imlibdata, width * 3, height);
320 draw_bevel_three_state(b->imlibdata, i);
321
322 return _xitk_button_create(wl, NULL, b, x, y, NULL, i, 0, 0);
323 }
324