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 <X11/Xlib.h>
28 #include <X11/Xutil.h>
29 #include <X11/keysym.h>
30
31 #include "common.h"
32
33 #define VFREE(vfp) do {memset (vfp, 0x55, sizeof (*(vfp))); free (vfp); } while (0)
34
35 #undef TRACE_REWIRE
36
37 #define DEFAULT_DEINTERLACER "tvtime:method=LinearBlend,cheap_mode=1,pulldown=0,use_progressive_frame_flag=1"
38
39 #define WINDOW_WIDTH 530
40 #define WINDOW_HEIGHT 503
41
42 #define FRAME_WIDTH (WINDOW_WIDTH - 50)
43 #define FRAME_HEIGHT 80
44
45 #define HELP_WINDOW_WIDTH 400
46 #define HELP_WINDOW_HEIGHT 402
47
48 #define MAX_DISPLAY_FILTERS 5
49 /* It hardly makes any sense to use infinitely many filters. */
50 #define MAX_USED_FILTERS 32
51
52 #define MAX_DISP_ENTRIES 15
53 #define BROWSER_LINE_WIDTH 55
54
55 #define DISABLE_ME(widget) \
56 do { \
57 if(widget) \
58 xitk_disable_and_hide_widget(widget); \
59 } while(0)
60
61 #define ENABLE_ME(widget) \
62 do { \
63 if(widget) \
64 xitk_enable_and_show_widget(widget); \
65 } while(0)
66
67 typedef struct {
68 xine_post_t *post;
69 const xine_post_api_t *api;
70 const xine_post_api_descr_t *descr;
71 const xine_post_api_parameter_t *param;
72 char *param_data;
73
74 int x;
75 int y;
76
77 xitk_widget_t *frame;
78 xitk_widget_t *plugins;
79 xitk_widget_t *properties;
80 xitk_widget_t *value;
81 xitk_widget_t *comment;
82
83 xitk_widget_t *up;
84 xitk_widget_t *down;
85
86 xitk_widget_t *help;
87
88 int readonly;
89
90 char **properties_names;
91 } post_object_t;
92
93 typedef struct {
94 xitk_window_t *xwin;
95
96 xitk_widget_list_t *widget_list;
97
98 xitk_widget_t *slider;
99
100 char **plugin_names;
101
102 post_object_t *post_objects[MAX_USED_FILTERS];
103 int first_displayed;
104 int object_num;
105
106 xitk_widget_t *enable;
107
108 int x, y;
109
110 int running;
111 int visible;
112 xitk_register_key_t widget_key;
113
114 /* help window stuff */
115 xitk_window_t *helpwin;
116 xitk_widget_list_t *help_widget_list;
117 char **help_text;
118 xitk_register_key_t help_widget_key;
119 int help_running;
120 xitk_widget_t *help_browser;
121 } _pplugin_t;
122
123 typedef struct {
124 _pplugin_t *pplugin;
125 } _pp_wrapper_t;
126
127 static _pp_wrapper_t vpp_wrapper = { NULL };
128 static _pp_wrapper_t app_wrapper = { NULL };
129 static char **post_audio_plugins;
130
131 /* Some functions prototype */
132 static void _vpplugin_unwire(void);
133 static void _applugin_unwire(void);
134 static void _pplugin_unwire(_pp_wrapper_t *pp_wrapper);
135 static post_element_t **pplugin_parse_and_load(_pp_wrapper_t *pp_wrapper, const char *, int *);
136 static void _vpplugin_rewire(void);
137 static void _applugin_rewire(void);
138 static void _pplugin_rewire(_pp_wrapper_t *pp_wrapper);
139 static void _pplugin_rewire_from_post_elements(_pp_wrapper_t *pp_wrapper, post_element_t **, int);
140 static post_element_t **_pplugin_join_deinterlace_and_post_elements(int *);
141 static post_element_t **_pplugin_join_visualization_and_post_elements(int *);
142 static void _pplugin_save_chain(_pp_wrapper_t *pp_wrapper);
143 static void _vpplugin_close_help(xitk_widget_t *, void *);
144 static void _applugin_close_help(xitk_widget_t *, void *);
145 static void _pplugin_close_help(_pp_wrapper_t *pp_wrapper, xitk_widget_t *, void *);
146
post_deinterlace_plugin_cb(void * data,xine_cfg_entry_t * cfg)147 static void post_deinterlace_plugin_cb(void *data, xine_cfg_entry_t *cfg) {
148 gGui_t *gui = data;
149 post_element_t **posts = NULL;
150 int num, i;
151
152 gui->deinterlace_plugin = cfg->str_value;
153
154 if(gui->deinterlace_enable)
155 _vpplugin_unwire();
156
157 for(i = 0; i < gui->deinterlace_elements_num; i++) {
158 xine_post_dispose(__xineui_global_xine_instance, gui->deinterlace_elements[i]->post);
159 free(gui->deinterlace_elements[i]->name);
160 VFREE(gui->deinterlace_elements[i]);
161 }
162
163 SAFE_FREE(gui->deinterlace_elements);
164 gui->deinterlace_elements_num = 0;
165
166 if((posts = pplugin_parse_and_load(&vpp_wrapper, gui->deinterlace_plugin, &num))) {
167 gui->deinterlace_elements = posts;
168 gui->deinterlace_elements_num = num;
169 }
170
171 if(gui->deinterlace_enable)
172 _vpplugin_rewire();
173 }
174
post_audio_plugin_cb(void * data,xine_cfg_entry_t * cfg)175 static void post_audio_plugin_cb(void *data, xine_cfg_entry_t *cfg) {
176 gGui_t *gui = data;
177 gui->visual_anim.post_plugin_num = cfg->num_value;
178 post_rewire_visual_anim();
179 }
180
post_get_audio_plugins_names(void)181 const char **post_get_audio_plugins_names(void) {
182 return (const char **) post_audio_plugins;
183 }
184
post_init(void)185 void post_init(void) {
186 gGui_t *gui = gGui;
187
188 memset(&gui->visual_anim.post_output_element, 0, sizeof (gui->visual_anim.post_output_element));
189
190 gui->visual_anim.post_plugin_num = -1;
191 gui->visual_anim.post_changed = 0;
192
193 if(gui->ao_port) {
194 const char *const *pol = xine_list_post_plugins_typed(__xineui_global_xine_instance,
195 XINE_POST_TYPE_AUDIO_VISUALIZATION);
196
197 if(pol) {
198 int num_plug = 0;
199
200 while(pol[num_plug]) {
201
202 post_audio_plugins = (char **) realloc(post_audio_plugins, sizeof(char *) * (num_plug + 2));
203
204 post_audio_plugins[num_plug] = strdup(pol[num_plug]);
205 post_audio_plugins[num_plug + 1] = NULL;
206 num_plug++;
207 }
208
209 if(num_plug) {
210
211 gui->visual_anim.post_plugin_num =
212 xine_config_register_enum(__xineui_global_xine_instance, "gui.post_audio_plugin",
213 0, post_audio_plugins,
214 _("Audio visualization plugin"),
215 _("Post audio plugin to used when playing streams without video"),
216 CONFIG_LEVEL_BEG,
217 post_audio_plugin_cb,
218 gGui);
219
220 gui->visual_anim.post_output_element.post =
221 xine_post_init(__xineui_global_xine_instance,
222 post_audio_plugins[gui->visual_anim.post_plugin_num], 0,
223 &gui->ao_port, &gui->vo_port);
224
225 }
226 }
227 }
228 }
229
post_rewire_visual_anim(void)230 void post_rewire_visual_anim(void) {
231 gGui_t *gui = gGui;
232
233 if(gui->visual_anim.post_output_element.post) {
234 (void) post_rewire_audio_port_to_stream(gui->stream);
235
236 xine_post_dispose(__xineui_global_xine_instance, gui->visual_anim.post_output_element.post);
237 }
238
239 gui->visual_anim.post_output_element.post =
240 xine_post_init(__xineui_global_xine_instance,
241 post_audio_plugins[gui->visual_anim.post_plugin_num], 0,
242 &gui->ao_port, &gui->vo_port);
243
244 if(gui->visual_anim.post_output_element.post &&
245 (gui->visual_anim.enabled == 1) && (gui->visual_anim.running == 1)) {
246
247 (void) post_rewire_audio_post_to_stream(gui->stream);
248
249 }
250 }
251
252 static int ignore_visual_anim = 1;
253
post_rewire_audio_port_to_stream(xine_stream_t * stream)254 int post_rewire_audio_port_to_stream(xine_stream_t *stream) {
255
256 _applugin_unwire();
257 ignore_visual_anim = 1;
258 _applugin_rewire();
259 /*
260 gGui_t *gui = gGui;
261 xine_post_out_t * audio_source;
262
263 audio_source = xine_get_audio_source(stream);
264 return xine_post_wire_audio_port(audio_source, gui->ao_port);
265 */
266 return 1;
267 }
268
post_rewire_audio_post_to_stream(xine_stream_t * stream)269 int post_rewire_audio_post_to_stream(xine_stream_t *stream) {
270
271 _applugin_unwire();
272 ignore_visual_anim = 0;
273 _applugin_rewire();
274 /*
275 xine_post_out_t * audio_source;
276 gGui_t *gui = gGui;
277
278 audio_source = xine_get_audio_source(stream);
279 return xine_post_wire_audio_port(audio_source, gui->visual_anim.post_output->audio_input[0]);
280 */
281 return 1;
282 }
283
284 /* ================================================================ */
285
_vpplugin_unwire(void)286 static void _vpplugin_unwire(void) {
287 gGui_t *gui = gGui;
288 xine_post_out_t *vo_source;
289
290 if (gui->stream) {
291 vo_source = xine_get_video_source(gui->stream);
292
293 if (gui->vo_port)
294 (void) xine_post_wire_video_port(vo_source, gui->vo_port);
295 }
296 }
297
_applugin_unwire(void)298 static void _applugin_unwire(void) {
299 gGui_t *gui = gGui;
300 xine_post_out_t *ao_source;
301
302 if (gui->stream) {
303 ao_source = xine_get_audio_source(gui->stream);
304
305 if (gui->ao_port)
306 (void) xine_post_wire_audio_port(ao_source, gui->ao_port);
307 }
308 }
309
_pplugin_unwire(_pp_wrapper_t * pp_wrapper)310 static void _pplugin_unwire(_pp_wrapper_t *pp_wrapper) {
311 if (pp_wrapper == &vpp_wrapper)
312 _vpplugin_unwire();
313 else
314 _applugin_unwire();
315 }
316
_vpplugin_rewire(void)317 static void _vpplugin_rewire(void) {
318 static post_element_t **post_elements;
319 int post_elements_num;
320 _pp_wrapper_t *pp_wrapper = &vpp_wrapper;
321
322 _pplugin_save_chain(pp_wrapper);
323
324 post_elements = _pplugin_join_deinterlace_and_post_elements(&post_elements_num);
325
326 if( post_elements ) {
327 _pplugin_rewire_from_post_elements(pp_wrapper, post_elements, post_elements_num);
328
329 free(post_elements);
330 }
331
332 #if 0
333 gGui_t *gui = gGui;
334 if(pplugin && (gui->post_enable && !gui->deinterlace_enable)) {
335 xine_post_out_t *vo_source;
336 int post_num = pplugin->object_num;
337 int i = 0;
338
339 if(!xitk_combo_get_current_selected(pplugin->post_objects[post_num - 1]->plugins))
340 post_num--;
341
342 if(post_num) {
343 int paused = 0;
344
345 if((paused = (xine_get_param(gui->stream, XINE_PARAM_SPEED) == XINE_SPEED_PAUSE)))
346 xine_set_param(gui->stream, XINE_PARAM_SPEED, XINE_SPEED_SLOW_4);
347
348 for(i = (post_num - 1); i >= 0; i--) {
349 const char *const *outs = xine_post_list_outputs(pplugin->post_objects[i]->post);
350 const xine_post_out_t *vo_out = xine_post_output(pplugin->post_objects[i]->post, (char *) *outs);
351 if(i == (post_num - 1)) {
352 #ifdef TRACE_REWIRE
353 printf(" VIDEO_OUT .. OUT<-[PLUGIN %d]\n", i);
354 #endif
355 xine_post_wire_video_port((xine_post_out_t *) vo_out, gui->vo_port);
356 }
357 else {
358 const xine_post_in_t *vo_in = xine_post_input(pplugin->post_objects[i+1]->post, "video");
359 int err;
360
361 #ifdef TRACE_REWIRE
362 printf(" [PLUGIN %d]->IN ... OUT<-[PLUGIN %d]", i+1, i);
363 #endif
364 err = xine_post_wire((xine_post_out_t *) vo_out, (xine_post_in_t *) vo_in);
365 #ifdef TRACE_REWIRE
366 printf(" (RESULT: %d)\n", err);
367 #endif
368 }
369 }
370
371 #ifdef TRACE_REWIRE
372 printf(" [PLUGIN %d]->IN .. STREAM\n", 0);
373 #endif
374
375 vo_source = xine_get_video_source(gui->stream);
376 xine_post_wire_video_port(vo_source, pplugin->post_objects[0]->post->video_input[0]);
377
378 if(paused)
379 xine_set_param(gui->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
380
381 }
382 }
383 #endif
384 }
385
_applugin_rewire(void)386 static void _applugin_rewire(void) {
387 static post_element_t **post_elements;
388 int post_elements_num;
389 _pp_wrapper_t *pp_wrapper = &app_wrapper;
390
391 _pplugin_save_chain(pp_wrapper);
392
393 post_elements = _pplugin_join_visualization_and_post_elements(&post_elements_num);
394
395 if( post_elements ) {
396 _pplugin_rewire_from_post_elements(pp_wrapper, post_elements, post_elements_num);
397
398 free(post_elements);
399 }
400 }
401
_pplugin_rewire(_pp_wrapper_t * pp_wrapper)402 static void _pplugin_rewire(_pp_wrapper_t *pp_wrapper) {
403 if (pp_wrapper == &vpp_wrapper)
404 _vpplugin_rewire();
405 else
406 _applugin_rewire();
407 }
408
_pplugin_get_object_offset(_pp_wrapper_t * pp_wrapper,post_object_t * pobj)409 static int _pplugin_get_object_offset(_pp_wrapper_t *pp_wrapper, post_object_t *pobj) {
410 int i;
411
412 for(i = 0; i < pp_wrapper->pplugin->object_num; i++) {
413 if(pp_wrapper->pplugin->post_objects[i] == pobj)
414 return i;
415 }
416
417 return 0;
418 }
419
_pplugin_is_first_filter(_pp_wrapper_t * pp_wrapper,post_object_t * pobj)420 static int _pplugin_is_first_filter(_pp_wrapper_t *pp_wrapper, post_object_t *pobj) {
421 if(pp_wrapper->pplugin)
422 return (pobj == *pp_wrapper->pplugin->post_objects);
423
424 return 0;
425 }
426
_pplugin_is_last_filter(_pp_wrapper_t * pp_wrapper,post_object_t * pobj)427 static int _pplugin_is_last_filter(_pp_wrapper_t *pp_wrapper, post_object_t *pobj) {
428
429 if(pp_wrapper->pplugin) {
430 post_object_t **po = pp_wrapper->pplugin->post_objects;
431
432 while(*po && (*po != pobj))
433 po++;
434
435 if(*(po + 1) == NULL)
436 return 1;
437 }
438
439 return 0;
440 }
441
_pplugin_hide_obj(post_object_t * pobj)442 static void _pplugin_hide_obj(post_object_t *pobj) {
443 if(pobj) {
444 DISABLE_ME(pobj->frame);
445 DISABLE_ME(pobj->plugins);
446 DISABLE_ME(pobj->properties);
447 DISABLE_ME(pobj->value);
448 DISABLE_ME(pobj->comment);
449 DISABLE_ME(pobj->up);
450 DISABLE_ME(pobj->down);
451 DISABLE_ME(pobj->help);
452 }
453 }
454
_pplugin_show_obj(_pp_wrapper_t * pp_wrapper,post_object_t * pobj)455 static void _pplugin_show_obj(_pp_wrapper_t *pp_wrapper, post_object_t *pobj) {
456
457 if(pobj) {
458
459 if(pobj->frame)
460 xitk_set_widget_pos(pobj->frame, pobj->x, pobj->y);
461
462 if(pobj->plugins)
463 xitk_set_widget_pos(pobj->plugins, pobj->x + 26 + 6, pobj->y + 5 + (20 - xitk_get_widget_height(pobj->plugins)) / 2);
464
465 if(pobj->properties)
466 xitk_set_widget_pos(pobj->properties, pobj->x + 26 + 196, pobj->y + 5 + (20 - xitk_get_widget_height(pobj->properties)) / 2);
467
468 if(pobj->help)
469 xitk_set_widget_pos(pobj->help, pobj->x + 26 + 386, pobj->y + 5);
470
471 if(pobj->comment)
472 xitk_set_widget_pos(pobj->comment, pobj->x + 26 + 6, pobj->y + 28 + 4);
473
474 if(pobj->value)
475 xitk_set_widget_pos(pobj->value, pobj->x + 26 + 6, pobj->y + (FRAME_HEIGHT - 5 + 1) - (20 + xitk_get_widget_height(pobj->value)) / 2);
476
477 if(pobj->up)
478 xitk_set_widget_pos(pobj->up, pobj->x + 5, pobj->y + 5);
479
480 if(pobj->down)
481 xitk_set_widget_pos(pobj->down, pobj->x + 5, pobj->y + (FRAME_HEIGHT - 16 - 5));
482
483 ENABLE_ME(pobj->frame);
484 ENABLE_ME(pobj->plugins);
485 ENABLE_ME(pobj->properties);
486 ENABLE_ME(pobj->value);
487 ENABLE_ME(pobj->comment);
488 ENABLE_ME(pobj->help);
489
490 if((!_pplugin_is_first_filter(pp_wrapper, pobj)) && (xitk_combo_get_current_selected(pobj->plugins)))
491 ENABLE_ME(pobj->up);
492
493 if((!_pplugin_is_last_filter(pp_wrapper, pobj) && (xitk_combo_get_current_selected(pobj->plugins))) &&
494 (_pplugin_is_last_filter(pp_wrapper, pobj)
495 || (!_pplugin_is_last_filter(pp_wrapper, pobj)
496 && pp_wrapper->pplugin->post_objects[_pplugin_get_object_offset(pp_wrapper, pobj) + 1]
497 && xitk_combo_get_current_selected(pp_wrapper->pplugin->post_objects[_pplugin_get_object_offset(pp_wrapper, pobj) + 1]->plugins))))
498 ENABLE_ME(pobj->down);
499
500 }
501 }
502
_pplugin_paint_widgets(_pp_wrapper_t * pp_wrapper)503 static void _pplugin_paint_widgets(_pp_wrapper_t *pp_wrapper) {
504 if(pp_wrapper->pplugin) {
505 int i, x, y;
506 int last;
507 int slidmax, slidpos;
508
509 last = pp_wrapper->pplugin->object_num <= (pp_wrapper->pplugin->first_displayed + MAX_DISPLAY_FILTERS)
510 ? pp_wrapper->pplugin->object_num : (pp_wrapper->pplugin->first_displayed + MAX_DISPLAY_FILTERS);
511
512 for(i = 0; i < pp_wrapper->pplugin->object_num; i++)
513 _pplugin_hide_obj(pp_wrapper->pplugin->post_objects[i]);
514
515 x = 15;
516 y = 34 - (FRAME_HEIGHT + 4);
517
518 for(i = pp_wrapper->pplugin->first_displayed; i < last; i++) {
519 y += FRAME_HEIGHT + 4;
520 pp_wrapper->pplugin->post_objects[i]->x = x;
521 pp_wrapper->pplugin->post_objects[i]->y = y;
522 _pplugin_show_obj(pp_wrapper, pp_wrapper->pplugin->post_objects[i]);
523 }
524
525 if(pp_wrapper->pplugin->object_num > MAX_DISPLAY_FILTERS) {
526 slidmax = pp_wrapper->pplugin->object_num - MAX_DISPLAY_FILTERS;
527 slidpos = slidmax - pp_wrapper->pplugin->first_displayed;
528 xitk_enable_and_show_widget(pp_wrapper->pplugin->slider);
529 }
530 else {
531 slidmax = 1;
532 slidpos = slidmax;
533
534 if(!pp_wrapper->pplugin->first_displayed)
535 xitk_disable_and_hide_widget(pp_wrapper->pplugin->slider);
536 }
537
538 xitk_slider_set_max(pp_wrapper->pplugin->slider, slidmax);
539 xitk_slider_set_pos(pp_wrapper->pplugin->slider, slidpos);
540 }
541 }
542
_pplugin_send_expose(_pp_wrapper_t * pp_wrapper)543 static void _pplugin_send_expose(_pp_wrapper_t *pp_wrapper) {
544 gGui_t *gui = gGui;
545 if(pp_wrapper->pplugin) {
546 gui->x_lock_display (gui->display);
547 XClearWindow(gui->display, (XITK_WIDGET_LIST_WINDOW(pp_wrapper->pplugin->widget_list)));
548 gui->x_unlock_display (gui->display);
549 }
550 }
551
_pplugin_destroy_widget(xitk_widget_t ** w)552 static void _pplugin_destroy_widget (xitk_widget_t **w) {
553 xitk_destroy_widget (*w);
554 *w = NULL;
555 }
556
_pplugin_update_parameter(post_object_t * pobj)557 static void _pplugin_update_parameter(post_object_t *pobj) {
558 pobj->api->set_parameters(pobj->post, pobj->param_data);
559 pobj->api->get_parameters(pobj->post, pobj->param_data);
560 }
561
_pplugin_set_param_int(xitk_widget_t * w,void * data,int value)562 static void _pplugin_set_param_int(xitk_widget_t *w, void *data, int value) {
563 post_object_t *pobj = (post_object_t *) data;
564
565 if(pobj->readonly)
566 return;
567
568 //can be int[]:
569 //int num_of_int = pobj->param->size / sizeof(char);
570
571 if(pobj->param->range_min && pobj->param->range_max &&
572 (value < (int)pobj->param->range_min || value > (int)pobj->param->range_max)) {
573 xine_error(_("Entered value is out of bounds (%d>%d<%d)."),
574 (int)pobj->param->range_min, value, (int)pobj->param->range_max);
575 }
576 else {
577 *(int *)(pobj->param_data + pobj->param->offset) = value;
578
579 _pplugin_update_parameter(pobj);
580
581 if(xitk_get_widget_type(w) & WIDGET_GROUP_COMBO)
582 xitk_combo_set_select(pobj->value, *(int *)(pobj->param_data + pobj->param->offset));
583 else
584 xitk_intbox_set_value(pobj->value, *(int *)(pobj->param_data + pobj->param->offset));
585 }
586 }
587
_pplugin_set_param_double(xitk_widget_t * w,void * data,double value)588 static void _pplugin_set_param_double(xitk_widget_t *w, void *data, double value) {
589 post_object_t *pobj = (post_object_t *) data;
590
591 if(pobj->readonly)
592 return;
593
594 if(pobj->param->range_min && pobj->param->range_max &&
595 (value < pobj->param->range_min || value > pobj->param->range_max)) {
596 xine_error(_("Entered value is out of bounds (%e>%e<%e)."),
597 pobj->param->range_min, value, pobj->param->range_max);
598 }
599 else {
600 *(double *)(pobj->param_data + pobj->param->offset) = value;
601
602 _pplugin_update_parameter(pobj);
603
604 xitk_doublebox_set_value(pobj->value, *(double *)(pobj->param_data + pobj->param->offset));
605 }
606 }
607
_pplugin_set_param_char(xitk_widget_t * w,void * data,const char * text)608 static void _pplugin_set_param_char(xitk_widget_t *w, void *data, const char *text) {
609 post_object_t *pobj = (post_object_t *) data;
610
611 if(pobj->readonly)
612 return;
613
614 // SUPPORT CHAR but no STRING yet
615 if(pobj->param->type == POST_PARAM_TYPE_CHAR) {
616 int maxlen = pobj->param->size / sizeof(char);
617
618 strlcpy((char *)(pobj->param_data + pobj->param->offset), text, maxlen);
619 _pplugin_update_parameter(pobj);
620 xitk_inputtext_change_text(pobj->value, (char *)(pobj->param_data + pobj->param->offset));
621 }
622 else
623 xine_error(_("parameter type POST_PARAM_TYPE_STRING not supported yet.\n"));
624
625 }
626
_pplugin_set_param_stringlist(xitk_widget_t * w,void * data,int value)627 static void _pplugin_set_param_stringlist(xitk_widget_t *w, void *data, int value) {
628 post_object_t *pobj = (post_object_t *) data;
629
630 if(pobj->readonly)
631 return;
632
633 xine_error(_("parameter type POST_PARAM_TYPE_STRINGLIST not supported yet.\n"));
634 }
635
_pplugin_set_param_bool(xitk_widget_t * w,void * data,int state)636 static void _pplugin_set_param_bool(xitk_widget_t *w, void *data, int state) {
637 post_object_t *pobj = (post_object_t *) data;
638
639 if(pobj->readonly)
640 return;
641
642 *(int *)(pobj->param_data + pobj->param->offset) = state;
643 _pplugin_update_parameter(pobj);
644 xitk_checkbox_set_state(pobj->value,
645 (*(int *)(pobj->param_data + pobj->param->offset)));
646 }
647
_pplugin_add_parameter_widget(_pp_wrapper_t * pp_wrapper,post_object_t * pobj)648 static void _pplugin_add_parameter_widget(_pp_wrapper_t *pp_wrapper, post_object_t *pobj) {
649 gGui_t *gui = gGui;
650
651 if(pobj) {
652 xitk_label_widget_t lb;
653 char buffer[2048];
654
655 snprintf(buffer, sizeof(buffer), "%s:", (pobj->param->description)
656 ? pobj->param->description : _("No description available"));
657
658 XITK_WIDGET_INIT(&lb, gui->imlib_data);
659 lb.window = xitk_window_get_window(pp_wrapper->pplugin->xwin);
660 lb.gc = (XITK_WIDGET_LIST_GC(pp_wrapper->pplugin->widget_list));
661 lb.skin_element_name = NULL;
662 lb.label = buffer;
663 lb.callback = NULL;
664 lb.userdata = NULL;
665 pobj->comment = xitk_noskin_label_create (pp_wrapper->pplugin->widget_list, &lb,
666 0, 0, FRAME_WIDTH - (26 + 6 + 6), 20, hboldfontname);
667 xitk_add_widget (pp_wrapper->pplugin->widget_list, pobj->comment);
668
669 switch(pobj->param->type) {
670 case POST_PARAM_TYPE_INT:
671 {
672 if(pobj->param->enum_values) {
673 xitk_combo_widget_t cmb;
674
675 XITK_WIDGET_INIT(&cmb, gui->imlib_data);
676 cmb.skin_element_name = NULL;
677 cmb.layer_above = (is_layer_above());
678 cmb.parent_wlist = pp_wrapper->pplugin->widget_list;
679 cmb.entries = (const char **)pobj->param->enum_values;
680 cmb.parent_wkey = &pp_wrapper->pplugin->widget_key;
681 cmb.callback = _pplugin_set_param_int;
682 cmb.userdata = pobj;
683 pobj->value = xitk_noskin_combo_create (pp_wrapper->pplugin->widget_list, &cmb,
684 0, 0, 365, NULL, NULL);
685 xitk_add_widget (pp_wrapper->pplugin->widget_list, pobj->value);
686 xitk_combo_set_select(pobj->value, *(int *)(pobj->param_data + pobj->param->offset));
687 }
688 else {
689 xitk_intbox_widget_t ib;
690
691 XITK_WIDGET_INIT(&ib, gui->imlib_data);
692 ib.skin_element_name = NULL;
693 ib.value = *(int *)(pobj->param_data + pobj->param->offset);
694 ib.step = 1;
695 ib.parent_wlist = pp_wrapper->pplugin->widget_list;
696 ib.callback = _pplugin_set_param_int;
697 ib.userdata = pobj;
698 pobj->value = xitk_noskin_intbox_create (pp_wrapper->pplugin->widget_list, &ib,
699 0, 0, 50, 20, NULL, NULL, NULL);
700 xitk_add_widget (pp_wrapper->pplugin->widget_list, pobj->value);
701 }
702 }
703 break;
704
705 case POST_PARAM_TYPE_DOUBLE:
706 {
707 xitk_doublebox_widget_t ib;
708
709 XITK_WIDGET_INIT(&ib, gui->imlib_data);
710 ib.skin_element_name = NULL;
711 ib.value = *(double *)(pobj->param_data + pobj->param->offset);
712 ib.step = .5;
713 ib.parent_wlist = pp_wrapper->pplugin->widget_list;
714 ib.callback = _pplugin_set_param_double;
715 ib.userdata = pobj;
716 pobj->value = xitk_noskin_doublebox_create (pp_wrapper->pplugin->widget_list, &ib,
717 0, 0, 100, 20, NULL, NULL, NULL);
718 xitk_add_widget (pp_wrapper->pplugin->widget_list, pobj->value);
719 }
720 break;
721
722 case POST_PARAM_TYPE_CHAR:
723 case POST_PARAM_TYPE_STRING:
724 {
725 xitk_inputtext_widget_t inp;
726
727 XITK_WIDGET_INIT(&inp, gui->imlib_data);
728 inp.skin_element_name = NULL;
729 inp.text = (char *)(pobj->param_data + pobj->param->offset);
730 inp.max_length = 256;
731 inp.callback = _pplugin_set_param_char;
732 inp.userdata = pobj;
733 pobj->value = xitk_noskin_inputtext_create (pp_wrapper->pplugin->widget_list, &inp,
734 0, 0, 365, 20, "Black", "Black", fontname);
735 xitk_add_widget (pp_wrapper->pplugin->widget_list, pobj->value);
736 }
737 break;
738
739 case POST_PARAM_TYPE_STRINGLIST:
740 {
741 xitk_combo_widget_t cmb;
742
743 XITK_WIDGET_INIT(&cmb, gui->imlib_data);
744 cmb.skin_element_name = NULL;
745 cmb.layer_above = (is_layer_above());
746 cmb.parent_wlist = pp_wrapper->pplugin->widget_list;
747 cmb.entries = (const char **)(pobj->param_data + pobj->param->offset);
748 cmb.parent_wkey = &pp_wrapper->pplugin->widget_key;
749 cmb.callback = _pplugin_set_param_stringlist;
750 cmb.userdata = pobj;
751 pobj->value = xitk_noskin_combo_create (pp_wrapper->pplugin->widget_list, &cmb,
752 0, 0, 365, NULL, NULL);
753 xitk_add_widget (pp_wrapper->pplugin->widget_list, pobj->value);
754 xitk_combo_set_select(pobj->value, *(int *)(pobj->param_data + pobj->param->offset));
755 }
756 break;
757
758 case POST_PARAM_TYPE_BOOL:
759 {
760 xitk_checkbox_widget_t cb;
761
762 XITK_WIDGET_INIT(&cb, gui->imlib_data);
763 cb.skin_element_name = NULL;
764 cb.callback = _pplugin_set_param_bool;
765 cb.userdata = pobj;
766 pobj->value = xitk_noskin_checkbox_create (pp_wrapper->pplugin->widget_list, &cb, 0, 0, 12, 12);
767 xitk_add_widget (pp_wrapper->pplugin->widget_list, pobj->value);
768 xitk_checkbox_set_state(pobj->value,
769 (*(int *)(pobj->param_data + pobj->param->offset)));
770 }
771 break;
772 }
773 }
774 }
775
_pplugin_change_parameter(_pp_wrapper_t * pp_wrapper,xitk_widget_t * w,void * data,int select)776 static void _pplugin_change_parameter(_pp_wrapper_t *pp_wrapper, xitk_widget_t *w, void *data, int select) {
777 post_object_t *pobj = (post_object_t *) data;
778
779 if(pobj) {
780
781 _pplugin_destroy_widget (&pobj->value);
782 _pplugin_destroy_widget (&pobj->comment);
783
784 if(pobj->descr) {
785 pobj->param = pobj->descr->parameter;
786 pobj->param += select;
787 pobj->readonly = pobj->param->readonly;
788 _pplugin_add_parameter_widget(pp_wrapper, pobj);
789 }
790
791 _pplugin_paint_widgets(pp_wrapper);
792 }
793 }
794
_vpplugin_change_parameter(xitk_widget_t * w,void * data,int select)795 static void _vpplugin_change_parameter(xitk_widget_t *w, void *data, int select) {
796 return _pplugin_change_parameter(&vpp_wrapper, w, data, select);
797 }
798
_applugin_change_parameter(xitk_widget_t * w,void * data,int select)799 static void _applugin_change_parameter(xitk_widget_t *w, void *data, int select) {
800 return _pplugin_change_parameter(&app_wrapper, w, data, select);
801 }
802
_pplugin_get_plugins(_pp_wrapper_t * pp_wrapper)803 static void _pplugin_get_plugins(_pp_wrapper_t *pp_wrapper) {
804 int plugin_type = (pp_wrapper == &vpp_wrapper) ? XINE_POST_TYPE_VIDEO_FILTER : XINE_POST_TYPE_AUDIO_FILTER;
805 const char *const *pol = xine_list_post_plugins_typed(__xineui_global_xine_instance, plugin_type);
806
807 if(pol) {
808 int i = 0;
809
810 pp_wrapper->pplugin->plugin_names = (char **) malloc(sizeof(char *) * 2);
811 pp_wrapper->pplugin->plugin_names[i] = strdup(_("No Filter"));
812 while(pol[i]) {
813 pp_wrapper->pplugin->plugin_names = (char **) realloc(pp_wrapper->pplugin->plugin_names, sizeof(char *) * (i + 1 + 2));
814
815 pp_wrapper->pplugin->plugin_names[i + 1] = strdup(pol[i]);
816 i++;
817 }
818 pp_wrapper->pplugin->plugin_names[i + 1] = NULL;
819 }
820 }
821
_pplugin_destroy_only_obj(_pp_wrapper_t * pp_wrapper,post_object_t * pobj)822 static void _pplugin_destroy_only_obj(_pp_wrapper_t *pp_wrapper, post_object_t *pobj) {
823 if(pobj) {
824
825 if(pobj->properties) {
826
827 _pplugin_destroy_widget (&pobj->properties);
828
829 VFREE(pobj->param_data);
830 pobj->param_data = NULL;
831
832 if(pobj->properties_names) {
833 int pnum = 0;
834
835 while(pobj->properties_names[pnum]) {
836 free(pobj->properties_names[pnum]);
837 pnum++;
838 }
839
840 free(pobj->properties_names);
841 pobj->properties_names = NULL;
842 }
843 }
844
845 _pplugin_destroy_widget (&pobj->comment);
846 _pplugin_destroy_widget (&pobj->value);
847
848 if(pobj->api && pobj->help) {
849 if(pp_wrapper->pplugin->help_running)
850 _pplugin_close_help(pp_wrapper, NULL,NULL);
851 _pplugin_destroy_widget (&pobj->help);
852 }
853
854 }
855 }
856
__pplugin_retrieve_parameters(post_object_t * pobj)857 static int __pplugin_retrieve_parameters(post_object_t *pobj) {
858 xine_post_in_t *input_api;
859
860 if((input_api = (xine_post_in_t *) xine_post_input(pobj->post, "parameters"))) {
861 const xine_post_api_t *post_api;
862 const xine_post_api_descr_t *api_descr;
863 const xine_post_api_parameter_t *parm;
864 int pnum = 0;
865
866 post_api = (const xine_post_api_t *) input_api->data;
867
868 api_descr = post_api->get_param_descr();
869
870 parm = api_descr->parameter;
871 pobj->param_data = malloc(api_descr->struct_size);
872 post_api->get_parameters(pobj->post, pobj->param_data);
873
874 while(parm->type != POST_PARAM_TYPE_LAST) {
875
876 pobj->properties_names = (char **) realloc(pobj->properties_names, sizeof(char *) * (pnum + 2));
877
878 pobj->properties_names[pnum] = strdup(parm->name);
879 pobj->properties_names[pnum + 1] = NULL;
880 pnum++;
881 parm++;
882 }
883
884 pobj->api = post_api;
885 pobj->descr = api_descr;
886 pobj->param = api_descr->parameter;
887
888 return 1;
889 }
890
891 return 0;
892 }
893
_pplugin_close_help(_pp_wrapper_t * pp_wrapper,xitk_widget_t * w,void * data)894 static void _pplugin_close_help(_pp_wrapper_t *pp_wrapper, xitk_widget_t *w, void *data) {
895 gGui_t *gui = gGui;
896
897 pp_wrapper->pplugin->help_running = 0;
898
899 xitk_unregister_event_handler(&pp_wrapper->pplugin->help_widget_key);
900
901 xitk_destroy_widgets(pp_wrapper->pplugin->help_widget_list);
902 xitk_window_destroy_window(gui->imlib_data, pp_wrapper->pplugin->helpwin);
903
904 pp_wrapper->pplugin->helpwin = NULL;
905 /* xitk_dlist_init (&pp_wrapper->pplugin->help_widget_list->list); */
906
907 gui->x_lock_display (gui->display);
908 XFreeGC(gui->display, (XITK_WIDGET_LIST_GC(pp_wrapper->pplugin->help_widget_list)));
909 gui->x_unlock_display (gui->display);
910
911 XITK_WIDGET_LIST_FREE(pp_wrapper->pplugin->help_widget_list);
912 }
913
_vpplugin_close_help(xitk_widget_t * w,void * data)914 static void _vpplugin_close_help(xitk_widget_t *w, void *data) {
915 _pplugin_close_help(&vpp_wrapper, w, data);
916 }
917
_applugin_close_help(xitk_widget_t * w,void * data)918 static void _applugin_close_help(xitk_widget_t *w, void *data) {
919 _pplugin_close_help(&app_wrapper, w, data);
920 }
921
_pplugin_help_handle_event(_pp_wrapper_t * pp_wrapper,XEvent * event,void * data)922 static void _pplugin_help_handle_event(_pp_wrapper_t *pp_wrapper, XEvent *event, void *data) {
923
924 if(event->type == KeyPress) {
925 if(xitk_get_key_pressed(event) == XK_Escape)
926 _pplugin_close_help(pp_wrapper, NULL, NULL);
927 else
928 gui_handle_event (event, gGui);
929 }
930 }
931
_vpplugin_help_handle_event(XEvent * event,void * data)932 static void _vpplugin_help_handle_event(XEvent *event, void *data) {
933 _pplugin_help_handle_event(&vpp_wrapper, event, data);
934 }
935
_applugin_help_handle_event(XEvent * event,void * data)936 static void _applugin_help_handle_event(XEvent *event, void *data) {
937 _pplugin_help_handle_event(&app_wrapper, event, data);
938 }
939
__line_wrap(char * s,int pos,int line_size)940 static int __line_wrap(char *s, int pos, int line_size)
941 {
942 int word_size = 0;
943
944 while( *s && *s != '\t' && *s != ' ' && *s != '\n' ) {
945 s++;
946 word_size++;
947 }
948
949 if( word_size >= line_size )
950 return pos > line_size;
951
952 return word_size + pos > line_size;
953 }
954
_pplugin_show_help(_pp_wrapper_t * pp_wrapper,xitk_widget_t * w,void * data)955 static void _pplugin_show_help(_pp_wrapper_t *pp_wrapper, xitk_widget_t *w, void *data) {
956 gGui_t *gui = gGui;
957 post_object_t *pobj = (post_object_t *) data;
958 GC gc;
959 xitk_pixmap_t *bg = NULL;
960 int x, y, width, height;
961 xitk_labelbutton_widget_t lb;
962 xitk_browser_widget_t br;
963
964 if(!pobj->api) {
965 if(pp_wrapper->pplugin->help_running)
966 _pplugin_close_help(pp_wrapper, NULL, NULL);
967 return;
968 }
969
970 /* create help window if needed */
971
972 if( !pp_wrapper->pplugin->help_running ) {
973 x = y = 80;
974 pp_wrapper->pplugin->helpwin = xitk_window_create_dialog_window(gui->imlib_data,
975 _("Plugin Help"), x, y,
976 HELP_WINDOW_WIDTH, HELP_WINDOW_HEIGHT);
977
978 set_window_states_start((xitk_window_get_window(pp_wrapper->pplugin->helpwin)));
979
980 gui->x_lock_display (gui->display);
981 gc = XCreateGC(gui->display,
982 (xitk_window_get_window(pp_wrapper->pplugin->helpwin)), None, None);
983 gui->x_unlock_display (gui->display);
984
985 pp_wrapper->pplugin->help_widget_list = xitk_widget_list_new();
986 xitk_widget_list_set(pp_wrapper->pplugin->help_widget_list,
987 WIDGET_LIST_WINDOW, (void *) (xitk_window_get_window(pp_wrapper->pplugin->helpwin)));
988 xitk_widget_list_set(pp_wrapper->pplugin->help_widget_list, WIDGET_LIST_GC, gc);
989
990 xitk_window_get_window_size(pp_wrapper->pplugin->helpwin, &width, &height);
991 bg = xitk_image_create_xitk_pixmap(gui->imlib_data, width, height);
992
993 gui->x_lock_display (gui->display);
994 XCopyArea(gui->display, (xitk_window_get_background(pp_wrapper->pplugin->helpwin)), bg->pixmap,
995 bg->gc, 0, 0, width, height, 0, 0);
996 gui->x_unlock_display (gui->display);
997
998 XITK_WIDGET_INIT(&lb, gui->imlib_data);
999 lb.button_type = CLICK_BUTTON;
1000 lb.label = _("Close");
1001 lb.align = ALIGN_CENTER;
1002 lb.callback = (pp_wrapper == &vpp_wrapper) ? _vpplugin_close_help : _applugin_close_help;
1003 lb.state_callback = NULL;
1004 lb.userdata = NULL;
1005 lb.skin_element_name = NULL;
1006 w = xitk_noskin_labelbutton_create (pp_wrapper->pplugin->help_widget_list,
1007 &lb, HELP_WINDOW_WIDTH - (100 + 15), HELP_WINDOW_HEIGHT - (23 + 15), 100, 23,
1008 "Black", "Black", "White", btnfontname);
1009 xitk_add_widget (pp_wrapper->pplugin->help_widget_list, w);
1010 xitk_enable_and_show_widget(w);
1011
1012
1013 XITK_WIDGET_INIT(&br, gui->imlib_data);
1014 br.arrow_up.skin_element_name = NULL;
1015 br.slider.skin_element_name = NULL;
1016 br.arrow_dn.skin_element_name = NULL;
1017 br.browser.skin_element_name = NULL;
1018 br.browser.max_displayed_entries = MAX_DISP_ENTRIES;
1019 br.browser.num_entries = 0;
1020 br.browser.entries = NULL;
1021 br.callback = NULL;
1022 br.dbl_click_callback = NULL;
1023 br.parent_wlist = pp_wrapper->pplugin->help_widget_list;
1024 br.userdata = NULL;
1025 pp_wrapper->pplugin->help_browser = xitk_noskin_browser_create (pp_wrapper->pplugin->help_widget_list,
1026 &br, (XITK_WIDGET_LIST_GC(pp_wrapper->pplugin->help_widget_list)), 15, 34,
1027 HELP_WINDOW_WIDTH - (30 + 16), 20, 16, br_fontname);
1028 xitk_add_widget (pp_wrapper->pplugin->help_widget_list, pp_wrapper->pplugin->help_browser);
1029 }
1030
1031 /* load text to the browser widget */
1032 {
1033 char *p, **hbuf = NULL;
1034 int lines = 0, i;
1035
1036 p = pobj->api->get_help();
1037
1038 do {
1039 char c, *old_p = p, *new_p;
1040 int w;
1041
1042 for(w = 0; !__line_wrap(p,w,BROWSER_LINE_WIDTH) && (c = *p++) != 0 && c != '\n'; w++)
1043 if (c == '\t') {
1044 w = (w + 1) | 7; /* allow for loop increment */
1045 if (w >= BROWSER_LINE_WIDTH)
1046 w = BROWSER_LINE_WIDTH - 1;
1047 }
1048
1049 hbuf = (char **) realloc(hbuf, sizeof(char *) * (lines + 2));
1050 hbuf[lines] = malloc(w + 2);
1051 hbuf[lines+1] = NULL;
1052
1053 new_p = p;
1054 p = old_p;
1055 for(i = 0; i < w; i++)
1056 switch (c = *p++) {
1057 case '\0':
1058 case '\n':
1059 hbuf[lines][i] = '\0';
1060 i = w;
1061 break;
1062 case '\t':
1063 do {
1064 hbuf[lines][i] = ' ';
1065 } while (++i & 7 && i < BROWSER_LINE_WIDTH);
1066 --i; /* allow for loop increment */
1067 break;
1068 default:
1069 hbuf[lines][i] = c;
1070 }
1071 hbuf[lines][i] = '\0';
1072 p = new_p;
1073
1074 lines++;
1075 } while( *p );
1076
1077 if(lines) {
1078 char **ohbuf = pp_wrapper->pplugin->help_text;
1079 int i = 0;
1080
1081 pp_wrapper->pplugin->help_text = hbuf;
1082 xitk_browser_update_list(pp_wrapper->pplugin->help_browser, (const char **)pp_wrapper->pplugin->help_text,
1083 NULL, lines, 0);
1084
1085 if(ohbuf) {
1086 while(ohbuf[i++])
1087 free(ohbuf[i]);
1088 free(ohbuf);
1089 }
1090 }
1091 }
1092
1093 if( !pp_wrapper->pplugin->help_running ) {
1094
1095 xitk_enable_and_show_widget(pp_wrapper->pplugin->help_browser);
1096 xitk_browser_set_alignment(pp_wrapper->pplugin->help_browser, ALIGN_LEFT);
1097
1098
1099 xitk_window_change_background(gui->imlib_data, pp_wrapper->pplugin->helpwin, bg->pixmap, width, height);
1100 xitk_image_destroy_xitk_pixmap(bg);
1101
1102 pp_wrapper->pplugin->help_widget_key = xitk_register_event_handler((pp_wrapper == &vpp_wrapper) ? "vpplugin_help" : "applugin_help",
1103 (xitk_window_get_window(pp_wrapper->pplugin->helpwin)),
1104 (pp_wrapper == &vpp_wrapper) ? _vpplugin_help_handle_event : _applugin_help_handle_event,
1105 NULL,
1106 NULL,
1107 pp_wrapper->pplugin->help_widget_list,
1108 NULL);
1109
1110 pp_wrapper->pplugin->help_running = 1;
1111 }
1112
1113 raise_window(xitk_window_get_window(pp_wrapper->pplugin->helpwin), 1, pp_wrapper->pplugin->help_running);
1114
1115 try_to_set_input_focus(xitk_window_get_window(pp_wrapper->pplugin->helpwin));
1116 }
1117
_vpplugin_show_help(xitk_widget_t * w,void * data)1118 static void _vpplugin_show_help(xitk_widget_t *w, void *data) {
1119 _pplugin_show_help(&vpp_wrapper, w, data);
1120 }
1121
_applugin_show_help(xitk_widget_t * w,void * data)1122 static void _applugin_show_help(xitk_widget_t *w, void *data) {
1123 _pplugin_show_help(&app_wrapper, w, data);
1124 }
1125
_pplugin_retrieve_parameters(_pp_wrapper_t * pp_wrapper,post_object_t * pobj)1126 static void _pplugin_retrieve_parameters(_pp_wrapper_t *pp_wrapper, post_object_t *pobj) {
1127 gGui_t *gui = gGui;
1128 xitk_combo_widget_t cmb;
1129 xitk_labelbutton_widget_t lb;
1130
1131 if(__pplugin_retrieve_parameters(pobj)) {
1132
1133 XITK_WIDGET_INIT(&cmb, gui->imlib_data);
1134 cmb.skin_element_name = NULL;
1135 cmb.layer_above = (is_layer_above());
1136 cmb.parent_wlist = pp_wrapper->pplugin->widget_list;
1137 cmb.entries = (const char **)pobj->properties_names;
1138 cmb.parent_wkey = &pp_wrapper->pplugin->widget_key;
1139 cmb.callback = (pp_wrapper == &vpp_wrapper) ? _vpplugin_change_parameter : _applugin_change_parameter;
1140 cmb.userdata = pobj;
1141 pobj->properties = xitk_noskin_combo_create (pp_wrapper->pplugin->widget_list,
1142 &cmb, 0, 0, 175, NULL, NULL);
1143 xitk_add_widget (pp_wrapper->pplugin->widget_list, pobj->properties);
1144 xitk_combo_set_select(pobj->properties, 0);
1145 xitk_combo_callback_exec(pobj->properties);
1146
1147 if(pobj->api && pobj->api->get_help) {
1148
1149 XITK_WIDGET_INIT(&lb, gui->imlib_data);
1150 lb.button_type = CLICK_BUTTON;
1151 lb.label = _("Help");
1152 lb.align = ALIGN_CENTER;
1153 lb.callback = (pp_wrapper == &vpp_wrapper) ? _vpplugin_show_help : _applugin_show_help;
1154 lb.state_callback = NULL;
1155 lb.userdata = pobj;
1156 lb.skin_element_name = NULL;
1157 pobj->help = xitk_noskin_labelbutton_create (pp_wrapper->pplugin->widget_list,
1158 &lb, 0, 0, 63, 20, "Black", "Black", "White", btnfontname);
1159 xitk_add_widget (pp_wrapper->pplugin->widget_list, pobj->help);
1160 }
1161 }
1162 else {
1163 xitk_label_widget_t lb;
1164
1165 XITK_WIDGET_INIT(&lb, gui->imlib_data);
1166 lb.window = xitk_window_get_window(pp_wrapper->pplugin->xwin);
1167 lb.gc = (XITK_WIDGET_LIST_GC(pp_wrapper->pplugin->widget_list));
1168 lb.skin_element_name = NULL;
1169 lb.label = _("There is no parameter available for this plugin.");
1170 lb.callback = NULL;
1171 lb.userdata = NULL;
1172 pobj->comment = xitk_noskin_label_create (pp_wrapper->pplugin->widget_list, &lb,
1173 0, 0, FRAME_WIDTH - (26 + 6 + 6), 20, hboldfontname);
1174 xitk_add_widget (pp_wrapper->pplugin->widget_list, pobj->comment);
1175 pobj->properties = NULL;
1176 }
1177 }
1178
1179 static post_object_t *_pplugin_create_filter_object (_pp_wrapper_t *pp_wrapper);
1180
_pplugin_select_filter(_pp_wrapper_t * pp_wrapper,xitk_widget_t * w,void * data,int select)1181 static void _pplugin_select_filter(_pp_wrapper_t *pp_wrapper, xitk_widget_t *w, void *data, int select) {
1182 gGui_t *gui = gGui;
1183 post_object_t *pobj = (post_object_t *) data;
1184 post_object_t **p = pp_wrapper->pplugin->post_objects;
1185 int n;
1186
1187 _pplugin_unwire(pp_wrapper);
1188
1189 for (n = 0; p[n] && (p[n] != pobj); n++) ;
1190 if (!select) {
1191 /* User selected first line which is "No filter". Reset this one, and kill everything thereafter. */
1192 if (p[n]) {
1193 _pplugin_destroy_only_obj (pp_wrapper, pobj);
1194 if (pobj->post) {
1195 xine_post_dispose (__xineui_global_xine_instance, pobj->post);
1196 pobj->post = NULL;
1197 }
1198 n++;
1199 pp_wrapper->pplugin->object_num = n;
1200 while (p[n]) {
1201 _pplugin_destroy_only_obj (pp_wrapper, p[n]);
1202 if (p[n]->post) {
1203 xine_post_dispose (__xineui_global_xine_instance, p[n]->post);
1204 p[n]->post = NULL;
1205 }
1206 _pplugin_destroy_widget (&p[n]->plugins);
1207 _pplugin_destroy_widget (&p[n]->frame);
1208 _pplugin_destroy_widget (&p[n]->up);
1209 _pplugin_destroy_widget (&p[n]->down);
1210 VFREE (p[n]);
1211 p[n] = NULL;
1212 n++;
1213 }
1214 _pplugin_send_expose (pp_wrapper);
1215 }
1216 if(pp_wrapper->pplugin->object_num <= MAX_DISPLAY_FILTERS)
1217 pp_wrapper->pplugin->first_displayed = 0;
1218 else if((pp_wrapper->pplugin->object_num - pp_wrapper->pplugin->first_displayed) < MAX_DISPLAY_FILTERS)
1219 pp_wrapper->pplugin->first_displayed = pp_wrapper->pplugin->object_num - MAX_DISPLAY_FILTERS;
1220 } else {
1221 /* Some filter has been selected. Kill old one and set new. */
1222 _pplugin_destroy_only_obj (pp_wrapper, pobj);
1223 if (pobj->post) {
1224 xine_post_dispose (__xineui_global_xine_instance, pobj->post);
1225 pobj->post = NULL;
1226 }
1227 pobj->post = xine_post_init (__xineui_global_xine_instance,
1228 xitk_combo_get_current_entry_selected (w), 0, &gui->ao_port, &gui->vo_port);
1229 _pplugin_retrieve_parameters (pp_wrapper, pobj);
1230 /* If this is the last filter, add a new "No filter" thereafter. */
1231 if ((n < MAX_USED_FILTERS - 1) && (n + 1 == pp_wrapper->pplugin->object_num)) {
1232 _pplugin_create_filter_object (pp_wrapper);
1233 }
1234 }
1235
1236 if(pp_wrapper->pplugin->help_running)
1237 _pplugin_show_help(pp_wrapper, NULL, pobj);
1238
1239 _pplugin_rewire(pp_wrapper);
1240 _pplugin_paint_widgets(pp_wrapper);
1241 }
1242
_vpplugin_select_filter(xitk_widget_t * w,void * data,int select)1243 static void _vpplugin_select_filter(xitk_widget_t *w, void *data, int select) {
1244 _pplugin_select_filter(&vpp_wrapper, w, data, select);
1245 }
1246
_applugin_select_filter(xitk_widget_t * w,void * data,int select)1247 static void _applugin_select_filter(xitk_widget_t *w, void *data, int select) {
1248 _pplugin_select_filter(&app_wrapper, w, data, select);
1249 }
1250
_pplugin_move_up(_pp_wrapper_t * pp_wrapper,xitk_widget_t * w,void * data)1251 static void _pplugin_move_up(_pp_wrapper_t *pp_wrapper, xitk_widget_t *w, void *data) {
1252 post_object_t *pobj = (post_object_t *) data;
1253 post_object_t **ppobj = pp_wrapper->pplugin->post_objects;
1254
1255 _pplugin_unwire(pp_wrapper);
1256
1257 while(*ppobj != pobj)
1258 ppobj++;
1259
1260 *ppobj = *(ppobj - 1);
1261 *(ppobj - 1) = pobj;
1262
1263 _pplugin_rewire(pp_wrapper);
1264 _pplugin_paint_widgets(pp_wrapper);
1265 }
1266
_vpplugin_move_up(xitk_widget_t * w,void * data)1267 static void _vpplugin_move_up(xitk_widget_t *w, void *data) {
1268 _pplugin_move_up(&vpp_wrapper, w, data);
1269 }
1270
_applugin_move_up(xitk_widget_t * w,void * data)1271 static void _applugin_move_up(xitk_widget_t *w, void *data) {
1272 _pplugin_move_up(&app_wrapper, w, data);
1273 }
1274
_pplugin_move_down(_pp_wrapper_t * pp_wrapper,xitk_widget_t * w,void * data)1275 static void _pplugin_move_down(_pp_wrapper_t *pp_wrapper, xitk_widget_t *w, void *data) {
1276 post_object_t *pobj = (post_object_t *) data;
1277 post_object_t **ppobj = pp_wrapper->pplugin->post_objects;
1278
1279 _pplugin_unwire(pp_wrapper);
1280
1281 while(*ppobj != pobj)
1282 ppobj++;
1283
1284 *ppobj = *(ppobj + 1);
1285 *(ppobj + 1) = pobj;
1286
1287 _pplugin_rewire(pp_wrapper);
1288 _pplugin_paint_widgets(pp_wrapper);
1289 }
1290
_vpplugin_move_down(xitk_widget_t * w,void * data)1291 static void _vpplugin_move_down(xitk_widget_t *w, void *data) {
1292 _pplugin_move_down(&vpp_wrapper, w, data);
1293 }
1294
_applugin_move_down(xitk_widget_t * w,void * data)1295 static void _applugin_move_down(xitk_widget_t *w, void *data) {
1296 _pplugin_move_down(&app_wrapper, w, data);
1297 }
1298
_pplugin_create_filter_object(_pp_wrapper_t * pp_wrapper)1299 static post_object_t *_pplugin_create_filter_object (_pp_wrapper_t *pp_wrapper) {
1300 gGui_t *gui = gGui;
1301 xitk_combo_widget_t cmb;
1302 post_object_t *pobj;
1303 xitk_image_widget_t im;
1304 xitk_image_t *image;
1305 xitk_button_widget_t b;
1306
1307 if (pp_wrapper->pplugin->object_num >= MAX_USED_FILTERS - 1)
1308 return NULL;
1309 pobj = calloc (1, sizeof (post_object_t));
1310 if (!pobj)
1311 return NULL;
1312
1313 pp_wrapper->pplugin->x = 15;
1314 pp_wrapper->pplugin->y += FRAME_HEIGHT + 4;
1315
1316 pp_wrapper->pplugin->post_objects[pp_wrapper->pplugin->object_num] = pobj;
1317 pobj->x = pp_wrapper->pplugin->x;
1318 pobj->y = pp_wrapper->pplugin->y;
1319 pp_wrapper->pplugin->object_num++;
1320
1321 image = xitk_image_create_image(gui->imlib_data, FRAME_WIDTH + 1, FRAME_HEIGHT + 1);
1322
1323 gui->x_lock_display (gui->display);
1324 XSetForeground(gui->display, (XITK_WIDGET_LIST_GC(pp_wrapper->pplugin->widget_list)),
1325 xitk_get_pixel_color_gray(gui->imlib_data));
1326 XFillRectangle(gui->display, image->image->pixmap,
1327 (XITK_WIDGET_LIST_GC(pp_wrapper->pplugin->widget_list)),
1328 0, 0, image->width, image->height);
1329 gui->x_unlock_display (gui->display);
1330
1331 /* Some decorations */
1332 draw_outter_frame(gui->imlib_data, image->image, NULL, NULL,
1333 0, 0, FRAME_WIDTH, FRAME_HEIGHT);
1334 draw_rectangular_outter_box_light(gui->imlib_data, image->image,
1335 27, 28, FRAME_WIDTH - 27 - 5, 1);
1336 draw_rectangular_outter_box_light(gui->imlib_data, image->image,
1337 26, 5, 1, FRAME_HEIGHT - 10);
1338 draw_inner_frame(gui->imlib_data, image->image, NULL, NULL,
1339 5, 5, 16, 16);
1340 draw_rectangular_inner_box_light(gui->imlib_data, image->image,
1341 5, 24, 1, FRAME_HEIGHT - 48);
1342 draw_rectangular_inner_box_light(gui->imlib_data, image->image,
1343 10, 24, 1, FRAME_HEIGHT - 48);
1344 draw_rectangular_inner_box_light(gui->imlib_data, image->image,
1345 15, 24, 1, FRAME_HEIGHT - 48);
1346 draw_rectangular_inner_box_light(gui->imlib_data, image->image,
1347 20, 24, 1, FRAME_HEIGHT - 48);
1348 draw_inner_frame(gui->imlib_data, image->image, NULL, NULL,
1349 5, FRAME_HEIGHT - 16 - 5, 16, 16);
1350
1351 XITK_WIDGET_INIT(&im, gui->imlib_data);
1352 im.skin_element_name = NULL;
1353 pobj->frame = xitk_noskin_image_create (pp_wrapper->pplugin->widget_list, &im, image, pobj->x - 5, pobj->y - 5);
1354 xitk_add_widget (pp_wrapper->pplugin->widget_list, pobj->frame);
1355
1356 DISABLE_ME(pobj->frame);
1357
1358 XITK_WIDGET_INIT(&cmb, gui->imlib_data);
1359 cmb.skin_element_name = NULL;
1360 cmb.layer_above = (is_layer_above());
1361 cmb.parent_wlist = pp_wrapper->pplugin->widget_list;
1362 cmb.entries = (const char **)pp_wrapper->pplugin->plugin_names;
1363 cmb.parent_wkey = &pp_wrapper->pplugin->widget_key;
1364 cmb.callback = (pp_wrapper == &vpp_wrapper) ? _vpplugin_select_filter : _applugin_select_filter;
1365 cmb.userdata = pobj;
1366 pobj->plugins = xitk_noskin_combo_create (pp_wrapper->pplugin->widget_list,
1367 &cmb, 0, 0, 175, NULL, NULL);
1368 xitk_add_widget (pp_wrapper->pplugin->widget_list, pobj->plugins);
1369 DISABLE_ME(pobj->plugins);
1370 xitk_combo_set_select(pobj->plugins, 0);
1371
1372 {
1373 xitk_image_t *bimage;
1374
1375 XITK_WIDGET_INIT(&b, gui->imlib_data);
1376 b.skin_element_name = NULL;
1377 b.callback = (pp_wrapper == &vpp_wrapper) ? _vpplugin_move_up : _applugin_move_up;
1378 b.userdata = pobj;
1379 pobj->up = xitk_noskin_button_create (pp_wrapper->pplugin->widget_list, &b, 0, 0, 17, 17);
1380 xitk_add_widget (pp_wrapper->pplugin->widget_list, pobj->up);
1381 DISABLE_ME(pobj->up);
1382
1383 if((bimage = xitk_get_widget_foreground_skin(pobj->up)) != NULL)
1384 draw_arrow_up(gui->imlib_data, bimage);
1385
1386 b.skin_element_name = NULL;
1387 b.callback = (pp_wrapper == &vpp_wrapper) ? _vpplugin_move_down : _applugin_move_down;
1388 b.userdata = pobj;
1389 pobj->down = xitk_noskin_button_create (pp_wrapper->pplugin->widget_list, &b, 0, 0, 17, 17);
1390 xitk_add_widget (pp_wrapper->pplugin->widget_list, pobj->down);
1391 DISABLE_ME(pobj->down);
1392
1393 if((bimage = xitk_get_widget_foreground_skin(pobj->down)) != NULL)
1394 draw_arrow_down(gui->imlib_data, bimage);
1395
1396 }
1397 return pobj;
1398 }
1399
_pplugin_rebuild_filters(_pp_wrapper_t * pp_wrapper)1400 static int _pplugin_rebuild_filters(_pp_wrapper_t *pp_wrapper) {
1401 gGui_t *gui = gGui;
1402 post_element_t **pelem = (pp_wrapper == &vpp_wrapper) ? gui->post_video_elements : gui->post_audio_elements;
1403 int plugin_type = (pp_wrapper == &vpp_wrapper) ? XINE_POST_TYPE_VIDEO_FILTER : XINE_POST_TYPE_AUDIO_FILTER;
1404 int num_filters = 0;
1405
1406 while(pelem && *pelem) {
1407 int i = 0;
1408
1409 if ((*pelem)->post->type == plugin_type) {
1410 num_filters++;
1411
1412 if (!_pplugin_create_filter_object (pp_wrapper))
1413 break;
1414 pp_wrapper->pplugin->post_objects[pp_wrapper->pplugin->object_num - 1]->post = (*pelem)->post;
1415
1416 while(pp_wrapper->pplugin->plugin_names[i] && strcasecmp(pp_wrapper->pplugin->plugin_names[i], (*pelem)->name))
1417 i++;
1418
1419 if(pp_wrapper->pplugin->plugin_names[i]) {
1420 xitk_combo_set_select(pp_wrapper->pplugin->post_objects[pp_wrapper->pplugin->object_num - 1]->plugins, i);
1421
1422 _pplugin_retrieve_parameters(pp_wrapper, pp_wrapper->pplugin->post_objects[pp_wrapper->pplugin->object_num - 1]);
1423 }
1424 }
1425
1426 pelem++;
1427 }
1428 /* Always have 1 "No filter" at the end for later extension. */
1429 _pplugin_create_filter_object (pp_wrapper);
1430
1431 _pplugin_paint_widgets(pp_wrapper);
1432
1433 return num_filters;
1434 }
1435
_pplugin_join_deinterlace_and_post_elements(int * post_elements_num)1436 static post_element_t **_pplugin_join_deinterlace_and_post_elements(int *post_elements_num) {
1437 gGui_t *gui = gGui;
1438 post_element_t **post_elements;
1439 int i = 0, j = 0;
1440
1441 *post_elements_num = 0;
1442 if( gui->post_video_enable )
1443 (*post_elements_num) += gui->post_video_elements_num;
1444 if( gui->deinterlace_enable )
1445 (*post_elements_num) += gui->deinterlace_elements_num;
1446
1447 if( *post_elements_num == 0 )
1448 return NULL;
1449
1450 post_elements = (post_element_t **)
1451 calloc((*post_elements_num), sizeof(post_element_t *));
1452
1453 for( i = 0; gui->deinterlace_enable && i < gui->deinterlace_elements_num; i++ ) {
1454 post_elements[i+j] = gui->deinterlace_elements[i];
1455 }
1456
1457 for( j = 0; gui->post_video_enable && j < gui->post_video_elements_num; j++ ) {
1458 post_elements[i+j] = gui->post_video_elements[j];
1459 }
1460
1461 return post_elements;
1462 }
1463
1464
_pplugin_join_visualization_and_post_elements(int * post_elements_num)1465 static post_element_t **_pplugin_join_visualization_and_post_elements(int *post_elements_num) {
1466 gGui_t *gui = gGui;
1467 post_element_t **post_elements;
1468 int i = 0, j = 0;
1469
1470 *post_elements_num = 0;
1471 if( gui->post_audio_enable )
1472 (*post_elements_num) += gui->post_audio_elements_num;
1473 if( !ignore_visual_anim )
1474 (*post_elements_num)++;
1475
1476 if( *post_elements_num == 0 )
1477 return NULL;
1478
1479 post_elements = (post_element_t **)
1480 calloc((*post_elements_num), sizeof(post_element_t *));
1481
1482 for( j = 0; gui->post_audio_enable && j < gui->post_audio_elements_num; j++ ) {
1483 post_elements[i+j] = gui->post_audio_elements[j];
1484 }
1485
1486 for( i = 0; !ignore_visual_anim && i < 1; i++ ) {
1487 post_elements[i+j] = &gui->visual_anim.post_output_element;
1488 }
1489
1490 return post_elements;
1491 }
1492
1493
_pplugin_save_chain(_pp_wrapper_t * pp_wrapper)1494 static void _pplugin_save_chain(_pp_wrapper_t *pp_wrapper) {
1495 gGui_t *gui = gGui;
1496
1497 if(pp_wrapper->pplugin) {
1498 post_element_t ***_post_elements = (pp_wrapper == &vpp_wrapper) ? &gui->post_video_elements : &gui->post_audio_elements;
1499 int *_post_elements_num = (pp_wrapper == &vpp_wrapper) ? &gui->post_video_elements_num : &gui->post_audio_elements_num;
1500 int i = 0;
1501 int post_num = pp_wrapper->pplugin->object_num;
1502
1503 if(!xitk_combo_get_current_selected(pp_wrapper->pplugin->post_objects[post_num - 1]->plugins))
1504 post_num--;
1505
1506 if(post_num) {
1507 if(!*_post_elements) {
1508 *_post_elements = (post_element_t **)
1509 calloc((post_num + 1), sizeof(post_element_t *));
1510 }
1511 else {
1512 int j;
1513
1514 for(j = 0; j < *_post_elements_num; j++) {
1515 free((*_post_elements)[j]->name);
1516 VFREE((*_post_elements)[j]);
1517 }
1518
1519 *_post_elements = (post_element_t **) realloc(*_post_elements, sizeof(post_element_t *) * (post_num + 1));
1520
1521 }
1522
1523 for(i = 0; i < post_num; i++) {
1524 (*_post_elements)[i] = (post_element_t *) calloc(1, sizeof(post_element_t));
1525 (*_post_elements)[i]->post = pp_wrapper->pplugin->post_objects[i]->post;
1526 (*_post_elements)[i]->name =
1527 strdup(xitk_combo_get_current_entry_selected(pp_wrapper->pplugin->post_objects[i]->plugins));
1528 }
1529
1530 (*_post_elements)[post_num] = NULL;
1531 *_post_elements_num = post_num;
1532 }
1533 else {
1534 if(*_post_elements_num) {
1535 int j;
1536
1537 for(j = 0; j < *_post_elements_num; j++) {
1538 free((*_post_elements)[j]->name);
1539 VFREE((*_post_elements)[j]);
1540 }
1541
1542 /* free((*_post_elements)[j]); */
1543 free(*_post_elements);
1544
1545 *_post_elements_num = 0;
1546 *_post_elements = NULL;
1547 }
1548 }
1549 }
1550 }
1551
_pplugin_nextprev(_pp_wrapper_t * pp_wrapper,xitk_widget_t * w,void * data,int pos)1552 static void _pplugin_nextprev(_pp_wrapper_t *pp_wrapper, xitk_widget_t *w, void *data, int pos) {
1553 int rpos = (xitk_slider_get_max(pp_wrapper->pplugin->slider)) - pos;
1554
1555 if(rpos != pp_wrapper->pplugin->first_displayed) {
1556 pp_wrapper->pplugin->first_displayed = rpos;
1557 _pplugin_paint_widgets(pp_wrapper);
1558 }
1559 }
1560
_vpplugin_nextprev(xitk_widget_t * w,void * data,int pos)1561 static void _vpplugin_nextprev(xitk_widget_t *w, void *data, int pos) {
1562 _pplugin_nextprev(&vpp_wrapper, w, data, pos);
1563 }
1564
_applugin_nextprev(xitk_widget_t * w,void * data,int pos)1565 static void _applugin_nextprev(xitk_widget_t *w, void *data, int pos) {
1566 _pplugin_nextprev(&app_wrapper, w, data, pos);
1567 }
1568
pplugin_exit(_pp_wrapper_t * pp_wrapper,xitk_widget_t * w,void * data)1569 static void pplugin_exit(_pp_wrapper_t *pp_wrapper, xitk_widget_t *w, void *data) {
1570 gGui_t *gui = gGui;
1571
1572 if(pp_wrapper->pplugin) {
1573 window_info_t wi;
1574 int i;
1575
1576 if( pp_wrapper->pplugin->help_running )
1577 _pplugin_close_help(pp_wrapper, NULL,NULL);
1578
1579 if(pp_wrapper->pplugin->help_text) {
1580 i = 0;
1581 while(pp_wrapper->pplugin->help_text[i++])
1582 free(pp_wrapper->pplugin->help_text[i]);
1583 free(pp_wrapper->pplugin->help_text);
1584 }
1585
1586 _pplugin_save_chain(pp_wrapper);
1587
1588 pp_wrapper->pplugin->running = 0;
1589 pp_wrapper->pplugin->visible = 0;
1590
1591 if((xitk_get_window_info(pp_wrapper->pplugin->widget_key, &wi))) {
1592 config_update_num ((pp_wrapper == &vpp_wrapper) ? "gui.vpplugin_x" : "gui.applugin_x", wi.x);
1593 config_update_num ((pp_wrapper == &vpp_wrapper) ? "gui.vpplugin_y" : "gui.applugin_y", wi.y);
1594 WINDOW_INFO_ZERO(&wi);
1595 }
1596
1597 {
1598 post_object_t **p = pp_wrapper->pplugin->post_objects;
1599 while (*p) {
1600 _pplugin_destroy_only_obj (pp_wrapper, *p);
1601 _pplugin_destroy_widget (&(*p)->plugins);
1602 _pplugin_destroy_widget (&(*p)->frame);
1603 _pplugin_destroy_widget (&(*p)->up);
1604 _pplugin_destroy_widget (&(*p)->down);
1605 VFREE (*p);
1606 *p = NULL;
1607 p++;
1608 }
1609 }
1610 pp_wrapper->pplugin->object_num = 0;
1611
1612 for(i = 0; pp_wrapper->pplugin->plugin_names[i]; i++)
1613 free(pp_wrapper->pplugin->plugin_names[i]);
1614
1615 free(pp_wrapper->pplugin->plugin_names);
1616
1617 xitk_unregister_event_handler(&pp_wrapper->pplugin->widget_key);
1618
1619 xitk_destroy_widgets(pp_wrapper->pplugin->widget_list);
1620 xitk_window_destroy_window(gui->imlib_data, pp_wrapper->pplugin->xwin);
1621
1622 pp_wrapper->pplugin->xwin = NULL;
1623 /* xitk_dlist_init (&pp_wrapper->pplugin->widget_list->list); */
1624
1625 gui->x_lock_display (gui->display);
1626 XFreeGC(gui->display, (XITK_WIDGET_LIST_GC(pp_wrapper->pplugin->widget_list)));
1627 gui->x_unlock_display (gui->display);
1628
1629 XITK_WIDGET_LIST_FREE(pp_wrapper->pplugin->widget_list);
1630
1631 VFREE(pp_wrapper->pplugin);
1632 pp_wrapper->pplugin = NULL;
1633
1634 try_to_set_input_focus(gui->video_window);
1635 }
1636 }
1637
vpplugin_exit(xitk_widget_t * w,void * data)1638 static void vpplugin_exit(xitk_widget_t *w, void *data) {
1639 pplugin_exit(&vpp_wrapper, w, data);
1640 }
1641
applugin_exit(xitk_widget_t * w,void * data)1642 static void applugin_exit(xitk_widget_t *w, void *data) {
1643 pplugin_exit(&app_wrapper, w, data);
1644 }
1645
_pplugin_handle_event(_pp_wrapper_t * pp_wrapper,XEvent * event,void * data)1646 static void _pplugin_handle_event(_pp_wrapper_t *pp_wrapper, XEvent *event, void *data) {
1647
1648 switch(event->type) {
1649
1650 case ButtonPress:
1651 if(event->xbutton.button == Button4) {
1652 xitk_slider_make_step(pp_wrapper->pplugin->slider);
1653 xitk_slider_callback_exec(pp_wrapper->pplugin->slider);
1654 }
1655 else if(event->xbutton.button == Button5) {
1656 xitk_slider_make_backstep(pp_wrapper->pplugin->slider);
1657 xitk_slider_callback_exec(pp_wrapper->pplugin->slider);
1658 }
1659 break;
1660
1661 case KeyPress:
1662 {
1663 KeySym mkey;
1664 int modifier;
1665
1666 xitk_get_key_modifier(event, &modifier);
1667 mkey = xitk_get_key_pressed(event);
1668
1669 switch(mkey) {
1670
1671 case XK_Up:
1672 if(xitk_is_widget_enabled(pp_wrapper->pplugin->slider) &&
1673 (modifier & 0xFFFFFFEF) == MODIFIER_NOMOD) {
1674 xitk_slider_make_step(pp_wrapper->pplugin->slider);
1675 xitk_slider_callback_exec(pp_wrapper->pplugin->slider);
1676 return;
1677 }
1678 break;
1679
1680 case XK_Down:
1681 if(xitk_is_widget_enabled(pp_wrapper->pplugin->slider) &&
1682 (modifier & 0xFFFFFFEF) == MODIFIER_NOMOD) {
1683 xitk_slider_make_backstep(pp_wrapper->pplugin->slider);
1684 xitk_slider_callback_exec(pp_wrapper->pplugin->slider);
1685 return;
1686 }
1687 break;
1688
1689 case XK_Next:
1690 if(xitk_is_widget_enabled(pp_wrapper->pplugin->slider)) {
1691 int pos, max = xitk_slider_get_max(pp_wrapper->pplugin->slider);
1692
1693 pos = max - (pp_wrapper->pplugin->first_displayed + MAX_DISPLAY_FILTERS);
1694 xitk_slider_set_pos(pp_wrapper->pplugin->slider, (pos >= 0) ? pos : 0);
1695 xitk_slider_callback_exec(pp_wrapper->pplugin->slider);
1696 return;
1697 }
1698 break;
1699
1700 case XK_Prior:
1701 if(xitk_is_widget_enabled(pp_wrapper->pplugin->slider)) {
1702 int pos, max = xitk_slider_get_max(pp_wrapper->pplugin->slider);
1703
1704 pos = max - (pp_wrapper->pplugin->first_displayed - MAX_DISPLAY_FILTERS);
1705 xitk_slider_set_pos(pp_wrapper->pplugin->slider, (pos <= max) ? pos : max);
1706 xitk_slider_callback_exec(pp_wrapper->pplugin->slider);
1707 return;
1708 }
1709 break;
1710
1711 case XK_Escape:
1712 pplugin_exit(pp_wrapper, NULL, NULL);
1713 return;
1714 }
1715 gui_handle_event (event, gGui);
1716 }
1717 break;
1718 }
1719 }
1720
_vpplugin_handle_event(XEvent * event,void * data)1721 static void _vpplugin_handle_event(XEvent *event, void *data) {
1722 _pplugin_handle_event(&vpp_wrapper, event, data);
1723 }
1724
_applugin_handle_event(XEvent * event,void * data)1725 static void _applugin_handle_event(XEvent *event, void *data) {
1726 _pplugin_handle_event(&app_wrapper, event, data);
1727 }
1728
_pplugin_enability(_pp_wrapper_t * pp_wrapper,xitk_widget_t * w,void * data,int state)1729 static void _pplugin_enability(_pp_wrapper_t *pp_wrapper, xitk_widget_t *w, void *data, int state) {
1730 gGui_t *gui = gGui;
1731 if (pp_wrapper == &vpp_wrapper)
1732 gui->post_video_enable = state;
1733 else
1734 gui->post_audio_enable = state;
1735
1736 _pplugin_unwire(pp_wrapper);
1737 _pplugin_rewire(pp_wrapper);
1738 }
1739
_vpplugin_enability(xitk_widget_t * w,void * data,int state)1740 static void _vpplugin_enability(xitk_widget_t *w, void *data, int state) {
1741 _pplugin_enability(&vpp_wrapper, w, data, state);
1742 }
1743
_applugin_enability(xitk_widget_t * w,void * data,int state)1744 static void _applugin_enability(xitk_widget_t *w, void *data, int state) {
1745 _pplugin_enability(&app_wrapper, w, data, state);
1746 }
1747
pplugin_is_post_selected(_pp_wrapper_t * pp_wrapper)1748 static int pplugin_is_post_selected(_pp_wrapper_t *pp_wrapper) {
1749 gGui_t *gui = gGui;
1750
1751 if(pp_wrapper->pplugin) {
1752 int post_num = pp_wrapper->pplugin->object_num;
1753
1754 if(!xitk_combo_get_current_selected(pp_wrapper->pplugin->post_objects[post_num - 1]->plugins))
1755 post_num--;
1756
1757 return (post_num > 0);
1758 }
1759
1760 return (pp_wrapper == &vpp_wrapper) ? gui->post_video_elements_num : gui->post_audio_elements_num;
1761 }
1762
pplugin_rewire_from_posts_window(_pp_wrapper_t * pp_wrapper)1763 static void pplugin_rewire_from_posts_window(_pp_wrapper_t *pp_wrapper) {
1764 if(pp_wrapper->pplugin) {
1765 _pplugin_unwire(pp_wrapper);
1766 _pplugin_rewire(pp_wrapper);
1767 }
1768 }
1769
_vpplugin_rewire_from_post_elements(post_element_t ** post_elements,int post_elements_num)1770 static void _vpplugin_rewire_from_post_elements(post_element_t **post_elements, int post_elements_num) {
1771 gGui_t *gui = gGui;
1772
1773 if(post_elements_num) {
1774 xine_post_out_t *vo_source;
1775 int i = 0;
1776
1777 for(i = (post_elements_num - 1); i >= 0; i--) {
1778 /* use the first output from plugin */
1779 const char *const *outs = xine_post_list_outputs(post_elements[i]->post);
1780 const xine_post_out_t *vo_out = xine_post_output(post_elements[i]->post, (char *) *outs);
1781 if(i == (post_elements_num - 1)) {
1782 xine_post_wire_video_port((xine_post_out_t *) vo_out, gui->vo_port);
1783 }
1784 else {
1785 const xine_post_in_t *vo_in;
1786
1787 /* look for standard input names */
1788 vo_in = xine_post_input(post_elements[i + 1]->post, "video");
1789 if( !vo_in )
1790 vo_in = xine_post_input(post_elements[i + 1]->post, "video in");
1791
1792 xine_post_wire((xine_post_out_t *) vo_out, (xine_post_in_t *) vo_in);
1793 }
1794 }
1795
1796 vo_source = xine_get_video_source(gui->stream);
1797 xine_post_wire_video_port(vo_source, post_elements[0]->post->video_input[0]);
1798 }
1799 }
1800
_applugin_rewire_from_post_elements(post_element_t ** post_elements,int post_elements_num)1801 static void _applugin_rewire_from_post_elements(post_element_t **post_elements, int post_elements_num) {
1802 gGui_t *gui = gGui;
1803
1804 if(post_elements_num) {
1805 xine_post_out_t *ao_source;
1806 int i = 0;
1807
1808 for(i = (post_elements_num - 1); i >= 0; i--) {
1809 /* use the first output from plugin */
1810 const char *const *outs = xine_post_list_outputs(post_elements[i]->post);
1811 const xine_post_out_t *ao_out = xine_post_output(post_elements[i]->post, (char *) *outs);
1812 if(i == (post_elements_num - 1)) {
1813 xine_post_wire_audio_port((xine_post_out_t *) ao_out, gui->ao_port);
1814 }
1815 else {
1816 const xine_post_in_t *ao_in;
1817
1818 /* look for standard input names */
1819 ao_in = xine_post_input(post_elements[i + 1]->post, "audio");
1820 if( !ao_in )
1821 ao_in = xine_post_input(post_elements[i + 1]->post, "audio in");
1822
1823 xine_post_wire((xine_post_out_t *) ao_out, (xine_post_in_t *) ao_in);
1824 }
1825 }
1826
1827 ao_source = xine_get_audio_source(gui->stream);
1828 xine_post_wire_audio_port(ao_source, post_elements[0]->post->audio_input[0]);
1829 }
1830 }
1831
_pplugin_rewire_from_post_elements(_pp_wrapper_t * pp_wrapper,post_element_t ** post_elements,int post_elements_num)1832 static void _pplugin_rewire_from_post_elements(_pp_wrapper_t *pp_wrapper, post_element_t **post_elements, int post_elements_num) {
1833 if (pp_wrapper == &vpp_wrapper)
1834 _vpplugin_rewire_from_post_elements(post_elements, post_elements_num);
1835 else
1836 _applugin_rewire_from_post_elements(post_elements, post_elements_num);
1837 }
1838
pplugin_rewire_posts(_pp_wrapper_t * pp_wrapper)1839 static void pplugin_rewire_posts(_pp_wrapper_t *pp_wrapper) {
1840 _pplugin_unwire(pp_wrapper);
1841 _pplugin_rewire(pp_wrapper);
1842
1843 #if 0
1844 gGui_t *gui = gGui;
1845 if(gui->post_enable && !gui->deinterlace_enable)
1846 _pplugin_rewire_from_post_elements(gui->post_elements, gui->post_elements_num);
1847 #endif
1848 }
1849
pplugin_end(_pp_wrapper_t * pp_wrapper)1850 static void pplugin_end(_pp_wrapper_t *pp_wrapper) {
1851 pplugin_exit(pp_wrapper, NULL, NULL);
1852 }
1853
pplugin_is_visible(_pp_wrapper_t * pp_wrapper)1854 static int pplugin_is_visible(_pp_wrapper_t *pp_wrapper) {
1855 gGui_t *gui = gGui;
1856
1857 if(pp_wrapper->pplugin) {
1858 if(gui->use_root_window)
1859 return xitk_is_window_visible(gui->display, xitk_window_get_window(pp_wrapper->pplugin->xwin));
1860 else
1861 return pp_wrapper->pplugin->visible && xitk_is_window_visible(gui->display, xitk_window_get_window(pp_wrapper->pplugin->xwin));
1862 }
1863
1864 return 0;
1865 }
1866
pplugin_is_running(_pp_wrapper_t * pp_wrapper)1867 static int pplugin_is_running(_pp_wrapper_t *pp_wrapper) {
1868
1869 if(pp_wrapper->pplugin)
1870 return pp_wrapper->pplugin->running;
1871
1872 return 0;
1873 }
1874
pplugin_raise_window(_pp_wrapper_t * pp_wrapper)1875 static void pplugin_raise_window(_pp_wrapper_t *pp_wrapper) {
1876 if(pp_wrapper->pplugin != NULL)
1877 raise_window(xitk_window_get_window(pp_wrapper->pplugin->xwin), pp_wrapper->pplugin->visible, pp_wrapper->pplugin->running);
1878 }
1879
1880
pplugin_toggle_visibility(_pp_wrapper_t * pp_wrapper,xitk_widget_t * w,void * data)1881 static void pplugin_toggle_visibility(_pp_wrapper_t *pp_wrapper, xitk_widget_t *w, void *data) {
1882 if(pp_wrapper->pplugin != NULL)
1883 toggle_window(xitk_window_get_window(pp_wrapper->pplugin->xwin), pp_wrapper->pplugin->widget_list,
1884 &pp_wrapper->pplugin->visible, pp_wrapper->pplugin->running);
1885 }
1886
pplugin_update_enable_button(_pp_wrapper_t * pp_wrapper)1887 static void pplugin_update_enable_button(_pp_wrapper_t *pp_wrapper) {
1888 gGui_t *gui = gGui;
1889 if(pp_wrapper->pplugin)
1890 xitk_labelbutton_set_state(pp_wrapper->pplugin->enable, (pp_wrapper == &vpp_wrapper) ? gui->post_video_enable : gui->post_audio_enable);
1891 }
1892
pplugin_reparent(_pp_wrapper_t * pp_wrapper)1893 static void pplugin_reparent(_pp_wrapper_t *pp_wrapper) {
1894 if(pp_wrapper->pplugin)
1895 reparent_window((xitk_window_get_window(pp_wrapper->pplugin->xwin)));
1896 }
1897
pplugin_panel(_pp_wrapper_t * pp_wrapper)1898 static void pplugin_panel(_pp_wrapper_t *pp_wrapper) {
1899 gGui_t *gui = gGui;
1900 GC gc;
1901 xitk_labelbutton_widget_t lb;
1902 xitk_label_widget_t lbl;
1903 xitk_checkbox_widget_t cb;
1904 xitk_pixmap_t *bg;
1905 int x, y, width, height;
1906 xitk_slider_widget_t sl;
1907 xitk_widget_t *w;
1908
1909 pp_wrapper->pplugin = (_pplugin_t *) calloc(1, sizeof(_pplugin_t));
1910 pp_wrapper->pplugin->first_displayed = 0;
1911 pp_wrapper->pplugin->help_text = NULL;
1912
1913 x = xine_config_register_num (__xineui_global_xine_instance, (pp_wrapper == &vpp_wrapper) ? "gui.vpplugin_x" : "gui.applugin_x",
1914 80,
1915 CONFIG_NO_DESC,
1916 CONFIG_NO_HELP,
1917 CONFIG_LEVEL_DEB,
1918 CONFIG_NO_CB,
1919 CONFIG_NO_DATA);
1920 y = xine_config_register_num (__xineui_global_xine_instance, (pp_wrapper == &vpp_wrapper) ? "gui.vpplugin_y" : "gui.applugin_y",
1921 80,
1922 CONFIG_NO_DESC,
1923 CONFIG_NO_HELP,
1924 CONFIG_LEVEL_DEB,
1925 CONFIG_NO_CB,
1926 CONFIG_NO_DATA);
1927
1928 pp_wrapper->pplugin->xwin = xitk_window_create_dialog_window(gui->imlib_data,
1929 (pp_wrapper == &vpp_wrapper) ? _("Video Chain Reaction") : _("Audio Chain Reaction"),
1930 x, y, WINDOW_WIDTH, WINDOW_HEIGHT);
1931
1932 set_window_states_start((xitk_window_get_window(pp_wrapper->pplugin->xwin)));
1933
1934 gui->x_lock_display (gui->display);
1935 gc = XCreateGC(gui->display,
1936 (xitk_window_get_window(pp_wrapper->pplugin->xwin)), None, None);
1937 gui->x_unlock_display (gui->display);
1938
1939 pp_wrapper->pplugin->widget_list = xitk_widget_list_new();
1940 xitk_widget_list_set(pp_wrapper->pplugin->widget_list,
1941 WIDGET_LIST_WINDOW, (void *) (xitk_window_get_window(pp_wrapper->pplugin->xwin)));
1942 xitk_widget_list_set(pp_wrapper->pplugin->widget_list, WIDGET_LIST_GC, gc);
1943
1944 XITK_WIDGET_INIT(&lb, gui->imlib_data);
1945 XITK_WIDGET_INIT(&lbl, gui->imlib_data);
1946 XITK_WIDGET_INIT(&cb, gui->imlib_data);
1947
1948 xitk_window_get_window_size(pp_wrapper->pplugin->xwin, &width, &height);
1949 bg = xitk_image_create_xitk_pixmap(gui->imlib_data, width, height);
1950
1951 gui->x_lock_display (gui->display);
1952 XCopyArea(gui->display, (xitk_window_get_background(pp_wrapper->pplugin->xwin)), bg->pixmap,
1953 bg->gc, 0, 0, width, height, 0, 0);
1954 gui->x_unlock_display (gui->display);
1955
1956 XITK_WIDGET_INIT(&sl, gui->imlib_data);
1957
1958 sl.min = 0;
1959 sl.max = 1;
1960 sl.step = 1;
1961 sl.skin_element_name = NULL;
1962 sl.callback = NULL;
1963 sl.userdata = NULL;
1964 sl.motion_callback = (pp_wrapper == &vpp_wrapper) ? _vpplugin_nextprev : _applugin_nextprev;
1965 sl.motion_userdata = NULL;
1966 pp_wrapper->pplugin->slider = xitk_noskin_slider_create (pp_wrapper->pplugin->widget_list, &sl,
1967 (WINDOW_WIDTH - (16 + 15)), 34, 16, (MAX_DISPLAY_FILTERS * (FRAME_HEIGHT + 4) - 4), XITK_VSLIDER);
1968 xitk_add_widget (pp_wrapper->pplugin->widget_list, pp_wrapper->pplugin->slider);
1969
1970 y = WINDOW_HEIGHT - (23 + 15);
1971 x = 15;
1972
1973 lb.button_type = RADIO_BUTTON;
1974 lb.label = _("Enable");
1975 lb.align = ALIGN_CENTER;
1976 lb.callback = NULL;
1977 lb.state_callback = (pp_wrapper == &vpp_wrapper) ? _vpplugin_enability : _applugin_enability;
1978 lb.userdata = NULL;
1979 lb.skin_element_name = NULL;
1980 pp_wrapper->pplugin->enable = xitk_noskin_labelbutton_create (pp_wrapper->pplugin->widget_list,
1981 &lb, x, y, 100, 23, "Black", "Black", "White", btnfontname);
1982 xitk_add_widget (pp_wrapper->pplugin->widget_list, pp_wrapper->pplugin->enable);
1983
1984 xitk_labelbutton_set_state(pp_wrapper->pplugin->enable, (pp_wrapper == &vpp_wrapper) ? gui->post_video_enable : gui->post_audio_enable);
1985 xitk_enable_and_show_widget(pp_wrapper->pplugin->enable);
1986
1987 /* IMPLEMENT ME
1988 x += (100 + 15);
1989
1990 lb.button_type = CLICK_BUTTON;
1991 lb.label = _("Save");
1992 lb.align = ALIGN_CENTER;
1993 lb.callback = NULL;
1994 lb.state_callback = NULL;
1995 lb.userdata = NULL;
1996 lb.skin_element_name = NULL;
1997 w = xitk_noskin_labelbutton_create (pp_wrapper->pplugin->widget_list,
1998 &lb, x, y, 100, 23, "Black", "Black", "White", btnfontname);
1999 xitk_add_widget (pp_wrapper->pplugin->widget_list, w);
2000 xitk_enable_and_show_widget(w);
2001 */
2002
2003 x = WINDOW_WIDTH - (100 + 15);
2004
2005 lb.button_type = CLICK_BUTTON;
2006 lb.label = _("OK");
2007 lb.align = ALIGN_CENTER;
2008 lb.callback = (pp_wrapper == &vpp_wrapper) ? vpplugin_exit : applugin_exit;
2009 lb.state_callback = NULL;
2010 lb.userdata = NULL;
2011 lb.skin_element_name = NULL;
2012 w = xitk_noskin_labelbutton_create (pp_wrapper->pplugin->widget_list,
2013 &lb, x, y, 100, 23, "Black", "Black", "White", btnfontname);
2014 xitk_add_widget (pp_wrapper->pplugin->widget_list, w);
2015 xitk_enable_and_show_widget(w);
2016
2017 _pplugin_get_plugins(pp_wrapper);
2018
2019 pp_wrapper->pplugin->x = 15;
2020 pp_wrapper->pplugin->y = 34 - (FRAME_HEIGHT + 4);
2021
2022 _pplugin_rebuild_filters (pp_wrapper);
2023
2024 xitk_window_change_background(gui->imlib_data, pp_wrapper->pplugin->xwin, bg->pixmap, width, height);
2025 xitk_image_destroy_xitk_pixmap(bg);
2026
2027 pp_wrapper->pplugin->widget_key = xitk_register_event_handler((pp_wrapper == &vpp_wrapper) ? "vpplugin" : "applugin",
2028 (xitk_window_get_window(pp_wrapper->pplugin->xwin)),
2029 (pp_wrapper == &vpp_wrapper) ? _vpplugin_handle_event : _applugin_handle_event,
2030 NULL,
2031 NULL,
2032 pp_wrapper->pplugin->widget_list,
2033 NULL);
2034
2035 pp_wrapper->pplugin->visible = 1;
2036 pp_wrapper->pplugin->running = 1;
2037
2038 _pplugin_paint_widgets(pp_wrapper);
2039
2040 pplugin_raise_window(pp_wrapper);
2041
2042 try_to_set_input_focus(xitk_window_get_window(pp_wrapper->pplugin->xwin));
2043 }
2044
2045 /* pchain: "<post1>:option1=value1,option2=value2..;<post2>:...." */
pplugin_parse_and_load(_pp_wrapper_t * pp_wrapper,const char * pchain,int * post_elements_num)2046 static post_element_t **pplugin_parse_and_load(_pp_wrapper_t *pp_wrapper, const char *pchain, int *post_elements_num) {
2047 gGui_t *gui = gGui;
2048 int plugin_type = (pp_wrapper == &vpp_wrapper) ? XINE_POST_TYPE_VIDEO_FILTER : XINE_POST_TYPE_AUDIO_FILTER;
2049 post_element_t **post_elements = NULL;
2050
2051 *post_elements_num = 0;
2052
2053 if(pchain && strlen(pchain)) {
2054 char *p, *post_chain, *ppost_chain;
2055
2056 post_chain = strdup(pchain);
2057
2058 ppost_chain = post_chain;
2059 while((p = xine_strsep(&ppost_chain, ";"))) {
2060
2061 if(strlen(p)) {
2062 char *plugin, *args = NULL;
2063 xine_post_t *post;
2064
2065 while(*p == ' ')
2066 p++;
2067
2068 plugin = strdup(p);
2069
2070 if((p = strchr(plugin, ':')))
2071 *p++ = '\0';
2072
2073 if(p && (strlen(p) > 1))
2074 args = p;
2075
2076 post = xine_post_init(__xineui_global_xine_instance, plugin, 0, &gui->ao_port, &gui->vo_port);
2077
2078 if (post && pp_wrapper) {
2079 if (post->type != plugin_type) {
2080 xine_post_dispose(__xineui_global_xine_instance, post);
2081 post = NULL;
2082 }
2083 }
2084
2085 if(post) {
2086 post_object_t pobj;
2087
2088 post_elements = (post_element_t **) realloc(post_elements, sizeof(post_element_t *) * ((*post_elements_num) + 2));
2089
2090 post_elements[(*post_elements_num)] = (post_element_t *)
2091 calloc(1, sizeof(post_element_t));
2092 post_elements[(*post_elements_num)]->post = post;
2093 post_elements[(*post_elements_num)]->name = strdup(plugin);
2094 (*post_elements_num)++;
2095 post_elements[(*post_elements_num)] = NULL;
2096
2097 memset(&pobj, 0, sizeof(post_object_t));
2098 pobj.post = post;
2099
2100 if(__pplugin_retrieve_parameters(&pobj)) {
2101 int i;
2102
2103 if(pobj.properties_names && args) {
2104 char *param;
2105
2106 while((param = xine_strsep(&args, ",")) != NULL) {
2107
2108 p = param;
2109
2110 while((*p != '\0') && (*p != '='))
2111 p++;
2112
2113 if(strlen(p)) {
2114 int param_num = 0;
2115
2116 *p++ = '\0';
2117
2118 while(pobj.properties_names[param_num]
2119 && strcasecmp(pobj.properties_names[param_num], param))
2120 param_num++;
2121
2122 if(pobj.properties_names[param_num]) {
2123
2124 pobj.param = pobj.descr->parameter;
2125 pobj.param += param_num;
2126 pobj.readonly = pobj.param->readonly;
2127
2128 switch(pobj.param->type) {
2129 case POST_PARAM_TYPE_INT:
2130 if(!pobj.readonly) {
2131 if(pobj.param->enum_values) {
2132 char **values = pobj.param->enum_values;
2133 int i = 0;
2134
2135 while(values[i]) {
2136 if(!strcasecmp(values[i], p)) {
2137 *(int *)(pobj.param_data + pobj.param->offset) = i;
2138 break;
2139 }
2140 i++;
2141 }
2142
2143 if( !values[i] )
2144 *(int *)(pobj.param_data + pobj.param->offset) = (int) strtol(p, &p, 10);
2145 } else {
2146 *(int *)(pobj.param_data + pobj.param->offset) = (int) strtol(p, &p, 10);
2147 }
2148 _pplugin_update_parameter(&pobj);
2149 }
2150 break;
2151
2152 case POST_PARAM_TYPE_DOUBLE:
2153 if(!pobj.readonly) {
2154 *(double *)(pobj.param_data + pobj.param->offset) = strtod(p, &p);
2155 _pplugin_update_parameter(&pobj);
2156 }
2157 break;
2158
2159 case POST_PARAM_TYPE_CHAR:
2160 case POST_PARAM_TYPE_STRING:
2161 if(!pobj.readonly) {
2162 if(pobj.param->type == POST_PARAM_TYPE_CHAR) {
2163 int maxlen = pobj.param->size / sizeof(char);
2164
2165 strlcpy((char *)(pobj.param_data + pobj.param->offset), p, maxlen);
2166 _pplugin_update_parameter(&pobj);
2167 }
2168 else
2169 fprintf(stderr, "parameter type POST_PARAM_TYPE_STRING not supported yet.\n");
2170 }
2171 break;
2172
2173 case POST_PARAM_TYPE_STRINGLIST: /* unsupported */
2174 if(!pobj.readonly)
2175 fprintf(stderr, "parameter type POST_PARAM_TYPE_STRINGLIST not supported yet.\n");
2176 break;
2177
2178 case POST_PARAM_TYPE_BOOL:
2179 if(!pobj.readonly) {
2180 *(int *)(pobj.param_data + pobj.param->offset) = ((int) strtol(p, &p, 10)) ? 1 : 0;
2181 _pplugin_update_parameter(&pobj);
2182 }
2183 break;
2184 }
2185 }
2186 }
2187 }
2188
2189 i = 0;
2190
2191 while(pobj.properties_names[i]) {
2192 free(pobj.properties_names[i]);
2193 i++;
2194 }
2195
2196 free(pobj.properties_names);
2197 }
2198
2199 VFREE(pobj.param_data);
2200 }
2201 }
2202
2203 VFREE(plugin);
2204 }
2205 }
2206 free(post_chain);
2207 }
2208
2209 return post_elements;
2210 }
2211
pplugin_parse_and_store_post(_pp_wrapper_t * pp_wrapper,const char * post_chain)2212 static void pplugin_parse_and_store_post(_pp_wrapper_t *pp_wrapper, const char *post_chain) {
2213 gGui_t *gui = gGui;
2214 post_element_t ***_post_elements = (pp_wrapper == &vpp_wrapper) ? &gui->post_video_elements : &gui->post_audio_elements;
2215 int *_post_elements_num = (pp_wrapper == &vpp_wrapper) ? &gui->post_video_elements_num : &gui->post_audio_elements_num;
2216 post_element_t **posts = NULL;
2217 int num;
2218
2219 if((posts = pplugin_parse_and_load(pp_wrapper, post_chain, &num))) {
2220 if(*_post_elements_num) {
2221 int i;
2222 int ptot = *_post_elements_num + num;
2223
2224 *_post_elements = (post_element_t **) realloc(*_post_elements, sizeof(post_element_t *) * (ptot + 1));
2225 for(i = *_post_elements_num; i < ptot; i++)
2226 (*_post_elements)[i] = posts[i - *_post_elements_num];
2227
2228 (*_post_elements)[i] = NULL;
2229 (*_post_elements_num) += num;
2230
2231 free(posts);
2232 }
2233 else {
2234 *_post_elements = posts;
2235 *_post_elements_num = num;
2236 }
2237 }
2238 }
2239
post_deinit(void)2240 void post_deinit (void) {
2241 gGui_t *gui = gGui;
2242 int i;
2243
2244 if (gui->post_video_enable)
2245 _vpplugin_unwire ();
2246
2247 for (i = 0; i < gui->post_video_elements_num; i++) {
2248 xine_post_dispose (__xineui_global_xine_instance, gui->post_video_elements[i]->post);
2249 free (gui->post_video_elements[i]->name);
2250 VFREE (gui->post_video_elements[i]);
2251 }
2252 SAFE_FREE (gui->post_video_elements);
2253 gui->post_video_elements_num = 0;
2254
2255
2256 if (gui->post_audio_enable)
2257 _applugin_unwire ();
2258
2259 for (i = 0; i < gui->post_audio_elements_num; i++) {
2260 xine_post_dispose (__xineui_global_xine_instance, gui->post_audio_elements[i]->post);
2261 free (gui->post_audio_elements[i]->name);
2262 VFREE (gui->post_audio_elements[i]);
2263 }
2264 SAFE_FREE (gui->post_audio_elements);
2265 gui->post_audio_elements_num = 0;
2266 }
2267
_pplugin_get_default_deinterlacer(void)2268 static char *_pplugin_get_default_deinterlacer(void) {
2269 return DEFAULT_DEINTERLACER;
2270 }
2271
post_deinterlace_init(const char * deinterlace_post)2272 void post_deinterlace_init(const char *deinterlace_post) {
2273 gGui_t *gui = gGui;
2274 post_element_t **posts = NULL;
2275 int num;
2276 char *deinterlace_default;
2277
2278 deinterlace_default = _pplugin_get_default_deinterlacer();
2279
2280 gui->deinterlace_plugin =
2281 (char *) xine_config_register_string (__xineui_global_xine_instance, "gui.deinterlace_plugin",
2282 deinterlace_default,
2283 _("Deinterlace plugin."),
2284 _("Plugin (with optional parameters) to use "
2285 "when deinterlace is used (plugin separator is ';')."),
2286 CONFIG_LEVEL_ADV,
2287 post_deinterlace_plugin_cb,
2288 gGui);
2289 if((posts = pplugin_parse_and_load(0, (deinterlace_post && strlen(deinterlace_post)) ?
2290 deinterlace_post : gui->deinterlace_plugin, &num))) {
2291 gui->deinterlace_elements = posts;
2292 gui->deinterlace_elements_num = num;
2293 }
2294
2295 }
2296
post_deinterlace_deinit(void)2297 void post_deinterlace_deinit (void) {
2298 gGui_t *gui = gGui;
2299 int i;
2300 #if 0
2301 /* requires <xine/xine_internal.h> */
2302 __xineui_global_xine_instance->config->unregister_callback (__xineui_global_xine_instance, "gui.deinterlace_plugin");
2303 #endif
2304
2305 if (gui->deinterlace_enable)
2306 _vpplugin_unwire ();
2307
2308 for (i = 0; i < gui->deinterlace_elements_num; i++) {
2309 xine_post_dispose (__xineui_global_xine_instance, gui->deinterlace_elements[i]->post);
2310 free (gui->deinterlace_elements[i]->name);
2311 VFREE (gui->deinterlace_elements[i]);
2312 }
2313
2314 SAFE_FREE (gui->deinterlace_elements);
2315 gui->deinterlace_elements_num = 0;
2316 }
2317
post_deinterlace(void)2318 void post_deinterlace(void) {
2319 gGui_t *gui = gGui;
2320
2321 if( !gui->deinterlace_elements_num ) {
2322 /* fallback to the old method */
2323 xine_set_param(gui->stream, XINE_PARAM_VO_DEINTERLACE,
2324 gui->deinterlace_enable);
2325 }
2326 else {
2327 _pplugin_unwire(&vpp_wrapper);
2328 _pplugin_rewire(&vpp_wrapper);
2329 }
2330
2331 #if 0
2332 if(gui->deinterlace_enable) {
2333 if(gui->post_enable)
2334 _pplugin_unwire();
2335
2336 _pplugin_rewire_from_post_elements(gui->deinterlace_elements, gui->deinterlace_elements_num);
2337 }
2338 else {
2339 _pplugin_unwire();
2340
2341 if(gui->post_enable) {
2342 if(pplugin_is_visible() && pplugin)
2343 _pplugin_rewire();
2344 else
2345 _pplugin_rewire_from_post_elements(gui->post_elements, gui->post_elements_num);
2346 }
2347 }
2348 #endif
2349 }
2350
vpplugin_end(void)2351 void vpplugin_end(void)
2352 {
2353 pplugin_end(&vpp_wrapper);
2354 }
2355
vpplugin_is_visible(void)2356 int vpplugin_is_visible(void)
2357 {
2358 return pplugin_is_visible(&vpp_wrapper);
2359 }
2360
vpplugin_is_running(void)2361 int vpplugin_is_running(void)
2362 {
2363 return pplugin_is_running(&vpp_wrapper);
2364 }
2365
vpplugin_toggle_visibility(xitk_widget_t * w,void * data)2366 void vpplugin_toggle_visibility(xitk_widget_t *w, void *data)
2367 {
2368 pplugin_toggle_visibility(&vpp_wrapper, w, data);
2369 }
2370
vpplugin_raise_window(void)2371 void vpplugin_raise_window(void)
2372 {
2373 pplugin_raise_window(&vpp_wrapper);
2374 }
2375
vpplugin_update_enable_button(void)2376 void vpplugin_update_enable_button(void)
2377 {
2378 pplugin_update_enable_button(&vpp_wrapper);
2379 }
2380
vpplugin_panel(void)2381 void vpplugin_panel(void)
2382 {
2383 pplugin_panel(&vpp_wrapper);
2384 }
2385
vpplugin_parse_and_store_post(const char * post)2386 void vpplugin_parse_and_store_post(const char *post)
2387 {
2388 pplugin_parse_and_store_post(&vpp_wrapper, post);
2389 }
2390
vpplugin_rewire_from_posts_window(void)2391 void vpplugin_rewire_from_posts_window(void)
2392 {
2393 pplugin_rewire_from_posts_window(&vpp_wrapper);
2394 }
2395
vpplugin_rewire_posts(void)2396 void vpplugin_rewire_posts(void)
2397 {
2398 pplugin_rewire_posts(&vpp_wrapper);
2399 }
2400
vpplugin_is_post_selected(void)2401 int vpplugin_is_post_selected(void)
2402 {
2403 return pplugin_is_post_selected(&vpp_wrapper);
2404 }
2405
vpplugin_reparent(void)2406 void vpplugin_reparent(void)
2407 {
2408 pplugin_reparent(&vpp_wrapper);
2409 }
2410
applugin_end(void)2411 void applugin_end(void)
2412 {
2413 pplugin_end(&app_wrapper);
2414 }
2415
applugin_is_visible(void)2416 int applugin_is_visible(void)
2417 {
2418 return pplugin_is_visible(&app_wrapper);
2419 }
2420
applugin_is_running(void)2421 int applugin_is_running(void)
2422 {
2423 return pplugin_is_running(&app_wrapper);
2424 }
2425
applugin_toggle_visibility(xitk_widget_t * w,void * data)2426 void applugin_toggle_visibility(xitk_widget_t *w, void *data)
2427 {
2428 pplugin_toggle_visibility(&app_wrapper, w, data);
2429 }
2430
applugin_raise_window(void)2431 void applugin_raise_window(void)
2432 {
2433 pplugin_raise_window(&app_wrapper);
2434 }
2435
applugin_update_enable_button(void)2436 void applugin_update_enable_button(void)
2437 {
2438 pplugin_update_enable_button(&app_wrapper);
2439 }
2440
applugin_panel(void)2441 void applugin_panel(void)
2442 {
2443 pplugin_panel(&app_wrapper);
2444 }
2445
applugin_parse_and_store_post(const char * post)2446 void applugin_parse_and_store_post(const char *post)
2447 {
2448 pplugin_parse_and_store_post(&app_wrapper, post);
2449 }
2450
applugin_rewire_from_posts_window(void)2451 void applugin_rewire_from_posts_window(void)
2452 {
2453 pplugin_rewire_from_posts_window(&app_wrapper);
2454 }
2455
applugin_rewire_posts(void)2456 void applugin_rewire_posts(void)
2457 {
2458 pplugin_rewire_posts(&app_wrapper);
2459 }
2460
applugin_is_post_selected(void)2461 int applugin_is_post_selected(void)
2462 {
2463 return pplugin_is_post_selected(&app_wrapper);
2464 }
2465
applugin_reparent(void)2466 void applugin_reparent(void)
2467 {
2468 pplugin_reparent(&app_wrapper);
2469 }
2470