1 /**
2 * \file gnome_frame.c
3 *
4 * This file contains functions needed for creation and maintenance of the
5 * frame enclosing the area to capture.
6 */
7
8 /*
9 * Copyright (C) 2003-07 Karl H. Beckers, Frankfurt
10 * EMail: khb@jarre-de-the.net
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 *
27 * This file contains routines for setting up and handling the selection
28 * rectangle. Both Xt and GTK2 versions are in here now.
29 *
30 */
31
32 #ifndef DOXYGEN_SHOULD_SKIP_THIS
33 #ifdef HAVE_CONFIG_H
34 # include <config.h>
35 #endif
36
37 #define DEBUGFILE "gnome_frame.c"
38 #endif // DOXYGEN_SHOULD_SKIP_THIS
39
40 #include <X11/Intrinsic.h>
41 #include <gtk/gtk.h>
42 #include <gdk/gdkx.h>
43 #include <glade/glade.h>
44 #include <stdlib.h>
45 #include <sys/time.h> // for timeval struct and related
46 #include <pthread.h>
47
48 #include "app_data.h"
49 #include "job.h"
50 #include "frame.h"
51 #include "gnome_frame.h"
52 #include "gnome_ui.h"
53
54 #define XVC_FRAME_DIM_SHOW_TIME 2
55
56 /*
57 * file globals (static)
58 *
59 */
60 /**
61 * \brief remember the Display if already retrieved
62 *
63 * This assumes that the Display to capture from cannot change once xvidcap
64 * has been started. We reuse any Display we once retrieved to avoid
65 * potential X server roundtrip
66 */
67 static Display *xvc_dpy = NULL;
68
69 /** \brief make the frame parts available everywhere in this file */
70 static GtkWidget *gtk_frame_top,
71 *gtk_frame_left, *gtk_frame_right, *gtk_frame_bottom, *gtk_frame_center;
72 static GtkWidget *xvc_frame_dimensions_window;
73 static gboolean button_pressed = FALSE;
74 static int button_press_rel_x = 0;
75 static int button_press_rel_y = 0;
76 static gint frame_drag_cursor = GDK_X_CURSOR;
77 static long frame_dimensions_hide_time = 0;
78 static GdkDisplay *gdpy;
79
80 /**
81 * \brief gets the Display to capture from
82 *
83 * If the frame has been created we retrieve the Display from GDK. Otherwise,
84 * (either we're running without GUI or we're doing this before the frame
85 * has been created, which is the case if we pass --window) we use
86 * XOpenDisplay if xvc_dpy is not already set.
87 *
88 * @return a pointer to the Display to capture from. This Display can be
89 * expected to be always open and only closed on program exit.
90 * @see xvc_frame_drop_capture_display
91 */
92 Display *
xvc_frame_get_capture_display()93 xvc_frame_get_capture_display ()
94 {
95 #define DEBUGFUNCTION "xvc_frame_get_capure_display()"
96 XVC_AppData *app = xvc_appdata_ptr ();
97
98 if (!(app->flags & FLG_NOGUI) && !(app->flags & FLG_NOFRAME)
99 && gtk_frame_top) {
100 xvc_dpy = GDK_DRAWABLE_XDISPLAY (GTK_WIDGET (gtk_frame_top)->window);
101 } else {
102 if (!xvc_dpy)
103 gdpy = gdk_display_get_default ();
104 xvc_dpy = gdk_x11_display_get_xdisplay (gdpy);
105 }
106 g_assert (xvc_dpy);
107 return xvc_dpy;
108 #undef DEBUGFUNCTION
109 }
110
111 /**
112 * \brief cleans up the Display to capture from, i. e. close and set to NULL
113 */
114 void
xvc_frame_drop_capture_display()115 xvc_frame_drop_capture_display ()
116 {
117 #define DEBUGFUNCTION "xvc_frame_drop_capture_display()"
118 XVC_AppData *app = xvc_appdata_ptr ();
119
120 if ((app->flags & FLG_NOGUI || app->flags & FLG_NOFRAME) && xvc_dpy) {
121 gdk_display_close (gdpy);
122 gdpy = NULL;
123 xvc_dpy = NULL;
124 }
125 #undef DEBUGFUNCTION
126 }
127
128 /**
129 * \brief repositions the main control according to the frame's current
130 * position
131 *
132 * @param toplevel a pointer to the main control
133 */
134 void
do_reposition_control(GtkWidget * toplevel)135 do_reposition_control (GtkWidget * toplevel)
136 {
137 #define DEBUGFUNCTION "do_reposition_control()"
138 int max_width = 0, max_height = 0;
139 int pwidth = 0, pheight = 0;
140 XRectangle *x_rect = xvc_get_capture_area ();
141 int x = x_rect->x, y = x_rect->y;
142 int width = x_rect->width, height = x_rect->height;
143 GdkScreen *myscreen;
144 GdkRectangle rect;
145
146 myscreen = GTK_WINDOW (toplevel)->screen;
147 g_assert (myscreen);
148
149 max_width = gdk_screen_get_width (GDK_SCREEN (myscreen));
150 max_height = gdk_screen_get_height (GDK_SCREEN (myscreen));
151
152 xvc_get_ctrl_frame_extents (GDK_WINDOW (toplevel->window), &rect);
153 // gdk_window_get_frame_extents (GDK_WINDOW (toplevel->window), &rect);
154 pwidth = rect.width + FRAME_OFFSET;
155 pheight = rect.height + FRAME_OFFSET;
156
157 #ifdef DEBUG
158 printf ("%s %s: x %i y %i pwidth %i pheight %i width %i height %i\n",
159 DEBUGFILE, DEBUGFUNCTION, x, y, pwidth, pheight, width, height);
160 #endif // DEBUG
161 if ((y - pheight - FRAME_WIDTH) >= 0) {
162 gtk_window_move (GTK_WINDOW (toplevel), x, (y - pheight - FRAME_WIDTH));
163 } else {
164 GladeXML *xml = NULL;
165 GtkWidget *w = NULL;
166
167 xml = glade_get_widget_tree (GTK_WIDGET (toplevel));
168 g_assert (xml);
169
170 w = glade_xml_get_widget (xml, "xvc_ctrl_lock_toggle");
171 g_assert (w);
172
173 gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (w), FALSE);
174
175 if ((y + pheight + height + FRAME_WIDTH) < max_height) {
176 gtk_window_move (GTK_WINDOW (toplevel), x,
177 (y + height + FRAME_OFFSET + FRAME_WIDTH));
178 } else {
179 if (x > pwidth + FRAME_WIDTH + FRAME_OFFSET) {
180 gtk_window_move (GTK_WINDOW (toplevel),
181 (x - pwidth - FRAME_WIDTH), y);
182 } else {
183 if ((x + width + pwidth + FRAME_WIDTH) < max_width) {
184 gtk_window_move (GTK_WINDOW (toplevel),
185 (x + width + FRAME_OFFSET +
186 FRAME_WIDTH), y);
187 }
188 // otherwise leave the UI where it is ...
189 }
190 }
191 }
192 #undef DEBUGFUNCTION
193 }
194
195 /**
196 * \brief hides the frame dimensions display if the time scheduled for
197 * hiding it is in the past and the widget is available
198 *
199 * This is used through g_timeout_add to schedule hiding of the frame
200 * dimensions display.
201 * @return always zero to remove the timeout function after execution
202 */
203 static int
frame_dimensions_hide()204 frame_dimensions_hide ()
205 {
206 struct timeval curr_time;
207 long current_time = 0;
208
209 gettimeofday (&curr_time, NULL);
210 current_time = curr_time.tv_sec * 1000 + curr_time.tv_usec / 1000;
211 if (xvc_frame_dimensions_window &&
212 GTK_IS_WIDGET (xvc_frame_dimensions_window) &&
213 current_time >= frame_dimensions_hide_time)
214 gtk_widget_hide (xvc_frame_dimensions_window);
215
216 return 0;
217 }
218
219 /**
220 * \brief changes frame due to user input
221 *
222 * @param x x-position to change to
223 * @param y y-position to change to
224 * @param width new frame width
225 * @param height new frame height
226 * @param reposition_control TRUE for main control should be repositioned
227 * if frame moves, or FALSE if not
228 * @param show_dimensions should the frame dimensions display be shown or not?
229 */
230 void
xvc_change_gtk_frame(int x,int y,int width,int height,Boolean reposition_control,Boolean show_dimensions)231 xvc_change_gtk_frame (int x, int y, int width, int height,
232 Boolean reposition_control, Boolean show_dimensions)
233 {
234 #define DEBUGFUNCTION "xvc_change_gtk_frame()"
235 extern GtkWidget *xvc_ctrl_main_window;
236 XRectangle *x_rect = xvc_get_capture_area ();
237 XVC_AppData *app = xvc_appdata_ptr ();
238 struct timeval curr_time;
239 GladeXML *xml = NULL;
240 GtkWidget *w = NULL;
241 char buf[64];
242 int wwidth, wheight;
243
244 #ifdef USE_FFMPEG
245 //
246 // make sure we have even width and height for ffmpeg
247 //
248 if (app->current_mode > 0) {
249 Boolean changed = FALSE;
250
251 if ((width % 2) > 0) {
252 width--;
253 changed = TRUE;
254 }
255 if ((height % 2) > 0) {
256 height--;
257 changed = TRUE;
258 }
259 if (width < 10) {
260 width = 10;
261 changed = TRUE;
262 }
263 if (height < 10) {
264 height = 10;
265 changed = TRUE;
266 }
267
268 if (changed) {
269 if (app->flags & FLG_RUN_VERBOSE) {
270 printf
271 ("Modified Selection geometry: %dx%d+%d+%d\n",
272 width, height, x, y);
273 if (reposition_control)
274 printf ("Need to reposition the maincontrol\n");
275 }
276 }
277 }
278 #endif // USE_FFMPEG
279
280 // we have to adjust it to viewable areas
281 #ifdef DEBUG
282 printf ("%s %s: screen = %dx%d selection=%dx%d\n", DEBUGFILE,
283 DEBUGFUNCTION, app->max_width, app->max_height, width, height);
284 #endif
285
286 if (x < 0)
287 x = 0;
288 if (width > app->max_width)
289 width = app->max_width;
290 if (x + width > app->max_width)
291 x = app->max_width - width;
292
293 if (y < 0)
294 y = 0;
295 if (height > app->max_height)
296 height = app->max_height;
297 if (y + height > app->max_height)
298 y = app->max_height - height;
299
300 if ((app->flags & FLG_NOGUI) == 0 && (app->flags & FLG_NOFRAME) == 0) {
301 // move the frame if not running without GUI
302 if (width != app->area->width) {
303 gtk_widget_set_size_request (GTK_WIDGET (gtk_frame_top),
304 (width + 2 * FRAME_WIDTH),
305 FRAME_WIDTH);
306 gtk_widget_set_size_request (GTK_WIDGET (gtk_frame_bottom),
307 (width + 2 * FRAME_WIDTH),
308 FRAME_WIDTH);
309 }
310 if (height != app->area->height) {
311 gtk_widget_set_size_request (GTK_WIDGET (gtk_frame_left),
312 FRAME_WIDTH, height);
313 gtk_widget_set_size_request (GTK_WIDGET (gtk_frame_right),
314 FRAME_WIDTH, height);
315 }
316 if (x != app->area->x || y != app->area->y) {
317 gtk_window_move (GTK_WINDOW (gtk_frame_top), (x - FRAME_WIDTH),
318 (y - FRAME_WIDTH));
319 gtk_window_move (GTK_WINDOW (gtk_frame_left), (x - FRAME_WIDTH), y);
320 }
321 if (x != app->area->x || y != app->area->y || width != app->area->width
322 || height != app->area->height) {
323 gtk_window_move (GTK_WINDOW (gtk_frame_bottom), (x - FRAME_WIDTH),
324 (y + height));
325 gtk_window_move (GTK_WINDOW (gtk_frame_right), (x + width), y);
326 }
327 #ifdef HasVideo4Linux
328 // if we have a v4l blind, move it, too
329 if (gtk_frame_center != NULL)
330 gtk_window_move (GTK_WINDOW (gtk_frame_center), x, y);
331 #endif // HasVideo4Linux
332 }
333 // store coordinates in rectangle for further reference
334 x_rect->x = x;
335 x_rect->y = y;
336 x_rect->width = width;
337 x_rect->height = height;
338
339 // if the frame is locked, we have a GUI, and we also want to
340 // reposition the GUI (we don't want to except when repositioning the
341 // frame due too the cap_geometry cli parameter because the move of
342 // the frame would because triggered through a move of the control ...
343 // thus causing an infinite loop), move the control window, too
344 if (((app->flags & FLG_NOGUI) == 0) && reposition_control)
345 do_reposition_control (xvc_ctrl_main_window);
346
347 if (show_dimensions && ((app->flags & FLG_NOFRAME) == 0)) {
348 xml = glade_get_widget_tree (GTK_WIDGET (xvc_frame_dimensions_window));
349 g_assert (xml);
350 w = glade_xml_get_widget (xml, "xvc_frame_size_label");
351 g_assert (w);
352 sprintf (buf, "%i x %i", width, height);
353 gtk_label_set_text (GTK_LABEL (w), buf);
354 w = glade_xml_get_widget (xml, "xvc_frame_position_label");
355 g_assert (w);
356 sprintf (buf, "%i + %i", x, y);
357 gtk_label_set_text (GTK_LABEL (w), buf);
358
359 gtk_widget_show (GTK_WIDGET (xvc_frame_dimensions_window));
360 gtk_window_set_gravity (GTK_WINDOW (xvc_frame_dimensions_window),
361 GDK_GRAVITY_CENTER);
362 gtk_window_get_size (GTK_WINDOW (xvc_frame_dimensions_window),
363 &wwidth, &wheight);
364 gtk_window_move (GTK_WINDOW (xvc_frame_dimensions_window),
365 (x + (width >> 1) - (wwidth >> 1)),
366 (y + (height >> 1) - (wheight >> 1)));
367 gettimeofday (&curr_time, NULL);
368 frame_dimensions_hide_time =
369 (curr_time.tv_sec + XVC_FRAME_DIM_SHOW_TIME) * 1000;
370 g_timeout_add ((guint32) (XVC_FRAME_DIM_SHOW_TIME * 1000 + 100),
371 (GtkFunction) frame_dimensions_hide, NULL);
372 }
373 #undef DEBUGFUNCTION
374 }
375
376 /**
377 * \brief callback for the configure event on the main control to move
378 * the frame if the main control moves
379 */
380 static gint
on_gtk_frame_configure_event(GtkWidget * w,GdkEventConfigure * e)381 on_gtk_frame_configure_event (GtkWidget * w, GdkEventConfigure * e)
382 {
383 #define DEBUGFUNCTION "on_gtk_frame_configure_event()"
384 gint x, y, pwidth, pheight;
385 XVC_AppData *app = xvc_appdata_ptr ();
386 Job *job = xvc_job_ptr ();
387
388 if ((app->flags & FLG_LOCK_FOLLOWS_MOUSE) == 0 && xvc_is_frame_locked ()) {
389 GdkRectangle rect;
390
391 xvc_get_ctrl_frame_extents (GDK_WINDOW (w->window), &rect);
392 // gdk_window_get_frame_extents (GDK_WINDOW (w->window), &rect);
393
394 x = rect.x;
395 y = rect.y;
396 pwidth = rect.width;
397 pheight = rect.height;
398 y += pheight + FRAME_OFFSET + FRAME_WIDTH;
399
400 // don't move the frame in the middle of capturing
401 // let the capture thread take care of that
402 if (!app->recording_thread_running) {
403 xvc_change_gtk_frame (x, y, app->area->width, app->area->height,
404 FALSE, FALSE);
405 } else {
406 // tell the capture job we moved the frame
407 job->frame_moved_x = x - app->area->x;
408 job->frame_moved_y = y - app->area->y;
409 }
410 }
411 return FALSE;
412 #undef DEBUGFUNCTION
413 }
414
415 /**
416 * \brief callback to start the procedure for dragging the capture area frame
417 * if we're not capturing and the mouse button is not pressed already
418 */
419 gint
on_gtk_frame_enter_notify_event(GtkWidget * w,GdkEventCrossing * event)420 on_gtk_frame_enter_notify_event (GtkWidget * w, GdkEventCrossing * event)
421 {
422 gint x, y;
423 GdkModifierType mt;
424 GdkCursor *cursor;
425 Job *job = xvc_job_ptr ();
426
427 if ((job->state & VC_STOP) == 0)
428 return 0;
429
430 if (!button_pressed) {
431 gdk_window_get_pointer (w->window, &x, &y, &mt);
432
433 if (w == gtk_frame_right) {
434 if (y < XVC_MIN (FRAME_EDGE_SIZE, w->allocation.height / 3)) {
435 frame_drag_cursor = GDK_TOP_RIGHT_CORNER;
436 cursor = gdk_cursor_new (frame_drag_cursor);
437 } else if (y > XVC_MAX (w->allocation.height - FRAME_EDGE_SIZE,
438 (w->allocation.height << 1) / 3)) {
439 frame_drag_cursor = GDK_BOTTOM_RIGHT_CORNER;
440 cursor = gdk_cursor_new (frame_drag_cursor);
441 } else {
442 frame_drag_cursor = GDK_RIGHT_SIDE;
443 cursor = gdk_cursor_new (frame_drag_cursor);
444 }
445 gdk_window_set_cursor (GTK_WIDGET (gtk_frame_right)->window,
446 cursor);
447 gdk_cursor_destroy (cursor);
448 } else if (w == gtk_frame_top) {
449 if (x < XVC_MIN (FRAME_EDGE_SIZE, w->allocation.width / 3)) {
450 frame_drag_cursor = GDK_TOP_LEFT_CORNER;
451 cursor = gdk_cursor_new (frame_drag_cursor);
452 } else if (x > XVC_MAX (w->allocation.width - FRAME_EDGE_SIZE,
453 (w->allocation.width << 1) / 3)) {
454 frame_drag_cursor = GDK_TOP_RIGHT_CORNER;
455 cursor = gdk_cursor_new (frame_drag_cursor);
456 } else {
457 frame_drag_cursor = GDK_TOP_SIDE;
458 cursor = gdk_cursor_new (frame_drag_cursor);
459 }
460 gdk_window_set_cursor (GTK_WIDGET (gtk_frame_top)->window, cursor);
461 gdk_cursor_destroy (cursor);
462 } else if (w == gtk_frame_bottom) {
463 if (x < XVC_MIN (FRAME_EDGE_SIZE, w->allocation.width / 3)) {
464 frame_drag_cursor = GDK_BOTTOM_LEFT_CORNER;
465 cursor = gdk_cursor_new (frame_drag_cursor);
466 } else if (x > XVC_MAX (w->allocation.width - FRAME_EDGE_SIZE,
467 (w->allocation.width << 1) / 3)) {
468 frame_drag_cursor = GDK_BOTTOM_RIGHT_CORNER;
469 cursor = gdk_cursor_new (frame_drag_cursor);
470 } else {
471 frame_drag_cursor = GDK_BOTTOM_SIDE;
472 cursor = gdk_cursor_new (frame_drag_cursor);
473 }
474 gdk_window_set_cursor (GTK_WIDGET (gtk_frame_bottom)->window,
475 cursor);
476 gdk_cursor_destroy (cursor);
477 } else {
478 if (y < XVC_MIN (FRAME_EDGE_SIZE, w->allocation.height / 3)) {
479 frame_drag_cursor = GDK_TOP_LEFT_CORNER;
480 cursor = gdk_cursor_new (frame_drag_cursor);
481 } else if (y > XVC_MAX (w->allocation.height - FRAME_EDGE_SIZE,
482 (w->allocation.height << 1) / 3)) {
483 frame_drag_cursor = GDK_BOTTOM_LEFT_CORNER;
484 cursor = gdk_cursor_new (frame_drag_cursor);
485 } else {
486 frame_drag_cursor = GDK_LEFT_SIDE;
487 cursor = gdk_cursor_new (frame_drag_cursor);
488 }
489 gdk_window_set_cursor (GTK_WIDGET (gtk_frame_left)->window, cursor);
490 gdk_cursor_destroy (cursor);
491 }
492
493 }
494 return 0;
495 }
496
497 /**
498 * \brief resets the cursor on the capture area frame so that it will never
499 * change as for dragging during capture.
500 */
501 gint
on_gtk_frame_leave_notify_event(GtkWidget * w,GdkEventCrossing * event)502 on_gtk_frame_leave_notify_event (GtkWidget * w, GdkEventCrossing * event)
503 {
504 if (!button_pressed) {
505 frame_drag_cursor = GDK_X_CURSOR;
506 gdk_window_set_cursor (GTK_WIDGET (gtk_frame_top)->window, NULL);
507 gdk_window_set_cursor (GTK_WIDGET (gtk_frame_bottom)->window, NULL);
508 gdk_window_set_cursor (GTK_WIDGET (gtk_frame_right)->window, NULL);
509 gdk_window_set_cursor (GTK_WIDGET (gtk_frame_left)->window, NULL);
510 }
511 return 0;
512 }
513
514 /**
515 * \brief handle dragging or changing mouse pointer
516 */
517 gint
on_gtk_frame_motion_notify_event(GtkWidget * w,GdkEventMotion * event)518 on_gtk_frame_motion_notify_event (GtkWidget * w, GdkEventMotion * event)
519 {
520 gint x, y, x_root, y_root, twidth, theight;
521 GdkCursor *cursor;
522 XVC_AppData *app = xvc_appdata_ptr ();
523 Job *job = xvc_job_ptr ();
524
525 if ((job->state & VC_STOP) == 0)
526 return 0;
527
528 x = (int) event->x;
529 y = (int) event->y;
530 x_root = (int) event->x_root;
531 y_root = (int) event->y_root;
532
533 // printf("xr: %i - off: %i --- x: %i -- width: %i\n", x_root, button_press_rel_x, app->area->x, app->area->width);
534 // printf("yr: %i - off: %i --- y: %i\n", y_root, button_press_rel_y, app->area->y);
535
536 if (!button_pressed) {
537 if (w == gtk_frame_right) {
538 if (y < XVC_MIN (FRAME_EDGE_SIZE, w->allocation.height / 3)) {
539 frame_drag_cursor = GDK_TOP_RIGHT_CORNER;
540 cursor = gdk_cursor_new (frame_drag_cursor);
541 } else if (y > XVC_MAX (w->allocation.height - FRAME_EDGE_SIZE,
542 (w->allocation.height << 1) / 3)) {
543 frame_drag_cursor = GDK_BOTTOM_RIGHT_CORNER;
544 cursor = gdk_cursor_new (frame_drag_cursor);
545 } else {
546 frame_drag_cursor = GDK_RIGHT_SIDE;
547 cursor = gdk_cursor_new (frame_drag_cursor);
548 }
549 gdk_window_set_cursor (GTK_WIDGET (gtk_frame_right)->window,
550 cursor);
551 gdk_cursor_destroy (cursor);
552 } else if (w == gtk_frame_top) {
553 if (x < XVC_MIN (FRAME_EDGE_SIZE, w->allocation.width / 3)) {
554 frame_drag_cursor = GDK_TOP_LEFT_CORNER;
555 cursor = gdk_cursor_new (frame_drag_cursor);
556 } else if (x > XVC_MAX (w->allocation.width - FRAME_EDGE_SIZE,
557 (w->allocation.width << 1) / 3)) {
558 frame_drag_cursor = GDK_TOP_RIGHT_CORNER;
559 cursor = gdk_cursor_new (frame_drag_cursor);
560 } else {
561 frame_drag_cursor = GDK_TOP_SIDE;
562 cursor = gdk_cursor_new (frame_drag_cursor);
563 }
564 gdk_window_set_cursor (GTK_WIDGET (gtk_frame_top)->window, cursor);
565 gdk_cursor_destroy (cursor);
566 } else if (w == gtk_frame_bottom) {
567 if (x < XVC_MIN (FRAME_EDGE_SIZE, w->allocation.width / 3)) {
568 frame_drag_cursor = GDK_BOTTOM_LEFT_CORNER;
569 cursor = gdk_cursor_new (frame_drag_cursor);
570 } else if (x > XVC_MAX (w->allocation.width - FRAME_EDGE_SIZE,
571 (w->allocation.width << 1) / 3)) {
572 frame_drag_cursor = GDK_BOTTOM_RIGHT_CORNER;
573 cursor = gdk_cursor_new (frame_drag_cursor);
574 } else {
575 frame_drag_cursor = GDK_BOTTOM_SIDE;
576 cursor = gdk_cursor_new (frame_drag_cursor);
577 }
578 gdk_window_set_cursor (GTK_WIDGET (gtk_frame_bottom)->window,
579 cursor);
580 gdk_cursor_destroy (cursor);
581 } else {
582 if (y < XVC_MIN (FRAME_EDGE_SIZE, w->allocation.height / 3)) {
583 frame_drag_cursor = GDK_TOP_LEFT_CORNER;
584 cursor = gdk_cursor_new (frame_drag_cursor);
585 } else if (y > XVC_MAX (w->allocation.height - FRAME_EDGE_SIZE,
586 (w->allocation.height << 1) / 3)) {
587 frame_drag_cursor = GDK_BOTTOM_LEFT_CORNER;
588 cursor = gdk_cursor_new (frame_drag_cursor);
589 } else {
590 frame_drag_cursor = GDK_LEFT_SIDE;
591 cursor = gdk_cursor_new (frame_drag_cursor);
592 }
593 gdk_window_set_cursor (GTK_WIDGET (gtk_frame_left)->window, cursor);
594 gdk_cursor_destroy (cursor);
595 }
596 } else {
597 if (frame_drag_cursor == GDK_TOP_RIGHT_CORNER) {
598 x_root = x_root - button_press_rel_x;
599 y_root = y_root + button_press_rel_y;
600
601 if (x_root < (app->area->x + 20))
602 x_root = app->area->x + 20;
603 if (y_root > (app->area->y + app->area->height - 20))
604 y_root = app->area->y + app->area->height - 20;
605 twidth = x_root - app->area->x;
606 if ((twidth % 2) > 0) {
607 twidth--;
608 x_root--;
609 }
610 theight = app->area->height - y_root + app->area->y;
611 if ((theight % 2) > 0) {
612 theight--;
613 y_root++;
614 }
615
616 xvc_change_gtk_frame (app->area->x, y_root,
617 twidth, theight, FALSE, TRUE);
618 } else if (frame_drag_cursor == GDK_BOTTOM_RIGHT_CORNER) {
619 x_root = x_root - button_press_rel_x;
620 y_root = y_root - button_press_rel_y;
621
622 if (x_root < (app->area->x + 20))
623 x_root = app->area->x + 20;
624 if (y_root < (app->area->y + 20))
625 y_root = app->area->y + 20;
626 twidth = x_root - app->area->x;
627 if ((twidth % 2) > 0) {
628 twidth--;
629 x_root--;
630 }
631 theight = y_root - app->area->y;
632 if ((theight % 2) > 0) {
633 theight--;
634 y_root--;
635 }
636
637 xvc_change_gtk_frame (app->area->x, app->area->y,
638 twidth, theight, FALSE, TRUE);
639 } else if (frame_drag_cursor == GDK_RIGHT_SIDE) {
640 x_root = x_root - button_press_rel_x;
641
642 if (x_root < (app->area->x + 20))
643 x_root = app->area->x + 20;
644 twidth = x_root - app->area->x;
645 if ((twidth % 2) > 0) {
646 twidth--;
647 x_root--;
648 }
649
650 xvc_change_gtk_frame (app->area->x, app->area->y,
651 twidth, app->area->height, FALSE, TRUE);
652 } else if (frame_drag_cursor == GDK_TOP_SIDE) {
653 y_root = y_root + button_press_rel_y;
654
655 if (y_root > (app->area->y + app->area->height - 20))
656 y_root = app->area->y + app->area->height - 20;
657 theight = app->area->height - y_root + app->area->y;
658 if ((theight % 2) > 0) {
659 theight--;
660 y_root++;
661 }
662
663 xvc_change_gtk_frame (app->area->x, y_root,
664 app->area->width, theight, FALSE, TRUE);
665 } else if (frame_drag_cursor == GDK_TOP_LEFT_CORNER) {
666 x_root = x_root + button_press_rel_x;
667 y_root = y_root + button_press_rel_y;
668
669 if (x_root > (app->area->x + app->area->width - 20))
670 x_root = app->area->x + app->area->width - 20;
671 if (y_root > (app->area->y + app->area->height - 20))
672 y_root = app->area->y + app->area->height - 20;
673 twidth = app->area->width - x_root + app->area->x;
674 if ((twidth % 2) > 0) {
675 twidth--;
676 x_root++;
677 }
678 theight = app->area->height - y_root + app->area->y;
679 if ((theight % 2) > 0) {
680 theight--;
681 y_root++;
682 }
683
684 xvc_change_gtk_frame (x_root, y_root, twidth, theight, FALSE, TRUE);
685 } else if (frame_drag_cursor == GDK_LEFT_SIDE) {
686 x_root = x_root + button_press_rel_x;
687 if (x_root > (app->area->x + app->area->width - 20))
688 x_root = app->area->x + app->area->width - 20;
689 twidth = app->area->width - (x_root - app->area->x);
690 if ((twidth % 2) > 0) {
691 x_root++;
692 twidth--;
693 }
694
695 xvc_change_gtk_frame (x_root, app->area->y,
696 twidth, app->area->height, FALSE, TRUE);
697 } else if (frame_drag_cursor == GDK_BOTTOM_LEFT_CORNER) {
698 x_root = x_root + button_press_rel_x;
699 y_root = y_root - button_press_rel_y;
700
701 if (x_root > (app->area->x + app->area->width - 20))
702 x_root = app->area->x + app->area->width - 20;
703 if (y_root < (app->area->y + 20))
704 y_root = app->area->y + 20;
705 twidth = app->area->width - x_root + app->area->x;
706 if ((twidth % 2) > 0) {
707 twidth--;
708 x_root++;
709 }
710 theight = y_root - app->area->y;
711 if ((theight % 2) > 0) {
712 theight--;
713 y_root--;
714 }
715
716 xvc_change_gtk_frame (x_root, app->area->y,
717 twidth, theight, FALSE, TRUE);
718 } else { // GDK_BOTTOM_SIDE
719 y_root = y_root - button_press_rel_y;
720
721 if (y_root < (app->area->y + 20))
722 y_root = app->area->y + 20;
723 theight = y_root - app->area->y;
724 if ((theight % 2) > 0) {
725 theight--;
726 y_root--;
727 }
728
729 xvc_change_gtk_frame (app->area->x, app->area->y,
730 app->area->width, theight, FALSE, TRUE);
731 }
732 }
733 return 0;
734 }
735
736 /**
737 * \brief track mouse pointer presses on frame
738 */
739 gint
on_gtk_frame_button_press_event(GtkWidget * w,GdkEventButton * event)740 on_gtk_frame_button_press_event (GtkWidget * w, GdkEventButton * event)
741 {
742 XVC_AppData *app = xvc_appdata_ptr ();
743
744 button_pressed = TRUE;
745 if (w == gtk_frame_right) {
746 button_press_rel_x = event->x + 1;
747 button_press_rel_y = 0;
748 } else if (w == gtk_frame_top) {
749 if (event->x < FRAME_WIDTH) {
750 button_press_rel_x = FRAME_WIDTH - event->x - 1;
751 } else if (event->x > app->area->width + FRAME_WIDTH) {
752 button_press_rel_x = event->x - app->area->width - FRAME_WIDTH;
753 } else {
754 button_press_rel_x = 0;
755 }
756 button_press_rel_y = FRAME_WIDTH - event->y - 1;
757 } else if (w == gtk_frame_bottom) {
758 if (event->x < FRAME_WIDTH) {
759 button_press_rel_x = FRAME_WIDTH - event->x - 1;
760 } else if (event->x > app->area->width + FRAME_WIDTH) {
761 button_press_rel_x = event->x - app->area->width - FRAME_WIDTH;
762 } else {
763 button_press_rel_x = 0;
764 }
765 button_press_rel_y = event->y + 1;
766 } else {
767 button_press_rel_x = FRAME_WIDTH - event->x - 1;
768 button_press_rel_y = 0;
769 }
770 // printf("x %i y %i\n", button_press_rel_x, button_press_rel_y);
771 return 0;
772 }
773
774 /**
775 * \brief track mouse pointer presses on frame
776 */
777 gint
on_gtk_frame_button_release_event(GtkWidget * w,GdkEventButton * event)778 on_gtk_frame_button_release_event (GtkWidget * w, GdkEventButton * event)
779 {
780 if (xvc_is_frame_locked ()) {
781 XVC_AppData *app = xvc_appdata_ptr ();
782
783 xvc_change_gtk_frame (app->area->x, app->area->y,
784 app->area->width, app->area->height, TRUE, FALSE);
785 }
786 button_pressed = FALSE;
787 return 0;
788 }
789
790 /**
791 * \brief creates a frame around the area to capture
792 *
793 * @param toplevel a pointer to the main control
794 * @param pwidth width for the frame
795 * @param pheight height for the frame
796 * @param px x-position for the frame
797 * @param py y-position for the frame
798 */
799 void
xvc_create_gtk_frame(GtkWidget * toplevel,int pwidth,int pheight,int px,int py)800 xvc_create_gtk_frame (GtkWidget * toplevel, int pwidth, int pheight,
801 int px, int py)
802 {
803 #define DEBUGFUNCTION "xvc_create_gtk_frame()"
804 gint x = 0, y = 0;
805 GdkColor g_col;
806 GdkColormap *colormap;
807 GdkRectangle rect;
808 XVC_AppData *app = xvc_appdata_ptr ();
809 int flags = app->flags;
810 XRectangle *x_rect = xvc_get_capture_area ();
811 GladeXML *xml = NULL;
812
813 #ifdef DEBUG
814 printf ("%s %s: x %d y %d width %d height %d\n", DEBUGFILE,
815 DEBUGFUNCTION, px, py, pwidth, pheight);
816 #endif
817
818 #ifdef USE_FFMPEG
819 //
820 // make sure we have even width and height for ffmpeg
821 //
822 if (app->current_mode > 0) {
823 Boolean changed = FALSE;
824
825 if ((pwidth % 2) > 0) {
826 pwidth--;
827 changed = TRUE;
828 }
829 if ((pheight % 2) > 0) {
830 pheight--;
831 changed = TRUE;
832 }
833 if (pwidth < 10) {
834 pwidth = 10;
835 changed = TRUE;
836 }
837 if (pheight < 10) {
838 pheight = 10;
839 changed = TRUE;
840 }
841
842 if (changed) {
843 if (app->flags & FLG_RUN_VERBOSE) {
844 printf
845 ("Modified Selection geometry: %dx%d+%d+%d\n",
846 pwidth, pheight, x, y);
847 }
848 }
849 }
850 #endif // USE_FFMPEG
851
852 // we have to adjust it to viewable areas
853 // max_width = WidthOfScreen (DefaultScreenOfDisplay (app->dpy));
854 // max_height = HeightOfScreen (DefaultScreenOfDisplay (app->dpy));
855
856 #ifdef DEBUG
857 printf ("%s %s: screen = %dx%d selection=%dx%d\n", DEBUGFILE,
858 DEBUGFUNCTION, app->max_width, app->max_height, pwidth, pheight);
859 #endif
860
861 if (x < 0)
862 x = 0;
863 if (pwidth > app->max_width)
864 pwidth = app->max_width;
865 if (x + pwidth > app->max_width)
866 x = app->max_width - pwidth;
867
868 if (y < 0)
869 y = 0;
870 if (pheight > app->max_height)
871 pheight = app->max_height;
872 if (y + pheight > app->max_height)
873 y = app->max_height - pheight;
874
875 // now for the real work
876 if (!(flags & FLG_NOGUI)) {
877 g_assert (toplevel);
878
879 if (px < 0 && py < 0) {
880 // compute position for frame
881 xvc_get_ctrl_frame_extents (GDK_WINDOW (toplevel->window), &rect);
882 // gdk_window_get_frame_extents (GDK_WINDOW (toplevel->window), &rect);
883
884 if (x < 0)
885 x = 0;
886
887 y = rect.y;
888 y += rect.height + FRAME_OFFSET;
889 if (y < 0)
890 y = 0;
891 } else {
892 x = (px < 0 ? 0 : px);
893 y = (py < 0 ? 0 : py);
894 }
895 } else {
896 x = (px < 0 ? 0 : px);
897 y = (py < 0 ? 0 : py);
898 }
899
900 // store rectangle properties for further reference
901 g_assert (x_rect);
902
903 x_rect->width = pwidth;
904 x_rect->height = pheight;
905 x_rect->x = x;
906 x_rect->y = y;
907
908 // create frame
909 if (!(flags & FLG_NOGUI) && !(flags & FLG_NOFRAME)) {
910
911 // top of frame
912 gtk_frame_top = gtk_window_new (GTK_WINDOW_POPUP);
913 g_assert (gtk_frame_top);
914
915 gtk_widget_set_size_request (GTK_WIDGET (gtk_frame_top),
916 (pwidth + 2 * FRAME_WIDTH), FRAME_WIDTH);
917 gtk_window_set_title (GTK_WINDOW (gtk_frame_top), "gtk_frame_top");
918 gtk_window_set_resizable (GTK_WINDOW (gtk_frame_top), FALSE);
919 gtk_widget_add_events (GTK_WIDGET (gtk_frame_top),
920 (GDK_POINTER_MOTION_MASK |
921 GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_PRESS_MASK
922 | GDK_BUTTON_RELEASE_MASK));
923
924 colormap = gtk_widget_get_colormap (GTK_WIDGET (gtk_frame_top));
925 g_assert (colormap);
926
927 if (gdk_color_parse ("red", &g_col)) {
928 // do the following only if parsing color red succeeded ...
929 // if not, we met an error but handle it gracefully by
930 // ignoring the frame
931 // color
932 if (gdk_colormap_alloc_color
933 (GDK_COLORMAP (colormap), &g_col, FALSE, TRUE)) {
934 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_top),
935 GTK_STATE_NORMAL, &g_col);
936 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_top),
937 GTK_STATE_ACTIVE, &g_col);
938 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_top),
939 GTK_STATE_PRELIGHT, &g_col);
940 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_top),
941 GTK_STATE_INSENSITIVE, &g_col);
942 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_top),
943 GTK_STATE_SELECTED, &g_col);
944
945 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_top),
946 GTK_STATE_NORMAL, &g_col);
947 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_top),
948 GTK_STATE_ACTIVE, &g_col);
949 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_top),
950 GTK_STATE_PRELIGHT, &g_col);
951 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_top),
952 GTK_STATE_INSENSITIVE, &g_col);
953 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_top),
954 GTK_STATE_SELECTED, &g_col);
955 }
956 }
957 gtk_widget_show (gtk_frame_top);
958 gtk_window_move (GTK_WINDOW (gtk_frame_top), (x - FRAME_WIDTH),
959 (y - FRAME_WIDTH));
960
961 // left side of frame
962 gtk_frame_left = gtk_window_new (GTK_WINDOW_POPUP);
963 g_assert (gtk_frame_left);
964
965 gtk_widget_set_size_request (GTK_WIDGET (gtk_frame_left),
966 FRAME_WIDTH, pheight);
967 gtk_window_set_title (GTK_WINDOW (gtk_frame_left), "gtk_frame_left");
968 gtk_window_set_resizable (GTK_WINDOW (gtk_frame_left), FALSE);
969 gtk_widget_add_events (GTK_WIDGET (gtk_frame_left),
970 (GDK_POINTER_MOTION_MASK |
971 GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_PRESS_MASK
972 | GDK_BUTTON_RELEASE_MASK));
973
974 colormap = gtk_widget_get_colormap (GTK_WIDGET (gtk_frame_left));
975 g_assert (colormap);
976
977 if (gdk_color_parse ("red", &g_col)) {
978 // do the following only if parsing color red succeeded ...
979 // if not, we met an error but handle it gracefully by
980 // ignoring the frame color
981 if (gdk_colormap_alloc_color
982 (GDK_COLORMAP (colormap), &g_col, FALSE, TRUE)) {
983 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_left),
984 GTK_STATE_NORMAL, &g_col);
985 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_left),
986 GTK_STATE_ACTIVE, &g_col);
987 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_left),
988 GTK_STATE_PRELIGHT, &g_col);
989 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_left),
990 GTK_STATE_INSENSITIVE, &g_col);
991 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_left),
992 GTK_STATE_SELECTED, &g_col);
993
994 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_left),
995 GTK_STATE_NORMAL, &g_col);
996 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_left),
997 GTK_STATE_ACTIVE, &g_col);
998 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_left),
999 GTK_STATE_PRELIGHT, &g_col);
1000 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_left),
1001 GTK_STATE_INSENSITIVE, &g_col);
1002 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_left),
1003 GTK_STATE_SELECTED, &g_col);
1004 }
1005 }
1006 gtk_widget_show (GTK_WIDGET (gtk_frame_left));
1007 gtk_window_move (GTK_WINDOW (gtk_frame_left), (x - FRAME_WIDTH), y);
1008
1009 // bottom of frame
1010 gtk_frame_bottom = gtk_window_new (GTK_WINDOW_POPUP);
1011 g_assert (gtk_frame_bottom);
1012
1013 gtk_widget_set_size_request (GTK_WIDGET (gtk_frame_bottom),
1014 (pwidth + 2 * FRAME_WIDTH), FRAME_WIDTH);
1015 gtk_window_set_title (GTK_WINDOW (gtk_frame_bottom),
1016 "gtk_frame_bottom");
1017 gtk_window_set_resizable (GTK_WINDOW (gtk_frame_bottom), FALSE);
1018 gtk_widget_add_events (GTK_WIDGET (gtk_frame_bottom),
1019 (GDK_POINTER_MOTION_MASK |
1020 GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_PRESS_MASK
1021 | GDK_BUTTON_RELEASE_MASK));
1022
1023 colormap = gtk_widget_get_colormap (gtk_frame_bottom);
1024 g_assert (colormap);
1025
1026 if (gdk_color_parse ("red", &g_col)) {
1027 // do the following only if parsing color red succeeded ...
1028 // if not, we met an error but handle it gracefully by
1029 // ignoring the frame color
1030 if (gdk_colormap_alloc_color
1031 (GDK_COLORMAP (colormap), &g_col, FALSE, TRUE)) {
1032 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_bottom),
1033 GTK_STATE_NORMAL, &g_col);
1034 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_bottom),
1035 GTK_STATE_ACTIVE, &g_col);
1036 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_bottom),
1037 GTK_STATE_PRELIGHT, &g_col);
1038 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_bottom),
1039 GTK_STATE_INSENSITIVE, &g_col);
1040 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_bottom),
1041 GTK_STATE_SELECTED, &g_col);
1042
1043 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_bottom),
1044 GTK_STATE_NORMAL, &g_col);
1045 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_bottom),
1046 GTK_STATE_ACTIVE, &g_col);
1047 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_bottom),
1048 GTK_STATE_PRELIGHT, &g_col);
1049 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_bottom),
1050 GTK_STATE_INSENSITIVE, &g_col);
1051 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_bottom),
1052 GTK_STATE_SELECTED, &g_col);
1053 }
1054 }
1055 gtk_widget_show (GTK_WIDGET (gtk_frame_bottom));
1056 gtk_window_move (GTK_WINDOW (gtk_frame_bottom), (x - FRAME_WIDTH),
1057 (y + pheight));
1058
1059 // right side of frame
1060 gtk_frame_right = gtk_window_new (GTK_WINDOW_POPUP);
1061 g_assert (gtk_frame_right);
1062
1063 gtk_widget_set_size_request (GTK_WIDGET (gtk_frame_right),
1064 FRAME_WIDTH, pheight);
1065 gtk_window_set_title (GTK_WINDOW (gtk_frame_right), "gtk_frame_right");
1066 gtk_window_set_resizable (GTK_WINDOW (gtk_frame_right), FALSE);
1067 gtk_widget_add_events (GTK_WIDGET (gtk_frame_right),
1068 (GDK_POINTER_MOTION_MASK |
1069 GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_PRESS_MASK
1070 | GDK_BUTTON_RELEASE_MASK));
1071
1072 colormap = gtk_widget_get_colormap (gtk_frame_right);
1073 g_assert (colormap);
1074
1075 if (gdk_color_parse ("red", &g_col)) {
1076 // do the following only if parsing color red succeeded ...
1077 // if not, we met an error but handle it gracefully by
1078 // ignoring the frame color
1079 if (gdk_colormap_alloc_color
1080 (GDK_COLORMAP (colormap), &g_col, FALSE, TRUE)) {
1081 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_right),
1082 GTK_STATE_NORMAL, &g_col);
1083 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_right),
1084 GTK_STATE_ACTIVE, &g_col);
1085 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_right),
1086 GTK_STATE_PRELIGHT, &g_col);
1087 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_right),
1088 GTK_STATE_INSENSITIVE, &g_col);
1089 gtk_widget_modify_bg (GTK_WIDGET (gtk_frame_right),
1090 GTK_STATE_SELECTED, &g_col);
1091
1092 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_right),
1093 GTK_STATE_NORMAL, &g_col);
1094 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_right),
1095 GTK_STATE_ACTIVE, &g_col);
1096 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_right),
1097 GTK_STATE_PRELIGHT, &g_col);
1098 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_right),
1099 GTK_STATE_INSENSITIVE, &g_col);
1100 gtk_widget_modify_fg (GTK_WIDGET (gtk_frame_right),
1101 GTK_STATE_SELECTED, &g_col);
1102 }
1103 }
1104 gtk_widget_show (GTK_WIDGET (gtk_frame_right));
1105 gtk_window_move (GTK_WINDOW (gtk_frame_right), (x + pwidth), y);
1106
1107 xml =
1108 glade_xml_new (XVC_GLADE_FILE, "xvc_frame_dimensions_window", NULL);
1109 g_assert (xml);
1110 xvc_frame_dimensions_window =
1111 glade_xml_get_widget (xml, "xvc_frame_dimensions_window");
1112
1113 #ifdef HasVideo4Linux
1114 if (flags & FLG_USE_V4L) {
1115 gtk_frame_center = gtk_dialog_new ();
1116
1117 g_assert (gtk_frame_center);
1118
1119 gtk_widget_set_size_request (GTK_WIDGET (gtk_frame_center),
1120 pwidth, pheight);
1121 gtk_widget_set_sensitive (GTK_WIDGET (gtk_frame_center), FALSE);
1122 gtk_window_set_title (GTK_WINDOW (gtk_frame_right),
1123 "gtk_frame_center");
1124 GTK_WINDOW (gtk_frame_center)->type = GTK_WINDOW_POPUP;
1125 gtk_window_set_resizable (GTK_WINDOW (gtk_frame_center), FALSE);
1126 gtk_dialog_set_has_separator (GTK_DIALOG (gtk_frame_center), FALSE);
1127 gtk_widget_show (GTK_WIDGET (gtk_frame_center));
1128 gtk_window_move (GTK_WINDOW (gtk_frame_center), x, y);
1129
1130 // FIXME: right now the label for the Video Source is missing
1131 // gtk_frame_center = XtVaCreatePopupShell ("blind",
1132 // overrideShellWidgetClass, parent,
1133 // XtNx, x+FRAME_WIDTH,
1134 // XtNy, y+FRAME_WIDTH,
1135 // XtNwidth, width,
1136 // XtNheight, height,
1137 // NULL);
1138 // XtVaCreateManagedWidget ("text", xwLabelWidgetClass, blind,
1139 // XtNlabel, "Source: Video4Linux", NULL);
1140 // XtPopup(blind, XtGrabNone);
1141 }
1142 #endif // HasVideo4Linux
1143 g_signal_connect (G_OBJECT (gtk_frame_top), "enter_notify_event",
1144 G_CALLBACK (on_gtk_frame_enter_notify_event), NULL);
1145 g_signal_connect (G_OBJECT (gtk_frame_left), "enter_notify_event",
1146 G_CALLBACK (on_gtk_frame_enter_notify_event), NULL);
1147 g_signal_connect (G_OBJECT (gtk_frame_bottom), "enter_notify_event",
1148 G_CALLBACK (on_gtk_frame_enter_notify_event), NULL);
1149 g_signal_connect (G_OBJECT (gtk_frame_right), "enter_notify_event",
1150 G_CALLBACK (on_gtk_frame_enter_notify_event), NULL);
1151
1152 g_signal_connect (G_OBJECT (gtk_frame_top), "leave_notify_event",
1153 G_CALLBACK (on_gtk_frame_leave_notify_event), NULL);
1154 g_signal_connect (G_OBJECT (gtk_frame_left), "leave_notify_event",
1155 G_CALLBACK (on_gtk_frame_leave_notify_event), NULL);
1156 g_signal_connect (G_OBJECT (gtk_frame_bottom), "leave_notify_event",
1157 G_CALLBACK (on_gtk_frame_leave_notify_event), NULL);
1158 g_signal_connect (G_OBJECT (gtk_frame_right), "leave_notify_event",
1159 G_CALLBACK (on_gtk_frame_leave_notify_event), NULL);
1160
1161 g_signal_connect (G_OBJECT (gtk_frame_top), "motion_notify_event",
1162 G_CALLBACK (on_gtk_frame_motion_notify_event), NULL);
1163 g_signal_connect (G_OBJECT (gtk_frame_left), "motion_notify_event",
1164 G_CALLBACK (on_gtk_frame_motion_notify_event), NULL);
1165 g_signal_connect (G_OBJECT (gtk_frame_bottom), "motion_notify_event",
1166 G_CALLBACK (on_gtk_frame_motion_notify_event), NULL);
1167 g_signal_connect (G_OBJECT (gtk_frame_right), "motion_notify_event",
1168 G_CALLBACK (on_gtk_frame_motion_notify_event), NULL);
1169
1170 g_signal_connect (G_OBJECT (gtk_frame_top), "button_press_event",
1171 G_CALLBACK (on_gtk_frame_button_press_event), NULL);
1172 g_signal_connect (G_OBJECT (gtk_frame_left), "button_press_event",
1173 G_CALLBACK (on_gtk_frame_button_press_event), NULL);
1174 g_signal_connect (G_OBJECT (gtk_frame_bottom), "button_press_event",
1175 G_CALLBACK (on_gtk_frame_button_press_event), NULL);
1176 g_signal_connect (G_OBJECT (gtk_frame_right), "button_press_event",
1177 G_CALLBACK (on_gtk_frame_button_press_event), NULL);
1178
1179 g_signal_connect (G_OBJECT (gtk_frame_top), "button_release_event",
1180 G_CALLBACK (on_gtk_frame_button_release_event), NULL);
1181 g_signal_connect (G_OBJECT (gtk_frame_left), "button_release_event",
1182 G_CALLBACK (on_gtk_frame_button_release_event), NULL);
1183 g_signal_connect (G_OBJECT (gtk_frame_bottom), "button_release_event",
1184 G_CALLBACK (on_gtk_frame_button_release_event), NULL);
1185 g_signal_connect (G_OBJECT (gtk_frame_right), "button_release_event",
1186 G_CALLBACK (on_gtk_frame_button_release_event), NULL);
1187
1188 }
1189 // connect event-handler to configure event of gtk control window
1190 // to redraw the selection frame if the control is moved and the
1191 // frame is locked
1192 // this is also required with FLG_NOFRAME
1193 if (!(flags & FLG_NOGUI)) {
1194 g_signal_connect (G_OBJECT (toplevel), "configure-event",
1195 G_CALLBACK (on_gtk_frame_configure_event), NULL);
1196 }
1197
1198 xvc_set_frame_locked (1);
1199
1200 if (!(flags & FLG_NOGUI) && (px >= 0 || py >= 0))
1201 do_reposition_control (toplevel);
1202
1203 #undef DEBUGFUNCTION
1204 }
1205
1206 /**
1207 * \brief destroys the frame around the capture area
1208 */
1209 void
xvc_destroy_gtk_frame()1210 xvc_destroy_gtk_frame ()
1211 {
1212 #define DEBUGFUNCTION "xvc_destroy_gtk_frame()"
1213
1214 if (gtk_frame_bottom) {
1215 gtk_widget_destroy (gtk_frame_bottom);
1216 gtk_frame_bottom = NULL;
1217 }
1218 if (gtk_frame_right) {
1219 gtk_widget_destroy (gtk_frame_right);
1220 gtk_frame_right = NULL;
1221 }
1222 if (gtk_frame_left) {
1223 gtk_widget_destroy (gtk_frame_left);
1224 gtk_frame_left = NULL;
1225 }
1226 if (gtk_frame_top) {
1227 gtk_widget_destroy (gtk_frame_top);
1228 gtk_frame_top = NULL;
1229 }
1230 if (xvc_frame_dimensions_window) {
1231 gtk_widget_destroy (xvc_frame_dimensions_window);
1232 xvc_frame_dimensions_window = NULL;
1233 }
1234 if (gtk_frame_center) {
1235 gtk_widget_destroy (gtk_frame_center);
1236 gtk_frame_center = NULL;
1237 }
1238 #undef DEBUGFUNCTION
1239 }
1240