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 <X11/Xlib.h>
26 #include <stdio.h>
27 
28 #include "_xitk.h"
29 
enability(xitk_widget_t * w)30 static void enability(xitk_widget_t *w) {
31 
32   if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_INTBOX) &&
33 	   (w->type & WIDGET_GROUP_WIDGET))) {
34     intbox_private_data_t *private_data = (intbox_private_data_t *) w->private_data;
35 
36     if(w->enable == WIDGET_ENABLE) {
37       xitk_enable_widget(private_data->input_widget);
38       xitk_enable_widget(private_data->more_widget);
39       xitk_enable_widget(private_data->less_widget);
40     }
41     else {
42       xitk_disable_widget(private_data->input_widget);
43       xitk_disable_widget(private_data->more_widget);
44       xitk_disable_widget(private_data->less_widget);
45     }
46   }
47 }
48 
49 /*
50  *
51  */
notify_destroy(xitk_widget_t * w)52 static void notify_destroy(xitk_widget_t *w) {
53 
54   if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_INTBOX) &&
55 	   (w->type & WIDGET_GROUP_WIDGET))) {
56     intbox_private_data_t *private_data = (intbox_private_data_t *) w->private_data;
57 
58     XITK_FREE(private_data->skin_element_name);
59     XITK_FREE(private_data);
60   }
61 }
62 
63 /*
64  *
65  */
paint(xitk_widget_t * w)66 static void paint(xitk_widget_t *w) {
67 
68   if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_INTBOX) &&
69 	   (w->type & WIDGET_GROUP_WIDGET))) {
70     intbox_private_data_t *private_data = (intbox_private_data_t *) w->private_data;
71 
72     if(w->visible == 1) {
73       int bx, ih, iw;
74 
75       iw = xitk_get_widget_width(private_data->input_widget);
76       ih = xitk_get_widget_height(private_data->input_widget);
77       xitk_set_widget_pos(private_data->input_widget, w->x, w->y);
78       bx = w->x + iw;
79       xitk_set_widget_pos(private_data->more_widget, bx, w->y);
80       xitk_set_widget_pos(private_data->less_widget, bx, (w->y + (ih>>1)));
81 
82       xitk_show_widget(private_data->input_widget);
83       xitk_show_widget(private_data->more_widget);
84       xitk_show_widget(private_data->less_widget);
85     }
86     else {
87       xitk_hide_widget(private_data->input_widget);
88       xitk_hide_widget(private_data->more_widget);
89       xitk_hide_widget(private_data->less_widget);
90     }
91   }
92 }
93 
94 /*
95  *
96  */
notify_change_skin(xitk_widget_t * w,xitk_skin_config_t * skonfig)97 static void notify_change_skin(xitk_widget_t *w, xitk_skin_config_t *skonfig) {
98 
99   if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_INTBOX) &&
100 	   (w->type & WIDGET_GROUP_WIDGET))) {
101     intbox_private_data_t *private_data = (intbox_private_data_t *) w->private_data;
102 
103     if(private_data->skin_element_name) {
104       /*
105       int x, y;
106 
107       xitk_skin_lock(skonfig);
108 
109       // visibility && enability
110 
111       xitk_set_widget_pos(c, c->x, c->y);
112       xitk_get_widget_pos(private_data->label_widget, &x, &y);
113       x += xitk_get_widget_width(private_data->label_widget);
114 
115       (void) xitk_set_widget_pos(private_data->button_widget, x, y);
116 
117       xitk_skin_unlock(skonfig);
118       */
119     }
120   }
121 }
122 
tips_timeout(xitk_widget_t * w,unsigned long timeout)123 static void tips_timeout(xitk_widget_t *w, unsigned long timeout) {
124   if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_INTBOX) &&
125 	   (w->type & WIDGET_GROUP_WIDGET))) {
126     intbox_private_data_t *private_data = (intbox_private_data_t *) w->private_data;
127 
128     private_data->input_widget->tips_timeout = timeout;
129     private_data->more_widget->tips_timeout = timeout;
130     private_data->less_widget->tips_timeout = timeout;
131   }
132 }
133 
notify_event(xitk_widget_t * w,widget_event_t * event,widget_event_result_t * result)134 static int notify_event(xitk_widget_t *w, widget_event_t *event, widget_event_result_t *result) {
135   int retval = 0;
136 
137   switch(event->type) {
138   case WIDGET_EVENT_PAINT:
139     paint(w);
140     break;
141   case WIDGET_EVENT_CHANGE_SKIN:
142     notify_change_skin(w, event->skonfig);
143     break;
144   case WIDGET_EVENT_DESTROY:
145     notify_destroy(w);
146     break;
147   case WIDGET_EVENT_ENABLE:
148     enability(w);
149     break;
150   case WIDGET_EVENT_TIPS_TIMEOUT:
151     tips_timeout(w, event->tips_timeout);
152     break;
153   }
154 
155   return retval;
156 }
157 
158 /*
159  *
160  */
intbox_change_value(xitk_widget_t * x,void * data,const char * string)161 static void intbox_change_value(xitk_widget_t *x, void *data, const char *string) {
162   xitk_widget_t         *w = (xitk_widget_t *)data;
163 
164   if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_INTBOX) &&
165 	   (w->type & WIDGET_GROUP_WIDGET))) {
166     intbox_private_data_t *private_data = (intbox_private_data_t *)w->private_data;
167     char                   buf[256];
168 
169     private_data->value = strtol(string, NULL, 10);
170 
171     memset(&buf, 0, sizeof(buf));
172     snprintf(buf, sizeof(buf), "%d", private_data->value);
173     xitk_inputtext_change_text(private_data->input_widget, buf);
174     if(private_data->force_value == 0)
175       if(private_data->callback)
176 	private_data->callback(w, private_data->userdata, private_data->value);
177   }
178 }
179 
180 /*
181  *
182  */
xitk_intbox_set_value(xitk_widget_t * w,int value)183 void xitk_intbox_set_value(xitk_widget_t *w, int value) {
184 
185   if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_INTBOX) &&
186 	   (w->type & WIDGET_GROUP_WIDGET))) {
187     intbox_private_data_t *private_data = (intbox_private_data_t *) w->private_data;
188     char                   buf[256];
189 
190     memset(&buf, 0, sizeof(buf));
191     snprintf(buf, sizeof(buf), "%d", value);
192     private_data->force_value = 1;
193     intbox_change_value(NULL, (void*)w, buf);
194     private_data->force_value = 0;
195   }
196 }
197 
198 /*
199  *
200  */
xitk_intbox_get_value(xitk_widget_t * w)201 int xitk_intbox_get_value(xitk_widget_t *w) {
202 
203   if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_INTBOX) &&
204 	   (w->type & WIDGET_GROUP_WIDGET))) {
205     intbox_private_data_t *private_data = (intbox_private_data_t *)w->private_data;
206     const char            *strval;
207 
208     strval = xitk_inputtext_get_text(private_data->input_widget);
209     private_data->value = strtol(strval, NULL, 10);
210 
211     return private_data->value;
212   }
213   return 0;
214 }
215 
216 /*
217  *
218  */
intbox_stepdown(xitk_widget_t * x,void * data)219 static void intbox_stepdown(xitk_widget_t *x, void *data) {
220   xitk_widget_t *w = (xitk_widget_t *) data;
221 
222   if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_INTBOX) &&
223 	   (w->type & WIDGET_GROUP_WIDGET))) {
224     intbox_private_data_t *private_data = (intbox_private_data_t *)w->private_data;
225 
226     private_data->value -= private_data->step;
227     xitk_intbox_set_value(w, private_data->value);
228     if(private_data->callback)
229       private_data->callback(w, private_data->userdata, private_data->value);
230   }
231 }
232 
233 /*
234  *
235  */
intbox_stepup(xitk_widget_t * x,void * data)236 static void intbox_stepup(xitk_widget_t *x, void *data) {
237   xitk_widget_t *w = (xitk_widget_t *) data;
238 
239   if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_INTBOX) &&
240 	   (w->type & WIDGET_GROUP_WIDGET))) {
241     intbox_private_data_t *private_data = (intbox_private_data_t *)w->private_data;
242 
243     private_data->value += private_data->step;
244     xitk_intbox_set_value(w, private_data->value);
245     if(private_data->callback)
246       private_data->callback(w, private_data->userdata, private_data->value);
247   }
248 }
249 
xitk_intbox_get_input_widget(xitk_widget_t * w)250 xitk_widget_t *xitk_intbox_get_input_widget(xitk_widget_t *w) {
251 
252   if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_INTBOX) &&
253 	   (w->type & WIDGET_GROUP_WIDGET))) {
254     intbox_private_data_t *private_data = (intbox_private_data_t *)w->private_data;
255 
256     return private_data->input_widget;
257   }
258 
259   return NULL;
260 }
261 
262 /*
263  *
264  */
_xitk_intbox_create(xitk_widget_list_t * wl,xitk_skin_config_t * skonfig,xitk_intbox_widget_t * ib,char * skin_element_name,xitk_widget_t * mywidget,intbox_private_data_t * private_data,int visible,int enable)265 static xitk_widget_t *_xitk_intbox_create(xitk_widget_list_t *wl,
266 					  xitk_skin_config_t *skonfig,
267 					  xitk_intbox_widget_t *ib, char *skin_element_name,
268 					  xitk_widget_t *mywidget,
269 					  intbox_private_data_t *private_data,
270 					  int visible, int enable) {
271 
272   private_data->imlibdata                = ib->imlibdata;
273   private_data->skin_element_name        = (skin_element_name == NULL) ? NULL : strdup(skin_element_name);
274   private_data->parent_wlist             = ib->parent_wlist;
275   private_data->callback                 = ib->callback;
276   private_data->userdata                 = ib->userdata;
277   private_data->step                     = ib->step;
278   private_data->value                    = ib->value;
279   private_data->force_value              = 0;
280 
281   mywidget->private_data                 = private_data;
282 
283   mywidget->wl                           = wl;
284 
285   mywidget->enable                       = enable;
286   mywidget->running                      = 1;
287   mywidget->visible                      = visible;
288   mywidget->have_focus                   = FOCUS_LOST;
289 
290   mywidget->imlibdata                    = private_data->imlibdata;
291 
292   mywidget->type                         = WIDGET_GROUP | WIDGET_GROUP_WIDGET | WIDGET_GROUP_INTBOX;
293   mywidget->event                        = notify_event;
294   mywidget->tips_timeout                 = 0;
295   mywidget->tips_string                  = NULL;
296 
297   return mywidget;
298 }
299 
300 /*
301  *
302  */
xitk_noskin_intbox_create(xitk_widget_list_t * wl,xitk_intbox_widget_t * ib,int x,int y,int width,int height,xitk_widget_t ** iw,xitk_widget_t ** mw,xitk_widget_t ** lw)303 xitk_widget_t *xitk_noskin_intbox_create(xitk_widget_list_t *wl,
304 					 xitk_intbox_widget_t *ib,
305 					 int x, int y, int width, int height,
306 					 xitk_widget_t **iw, xitk_widget_t **mw, xitk_widget_t **lw) {
307   xitk_widget_t              *mywidget;
308   intbox_private_data_t      *private_data;
309   xitk_button_widget_t        b;
310   xitk_inputtext_widget_t     inp;
311 
312   XITK_CHECK_CONSTITENCY(ib);
313 
314   mywidget = (xitk_widget_t *) xitk_xmalloc (sizeof(xitk_widget_t));
315 
316   XITK_WIDGET_INIT(&b, ib->imlibdata);
317   XITK_WIDGET_INIT(&inp, ib->imlibdata);
318 
319   private_data = (intbox_private_data_t *) xitk_xmalloc(sizeof(intbox_private_data_t));
320 
321   /* Create inputtext and buttons (not skinable) */
322   {
323     char          buf[256];
324     xitk_image_t *wimage;
325 
326     memset(&buf, 0, sizeof(buf));
327     snprintf(buf, sizeof(buf), "%d", ib->value);
328 
329     inp.skin_element_name = NULL;
330     inp.text              = buf;
331     inp.max_length        = 16;
332     inp.callback          = intbox_change_value;
333     inp.userdata          = (void *)mywidget;
334     private_data->input_widget = xitk_noskin_inputtext_create (ib->parent_wlist, &inp,
335       x, y, (width - 10), height, "Black", "Black", DEFAULT_FONT_10);
336     xitk_dlist_add_tail (&ib->parent_wlist->list, &private_data->input_widget->node);
337     private_data->input_widget->type |= WIDGET_GROUP | WIDGET_GROUP_INTBOX;
338 
339     b.skin_element_name = NULL;
340     b.callback          = intbox_stepup;
341     b.userdata          = (void *)mywidget;
342     private_data->more_widget = xitk_noskin_button_create (ib->parent_wlist, &b,
343       (x + width) - (height>>1), y, (height>>1), (height>>1));
344     xitk_dlist_add_tail (&ib->parent_wlist->list, &private_data->more_widget->node);
345     private_data->more_widget->type |= WIDGET_GROUP | WIDGET_GROUP_INTBOX;
346 
347     b.skin_element_name = NULL;
348     b.callback          = intbox_stepdown;
349     b.userdata          = (void *)mywidget;
350     private_data->less_widget = xitk_noskin_button_create (ib->parent_wlist, &b,
351       (x + width) - (height>>1), (y + (height>>1)), (height>>1), (height>>1));
352     xitk_dlist_add_tail (&ib->parent_wlist->list, &private_data->less_widget->node);
353     private_data->less_widget->type |= WIDGET_GROUP | WIDGET_GROUP_INTBOX;
354 
355     /* Draw '+' and '-' in buttons */
356     wimage = xitk_get_widget_foreground_skin(private_data->more_widget);
357 
358     if(wimage)
359       draw_button_plus(ib->imlibdata, wimage);
360 
361     wimage = xitk_get_widget_foreground_skin(private_data->less_widget);
362 
363     if(wimage)
364       draw_button_minus(ib->imlibdata, wimage);
365 
366   }
367 
368   if(iw)
369     *iw = private_data->input_widget;
370   if(mw)
371     *mw = private_data->more_widget;
372   if(lw)
373     *lw = private_data->less_widget;
374 
375   mywidget->x = x;
376   mywidget->y = y;
377   mywidget->width = width;
378   mywidget->height = height;
379 
380   return _xitk_intbox_create(wl, NULL, ib, NULL, mywidget, private_data, 0, 0);
381 }
382