]> git.sesse.net Git - vlc/blobdiff - modules/video_output/x11/xcommon.c
*: a new mouse gestures interface, currently supporting back, forward, quit
[vlc] / modules / video_output / x11 / xcommon.c
index b3fffe4b8caaada29e73b2a9093c4bca25f4cabc..e8f51092f6c9beb643a1c47581d6015595047a3d 100644 (file)
@@ -2,7 +2,7 @@
  * xcommon.c: Functions common to the X11 and XVideo plugins
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: xcommon.c,v 1.6 2002/10/17 16:48:41 sam Exp $
+ * $Id: xcommon.c,v 1.14 2003/02/09 23:42:06 sigmunau Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -89,7 +89,7 @@ static void DestroyWindow  ( vout_thread_t *, x11_window_t * );
 static int  NewPicture     ( vout_thread_t *, picture_t * );
 static void FreePicture    ( vout_thread_t *, picture_t * );
 
-static IMAGE_TYPE *CreateImage    ( vout_thread_t *, 
+static IMAGE_TYPE *CreateImage    ( vout_thread_t *,
                                     Display *, EXTRA_ARGS, int, int );
 #ifdef HAVE_SYS_SHM_H
 static IMAGE_TYPE *CreateShmImage ( vout_thread_t *,
@@ -111,7 +111,8 @@ static void XVideoReleasePort( vout_thread_t *, int );
 #endif
 
 #ifdef MODULE_NAME_IS_x11
-static void SetPalette     ( vout_thread_t *, u16 *, u16 *, u16 * );
+static void SetPalette     ( vout_thread_t *,
+                             uint16_t *, uint16_t *, uint16_t * );
 #endif
 
 /*****************************************************************************
@@ -145,7 +146,7 @@ int E_(Activate) ( vlc_object_t *p_this )
         return VLC_ENOMEM;
     }
 
-    /* Open display, unsing the "display" config variable or the DISPLAY
+    /* Open display, using the "display" config variable or the DISPLAY
      * environment variable */
     psz_display = config_GetPsz( p_vout, MODULE_STRING "-display" );
 
@@ -183,7 +184,7 @@ int E_(Activate) ( vlc_object_t *p_this )
 
     if( b_chroma )
     {
-        msg_Dbg( p_vout, "forcing chroma 0x%.8x (%4.4s)", 
+        msg_Dbg( p_vout, "forcing chroma 0x%.8x (%4.4s)",
                  i_chroma, (char*)&i_chroma );
     }
     else
@@ -490,15 +491,17 @@ static int ManageVideo( vout_thread_t *p_vout )
     while( XCheckWindowEvent( p_vout->p_sys->p_display,
                               p_vout->p_sys->p_win->base_window,
                               StructureNotifyMask | KeyPressMask |
-                              ButtonPressMask | ButtonReleaseMask | 
+                              ButtonPressMask | ButtonReleaseMask |
                               PointerMotionMask | Button1MotionMask , &xevent )
            == True )
     {
         /* ConfigureNotify event: prepare  */
         if( xevent.type == ConfigureNotify )
         {
-            if( (xevent.xconfigure.width != p_vout->p_sys->p_win->i_width)
-              || (xevent.xconfigure.height != p_vout->p_sys->p_win->i_height) )
+            if( (unsigned int)xevent.xconfigure.width
+                   != p_vout->p_sys->p_win->i_width
+              || (unsigned int)xevent.xconfigure.height
+                    != p_vout->p_sys->p_win->i_height )
             {
                 /* Update dimensions */
                 p_vout->i_changes |= VOUT_SIZE_CHANGE;
@@ -512,7 +515,7 @@ static int ManageVideo( vout_thread_t *p_vout )
             /* We may have keys like F1 trough F12, ESC ... */
             x_key_symbol = XKeycodeToKeysym( p_vout->p_sys->p_display,
                                              xevent.xkey.keycode, 0 );
-            switch( x_key_symbol )
+            switch( (int)x_key_symbol )
             {
             case XK_Escape:
                 if( p_vout->b_fullscreen )
@@ -579,7 +582,7 @@ static int ManageVideo( vout_thread_t *p_vout )
 
             default:
                 /* "Normal Keys"
-                 * The reason why I use this instead of XK_0 is that 
+                 * The reason why I use this instead of XK_0 is that
                  * with XLookupString, we don't have to care about
                  * keymaps. */
 
@@ -610,7 +613,10 @@ static int ManageVideo( vout_thread_t *p_vout )
             switch( ((XButtonEvent *)&xevent)->button )
             {
                 case Button1:
-
+                    var_Get( p_vout, "mouse-button-down", &val );
+                    val.i_int |= 1;
+                    var_Set( p_vout, "mouse-button-down", val );
+                    
                     /* detect double-clicks */
                     if( ( ((XButtonEvent *)&xevent)->time -
                           p_vout->p_sys->i_time_button_last_pressed ) < 300 )
@@ -621,12 +627,29 @@ static int ManageVideo( vout_thread_t *p_vout )
                     p_vout->p_sys->i_time_button_last_pressed =
                         ((XButtonEvent *)&xevent)->time;
                     break;
-
+                case Button2:
+                    var_Get( p_vout, "mouse-button-down", &val );
+                    val.i_int |= 2;
+                    var_Set( p_vout, "mouse-button-down", val );
+                    break;
+                
+                case Button3:
+                    var_Get( p_vout, "mouse-button-down", &val );
+                    val.i_int |= 4;
+                    var_Set( p_vout, "mouse-button-down", val );
+                    break;
+                
                 case Button4:
+                    var_Get( p_vout, "mouse-button-down", &val );
+                    val.i_int |= 8;
+                    var_Set( p_vout, "mouse-button-down", val );
                     input_Seek( p_vout, 15, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
                     break;
 
                 case Button5:
+                    var_Get( p_vout, "mouse-button-down", &val );
+                    val.i_int |= 16;
+                    var_Set( p_vout, "mouse-button-down", val );
                     input_Seek( p_vout, -15, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
                     break;
             }
@@ -637,13 +660,26 @@ static int ManageVideo( vout_thread_t *p_vout )
             switch( ((XButtonEvent *)&xevent)->button )
             {
                 case Button1:
+                    var_Get( p_vout, "mouse-button-down", &val );
+                    val.i_int &= ~1;
+                    var_Set( p_vout, "mouse-button-down", val );
+
                     val.b_bool = VLC_TRUE;
                     var_Set( p_vout, "mouse-clicked", val );
                     break;
-
+                    
+                case Button2:
+                    var_Get( p_vout, "mouse-button-down", &val );
+                    val.i_int &= ~2;
+                    var_Set( p_vout, "mouse-button-down", val );
+                    break;
+                    
                 case Button3:
                     {
                         intf_thread_t *p_intf;
+                        var_Get( p_vout, "mouse-button-down", &val );
+                        val.i_int &= ~4;
+                        var_Set( p_vout, "mouse-button-down", val );
                         p_intf = vlc_object_find( p_vout, VLC_OBJECT_INTF,
                                                           FIND_ANYWHERE );
                         if( p_intf )
@@ -653,6 +689,19 @@ static int ManageVideo( vout_thread_t *p_vout )
                         }
                     }
                     break;
+
+                case Button4:
+                    var_Get( p_vout, "mouse-button-down", &val );
+                    val.i_int &= ~8;
+                    var_Set( p_vout, "mouse-button-down", val );
+                    break;
+
+                case Button5:
+                    var_Get( p_vout, "mouse-button-down", &val );
+                    val.i_int &= ~16;
+                    var_Set( p_vout, "mouse-button-down", val );
+                    break;
+                    
             }
         }
         /* Mouse move */
@@ -681,16 +730,16 @@ static int ManageVideo( vout_thread_t *p_vout )
             p_vout->p_sys->i_time_mouse_last_moved = mdate();
             if( ! p_vout->p_sys->b_mouse_pointer_visible )
             {
-                ToggleCursor( p_vout ); 
+                ToggleCursor( p_vout );
             }
         }
-        /* Reparent move -- XXX: why are we getting this ? */
-        else if( xevent.type == ReparentNotify )
+        else if( xevent.type == ReparentNotify /* XXX: why do we get this? */
+                  || xevent.type == MapNotify
+                  || xevent.type == UnmapNotify )
         {
-            ;
+            /* Ignore these events */
         }
-        /* Other event */
-        else
+        else /* Other events */
         {
             msg_Warn( p_vout, "unhandled event %d received", xevent.type );
         }
@@ -728,7 +777,7 @@ static int ManageVideo( vout_thread_t *p_vout )
                              ClientMessage, &xevent ) )
     {
         if( (xevent.xclient.message_type == p_vout->p_sys->p_win->wm_protocols)
-               && (xevent.xclient.data.l[0]
+               && ((Atom)xevent.xclient.data.l[0]
                      == p_vout->p_sys->p_win->wm_delete_window ) )
         {
             p_vout->p_vlc->b_die = 1;
@@ -756,10 +805,6 @@ static int ManageVideo( vout_thread_t *p_vout )
 
         p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
 
-        msg_Dbg( p_vout, "video display resized (%dx%d)",
-                         p_vout->p_sys->p_win->i_width,
-                         p_vout->p_sys->p_win->i_height );
 #ifdef MODULE_NAME_IS_x11
         /* We need to signal the vout thread about the size change because it
          * is doing the rescaling */
@@ -772,7 +817,7 @@ static int ManageVideo( vout_thread_t *p_vout )
 
         XResizeWindow( p_vout->p_sys->p_display,
                        p_vout->p_sys->p_win->video_window, i_width, i_height );
-        
+
         XMoveWindow( p_vout->p_sys->p_display,
                      p_vout->p_sys->p_win->video_window, i_x, i_y );
     }
@@ -824,6 +869,7 @@ static int CreateWindow( vout_thread_t *p_vout, x11_window_t *p_win )
     vlc_bool_t              b_configure_notify;
     vlc_bool_t              b_map_notify;
 
+    vlc_value_t             val;
     long long int           i_drawable;
 
     /* Prepare window manager hints and properties */
@@ -842,10 +888,10 @@ static int CreateWindow( vout_thread_t *p_vout, x11_window_t *p_win )
     xwindow_attributes.event_mask = ExposureMask | StructureNotifyMask;
 
     /* Check whether someone provided us with a window ID */
-    i_drawable = p_vout->b_fullscreen ?
-                    -1 : config_GetInt( p_vout, MODULE_STRING "-drawable");
+    var_Get( p_vout->p_vlc, "drawable", &val );
+    i_drawable = p_vout->b_fullscreen ? 0 : val.i_int;
 
-    if( i_drawable == -1 )
+    if( !i_drawable )
     {
         p_win->b_owned = VLC_TRUE;
 
@@ -899,7 +945,7 @@ static int CreateWindow( vout_thread_t *p_vout, x11_window_t *p_win )
     {
         /* WM_DELETE_WINDOW is not supported by window manager */
         msg_Warn( p_vout, "missing or bad window manager" );
-    } 
+    }
 
     /* Creation of a graphic context that doesn't generate a GraphicsExpose
      * event when using functions like XCopyArea */
@@ -955,7 +1001,7 @@ static int CreateWindow( vout_thread_t *p_vout, x11_window_t *p_win )
 
     XSelectInput( p_vout->p_sys->p_display, p_win->base_window,
                   StructureNotifyMask | KeyPressMask |
-                  ButtonPressMask | ButtonReleaseMask | 
+                  ButtonPressMask | ButtonReleaseMask |
                   PointerMotionMask );
 
 #ifdef MODULE_NAME_IS_x11
@@ -1076,7 +1122,7 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
                          p_vout->p_sys->i_xvport, p_vout->output.i_chroma,
 #else
                          p_vout->p_sys->p_visual,
-                         p_vout->p_sys->i_screen_depth, 
+                         p_vout->p_sys->i_screen_depth,
                          p_vout->p_sys->i_bytes_per_pixel,
 #endif
                          p_vout->output.i_width, p_vout->output.i_height );
@@ -1098,21 +1144,21 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
             p_pic->p[Y_PLANE].i_lines = p_vout->output.i_height;
             p_pic->p[Y_PLANE].i_pitch = p_pic->p_sys->p_image->pitches[0];
             p_pic->p[Y_PLANE].i_pixel_pitch = 1;
-            p_pic->p[Y_PLANE].i_visible_pitch = p_pic->p[Y_PLANE].i_pitch;
+            p_pic->p[Y_PLANE].i_visible_pitch = p_vout->output.i_width;
 
             p_pic->U_PIXELS = p_pic->p_sys->p_image->data
                                + p_pic->p_sys->p_image->offsets[1];
             p_pic->p[U_PLANE].i_lines = p_vout->output.i_height / 2;
             p_pic->p[U_PLANE].i_pitch = p_pic->p_sys->p_image->pitches[1];
             p_pic->p[U_PLANE].i_pixel_pitch = 1;
-            p_pic->p[U_PLANE].i_visible_pitch = p_pic->p[U_PLANE].i_pitch;
+            p_pic->p[U_PLANE].i_visible_pitch = p_vout->output.i_width / 2;
 
             p_pic->V_PIXELS = p_pic->p_sys->p_image->data
                                + p_pic->p_sys->p_image->offsets[2];
             p_pic->p[V_PLANE].i_lines = p_vout->output.i_height / 2;
             p_pic->p[V_PLANE].i_pitch = p_pic->p_sys->p_image->pitches[2];
             p_pic->p[V_PLANE].i_pixel_pitch = 1;
-            p_pic->p[V_PLANE].i_visible_pitch = p_pic->p[V_PLANE].i_pitch;
+            p_pic->p[V_PLANE].i_visible_pitch = p_vout->output.i_width / 2;
 
             p_pic->i_planes = 3;
             break;
@@ -1125,20 +1171,21 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
             p_pic->p[Y_PLANE].i_pitch = p_pic->p_sys->p_image->pitches[0];
             p_pic->p[Y_PLANE].i_pixel_pitch = 1;
             p_pic->p[Y_PLANE].i_visible_pitch = p_pic->p[Y_PLANE].i_pitch;
+            p_pic->p[Y_PLANE].i_visible_pitch = p_vout->output.i_width;
 
             p_pic->U_PIXELS = p_pic->p_sys->p_image->data
                                + p_pic->p_sys->p_image->offsets[2];
             p_pic->p[U_PLANE].i_lines = p_vout->output.i_height / 2;
             p_pic->p[U_PLANE].i_pitch = p_pic->p_sys->p_image->pitches[2];
             p_pic->p[U_PLANE].i_pixel_pitch = 1;
-            p_pic->p[U_PLANE].i_visible_pitch = p_pic->p[U_PLANE].i_pitch;
+            p_pic->p[U_PLANE].i_visible_pitch = p_vout->output.i_width / 2;
 
             p_pic->V_PIXELS = p_pic->p_sys->p_image->data
                                + p_pic->p_sys->p_image->offsets[1];
             p_pic->p[V_PLANE].i_lines = p_vout->output.i_height / 2;
             p_pic->p[V_PLANE].i_pitch = p_pic->p_sys->p_image->pitches[1];
             p_pic->p[V_PLANE].i_pixel_pitch = 1;
-            p_pic->p[V_PLANE].i_visible_pitch = p_pic->p[V_PLANE].i_pitch;
+            p_pic->p[V_PLANE].i_visible_pitch = p_vout->output.i_width / 2;
 
             p_pic->i_planes = 3;
             break;
@@ -1151,7 +1198,7 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
             /* XXX: this just looks so plain wrong... check it out ! */
             p_pic->p->i_pitch = p_pic->p_sys->p_image->pitches[0] / 4;
             p_pic->p->i_pixel_pitch = 4;
-            p_pic->p->i_visible_pitch = p_pic->p->i_pitch;
+            p_pic->p->i_visible_pitch = p_vout->output.i_width * 4;
 
             p_pic->i_planes = 1;
             break;
@@ -1164,7 +1211,7 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
             p_pic->p->i_lines = p_vout->output.i_height;
             p_pic->p->i_pitch = p_pic->p_sys->p_image->pitches[0];
             p_pic->p->i_pixel_pitch = 4;
-            p_pic->p->i_visible_pitch = p_pic->p->i_pitch;
+            p_pic->p->i_visible_pitch = p_vout->output.i_width * 4;
 
             p_pic->i_planes = 1;
             break;
@@ -1176,7 +1223,7 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
             p_pic->p->i_lines = p_vout->output.i_height;
             p_pic->p->i_pitch = p_pic->p_sys->p_image->pitches[0];
             p_pic->p->i_pixel_pitch = 2;
-            p_pic->p->i_visible_pitch = p_pic->p->i_pitch;
+            p_pic->p->i_visible_pitch = p_vout->output.i_width * 2;
 
             p_pic->i_planes = 1;
             break;
@@ -1188,7 +1235,7 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
             p_pic->p->i_lines = p_vout->output.i_height;
             p_pic->p->i_pitch = p_pic->p_sys->p_image->pitches[0];
             p_pic->p->i_pixel_pitch = 2;
-            p_pic->p->i_visible_pitch = p_pic->p->i_pitch;
+            p_pic->p->i_visible_pitch = p_vout->output.i_width * 2;
 
             p_pic->i_planes = 1;
             break;
@@ -1425,10 +1472,13 @@ static void EnableXScreenSaver( vout_thread_t *p_vout )
     int dummy;
 #endif
 
-    XSetScreenSaver( p_vout->p_sys->p_display, p_vout->p_sys->i_ss_timeout,
-                     p_vout->p_sys->i_ss_interval,
-                     p_vout->p_sys->i_ss_blanking,
-                     p_vout->p_sys->i_ss_exposure );
+    if( p_vout->p_sys->i_ss_timeout )
+    {
+        XSetScreenSaver( p_vout->p_sys->p_display, p_vout->p_sys->i_ss_timeout,
+                         p_vout->p_sys->i_ss_interval,
+                         p_vout->p_sys->i_ss_blanking,
+                         p_vout->p_sys->i_ss_exposure );
+    }
 
     /* Restore DPMS settings */
 #ifdef DPMSINFO_IN_DPMS_H
@@ -1460,10 +1510,13 @@ static void DisableXScreenSaver( vout_thread_t *p_vout )
                      &p_vout->p_sys->i_ss_exposure );
 
     /* Disable screen saver */
-    XSetScreenSaver( p_vout->p_sys->p_display, 0,
-                     p_vout->p_sys->i_ss_interval,
-                     p_vout->p_sys->i_ss_blanking,
-                     p_vout->p_sys->i_ss_exposure );
+    if( p_vout->p_sys->i_ss_timeout )
+    {
+        XSetScreenSaver( p_vout->p_sys->p_display, 0,
+                         p_vout->p_sys->i_ss_interval,
+                         p_vout->p_sys->i_ss_blanking,
+                         p_vout->p_sys->i_ss_exposure );
+    }
 
     /* Disable DPMS */
 #ifdef DPMSINFO_IN_DPMS_H
@@ -1637,8 +1690,8 @@ static int XVideoGetPort( vout_thread_t *p_vout,
 
             /* Look for the first available port supporting this format */
             for( i_port = p_adaptor[i_adaptor].base_id;
-                 ( i_port < p_adaptor[i_adaptor].base_id
-                             + p_adaptor[i_adaptor].num_ports )
+                 ( i_port < (int)(p_adaptor[i_adaptor].base_id
+                                   + p_adaptor[i_adaptor].num_ports) )
                    && ( i_selected_port == -1 );
                  i_port++ )
             {
@@ -1858,12 +1911,13 @@ static int InitDisplay( vout_thread_t *p_vout )
             /* Under XFree4.0, the list contains pixmap formats available
              * through all video depths ; so we have to check against current
              * depth. */
-            if( p_formats->depth == p_vout->p_sys->i_screen_depth )
+            if( p_formats->depth == (int)p_vout->p_sys->i_screen_depth )
             {
                 if( p_formats->bits_per_pixel / 8
-                        > p_vout->p_sys->i_bytes_per_pixel )
+                        > (int)p_vout->p_sys->i_bytes_per_pixel )
                 {
-                    p_vout->p_sys->i_bytes_per_pixel = p_formats->bits_per_pixel / 8;
+                    p_vout->p_sys->i_bytes_per_pixel =
+                                               p_formats->bits_per_pixel / 8;
                 }
             }
         }
@@ -2027,7 +2081,8 @@ static IMAGE_TYPE * CreateImage( vout_thread_t *p_vout,
  * anything, but could later send information on which colors it was unable
  * to set.
  *****************************************************************************/
-static void SetPalette( vout_thread_t *p_vout, u16 *red, u16 *green, u16 *blue )
+static void SetPalette( vout_thread_t *p_vout,
+                        uint16_t *red, uint16_t *green, uint16_t *blue )
 {
     int i;
     XColor p_colors[255];