]> git.sesse.net Git - vlc/commitdiff
* ./modules/video_output/directx/events.c: start the colorkey search at 10,
authorSam Hocevar <sam@videolan.org>
Fri, 25 Oct 2002 18:17:59 +0000 (18:17 +0000)
committerSam Hocevar <sam@videolan.org>
Fri, 25 Oct 2002 18:17:59 +0000 (18:17 +0000)
    not 5, to avoid using a color used by another application.
  * ./modules/video_output/directx/events.c: support for drawing in a parent
    window instead of creating our own; still a bit flakey.

  * ./mozilla/vlcshell.cpp: we can now compile the Mozilla plugin so that it
    does not call libvlc (for testing purposes).

modules/video_output/directx/directx.c
modules/video_output/directx/events.c
modules/video_output/directx/vout.h
mozilla/.cvsignore
mozilla/vlcplugin.h
mozilla/vlcshell.cpp

index 089bbc7fb3695766c3a23f419f847aeac8a19833..2b7cd4aae73b39cd118836014551027a49b6acd5 100644 (file)
@@ -2,7 +2,7 @@
  * vout.c: Windows DirectX video output display method
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: directx.c,v 1.4 2002/10/22 21:10:28 sam Exp $
+ * $Id: directx.c,v 1.5 2002/10/25 18:17:59 sam Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -98,11 +98,16 @@ static int  DirectXGetSurfaceDesc ( picture_t *p_pic );
     "isn't recommended as usually using video memory allows to benefit from " \
     "more hardware acceleration (like rescaling or YUV->RGB conversions). " \
     "This option doesn't have any effect when using overlays." )
+#define WINDOW_TEXT N_("specify an existing window")
+#define WINDOW_LONGTEXT N_( \
+    "Specify a window to use instead of opening a new one. This option is " \
+    "DANGEROUS, use with care." )
 
 vlc_module_begin();
     add_category_hint( N_("Video"), NULL );
     add_bool( "directx-hw-yuv", 1, NULL, HW_YUV_TEXT, HW_YUV_LONGTEXT );
     add_bool( "directx-use-sysmem", 0, NULL, SYSMEM_TEXT, SYSMEM_LONGTEXT );
+    add_integer( "directx-window", 0, NULL, WINDOW_TEXT, WINDOW_LONGTEXT );
     set_description( _("DirectX video module") );
     set_capability( "video output", 100 );
     add_shortcut( "directx" );
@@ -131,7 +136,7 @@ static int OpenVideo( vlc_object_t *p_this )
     if( p_vout->p_sys == NULL )
     {
         msg_Err( p_vout, "out of memory" );
-        return 1;
+        return VLC_ENOMEM;
     }
 
     /* Initialisations */
@@ -147,6 +152,7 @@ static int OpenVideo( vlc_object_t *p_this )
     p_vout->p_sys->p_clipper = NULL;
     p_vout->p_sys->hbrush = NULL;
     p_vout->p_sys->hwnd = NULL;
+    p_vout->p_sys->hparent = NULL;
     p_vout->p_sys->i_changes = 0;
     p_vout->p_sys->b_caps_overlay_clipping = 0;
     SetRectEmpty( &p_vout->p_sys->rect_display );
@@ -206,12 +212,11 @@ static int OpenVideo( vlc_object_t *p_this )
         goto error;
     }
 
-    return 0;
+    return VLC_SUCCESS;
 
  error:
     CloseVideo( VLC_OBJECT(p_vout) );
-    return 1;
-
+    return VLC_EGENERIC;
 }
 
 /*****************************************************************************
@@ -282,7 +287,9 @@ static int Init( vout_thread_t *p_vout )
     }
 
     /* Change the window title bar text */
-    if( p_vout->p_sys->b_using_overlay )
+    if( p_vout->p_sys->hparent )
+        ; /* Do nothing */
+    else if( p_vout->p_sys->b_using_overlay )
         SetWindowText( p_vout->p_sys->hwnd,
                        VOUT_TITLE " (hardware YUV overlay DirectX output)" );
     else if( p_vout->p_sys->b_hw_yuv )
@@ -291,7 +298,7 @@ static int Init( vout_thread_t *p_vout )
     else SetWindowText( p_vout->p_sys->hwnd,
                         VOUT_TITLE " (software RGB DirectX output)" );
 
-    return 0;
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -325,12 +332,14 @@ static void CloseVideo( vlc_object_t *p_this )
         vlc_object_detach( p_vout->p_sys->p_event );
 
         /* Kill DirectXEventThread */
-        p_vout->p_sys->p_event->b_die = 1;
+        p_vout->p_sys->p_event->b_die = VLC_TRUE;
 
         /* we need to be sure DirectXEventThread won't stay stuck in
          * GetMessage, so we send a fake message */
         if( p_vout->p_sys->hwnd )
+        {
             PostMessage( p_vout->p_sys->hwnd, WM_NULL, 0, 0);
+        }
 
         vlc_thread_join( p_vout->p_sys->p_event );
         vlc_object_destroy( p_vout->p_sys->p_event );
@@ -353,6 +362,13 @@ static int Manage( vout_thread_t *p_vout )
 {
     WINDOWPLACEMENT window_placement;
 
+    /* If we do not control our window, we check for geometry changes
+     * ourselves because the parent might not send us its events. */
+    if( p_vout->p_sys->hparent )
+    {
+        DirectXUpdateRects( p_vout, VLC_FALSE );
+    }
+
     /* We used to call the Win32 PeekMessage function here to read the window
      * messages. But since window can stay blocked into this function for a
      * long time (for example when you move your window on the screen), I
@@ -362,9 +378,9 @@ static int Manage( vout_thread_t *p_vout )
      * Scale Change 
      */
     if( p_vout->i_changes & VOUT_SCALE_CHANGE
-        || p_vout->p_sys->i_changes & VOUT_SCALE_CHANGE)
+         || p_vout->p_sys->i_changes & VOUT_SCALE_CHANGE )
     {
-        msg_Dbg( p_vout, "Scale Change" );
+        msg_Dbg( p_vout, "scale change" );
         if( !p_vout->p_sys->b_using_overlay )
             InvalidateRect( p_vout->p_sys->hwnd, NULL, TRUE );
         else
@@ -379,7 +395,7 @@ static int Manage( vout_thread_t *p_vout )
     if( p_vout->i_changes & VOUT_SIZE_CHANGE
         || p_vout->p_sys->i_changes & VOUT_SIZE_CHANGE )
     {
-        msg_Dbg( p_vout, "Size Change" );
+        msg_Dbg( p_vout, "size change" );
         if( !p_vout->p_sys->b_using_overlay )
             InvalidateRect( p_vout->p_sys->hwnd, NULL, TRUE );
         else
@@ -429,15 +445,20 @@ static int Manage( vout_thread_t *p_vout )
         ( (mdate() - p_vout->p_sys->i_lastmoved) > 5000000 ) )
     {
         /* Hide the mouse automatically */
-        p_vout->p_sys->b_cursor_hidden = 1;
-        PostMessage( p_vout->p_sys->hwnd, WM_VLC_HIDE_MOUSE, 0, 0 );
+        if( p_vout->p_sys->hwnd != p_vout->p_sys->hparent )
+        {
+            p_vout->p_sys->b_cursor_hidden = VLC_TRUE;
+            PostMessage( p_vout->p_sys->hwnd, WM_VLC_HIDE_MOUSE, 0, 0 );
+        }
     }
 
     /* Check if the event thread is still running */
     if( p_vout->p_sys->p_event->b_die )
-        return 1; /* exit */
+    {
+        return VLC_EGENERIC; /* exit */
+    }
 
-    return 0;
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -466,11 +487,11 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic )
         ddbltfx.dwDDFX = DDBLTFX_NOTEARING;
 
         /* Blit video surface to display */
-        dxresult = IDirectDrawSurface2_Blt(p_vout->p_sys->p_display,
-                                           &p_vout->p_sys->rect_dest_clipped,
-                                           p_pic->p_sys->p_surface,
-                                           &p_vout->p_sys->rect_src_clipped,
-                                           DDBLT_ASYNC, &ddbltfx );
+        dxresult = IDirectDrawSurface2_Blt( p_vout->p_sys->p_display,
+                                            &p_vout->p_sys->rect_dest_clipped,
+                                            p_pic->p_sys->p_surface,
+                                            &p_vout->p_sys->rect_src_clipped,
+                                            DDBLT_ASYNC, &ddbltfx );
         if ( dxresult == DDERR_SURFACELOST )
         {
             /* Our surface can be lost so be sure
@@ -478,7 +499,7 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic )
             IDirectDrawSurface2_Restore( p_vout->p_sys->p_display );
 
             /* Now that the surface has been restored try to display again */
-            dxresult = IDirectDrawSurface2_Blt(p_vout->p_sys->p_display,
+            dxresult = IDirectDrawSurface2_Blt( p_vout->p_sys->p_display,
                                            &p_vout->p_sys->rect_dest_clipped,
                                            p_pic->p_sys->p_surface,
                                            &p_vout->p_sys->rect_src_clipped,
@@ -487,17 +508,18 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic )
 
         if( dxresult != DD_OK )
         {
-            msg_Warn( p_vout, "could not Blit the surface" );
+            msg_Warn( p_vout, "could not blit surface (error %i)", dxresult );
             return;
         }
 
     }
     else /* using overlay */
     {
-
         /* Flip the overlay buffers if we are using back buffers */
         if( p_pic->p_sys->p_front_surface == p_pic->p_sys->p_surface )
+        {
             return;
+        }
 
         dxresult = IDirectDrawSurface2_Flip( p_pic->p_sys->p_front_surface,
                                              NULL, DDFLIP_WAIT );
@@ -515,16 +537,18 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic )
         }
 
         if( dxresult != DD_OK )
-            msg_Warn( p_vout, "could not flip overlay surface" );
+        {
+            msg_Warn( p_vout, "could not flip overlay (error %i)", dxresult );
+        }
 
-        if( !DirectXGetSurfaceDesc( p_pic ) )
+        if( DirectXGetSurfaceDesc( p_pic ) )
         {
             /* AAARRGG */
             msg_Err( p_vout, "cannot get surface desc" );
             return;
         }
 
-        if( !UpdatePictureStruct( p_vout, p_pic, p_vout->output.i_chroma ) )
+        if( UpdatePictureStruct( p_vout, p_pic, p_vout->output.i_chroma ) )
         {
             /* AAARRGG */
             msg_Err( p_vout, "invalid pic chroma" );
@@ -534,7 +558,6 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic )
         /* set currently displayed pic */
         p_vout->p_sys->p_current_surface = p_pic->p_sys->p_front_surface;
     }
-
 }
 
 
@@ -602,7 +625,7 @@ static int DirectXInitDDraw( vout_thread_t *p_vout )
     DirectXGetDDrawCaps( p_vout );
 
     msg_Dbg( p_vout, "End DirectXInitDDraw" );
-    return 0;
+    return VLC_SUCCESS;
 
  error:
     if( p_vout->p_sys->p_ddobject )
@@ -611,7 +634,7 @@ static int DirectXInitDDraw( vout_thread_t *p_vout )
         FreeLibrary( p_vout->p_sys->hddraw_dll );
     p_vout->p_sys->hddraw_dll = NULL;
     p_vout->p_sys->p_ddobject = NULL;
-    return 1;
+    return VLC_EGENERIC;
 }
 
 /*****************************************************************************
@@ -641,8 +664,8 @@ static int DirectXCreateDisplay( vout_thread_t *p_vout )
                                            &p_display, NULL );
     if( dxresult != DD_OK )
     {
-        msg_Err( p_vout, "cannot get direct draw primary surface" );
-        return 1;
+        msg_Err( p_vout, "cannot get primary surface (error %i)", dxresult );
+        return VLC_EGENERIC;
     }
 
     dxresult = IDirectDrawSurface_QueryInterface( p_display,
@@ -652,8 +675,9 @@ static int DirectXCreateDisplay( vout_thread_t *p_vout )
     IDirectDrawSurface_Release( p_display );
     if ( dxresult != DD_OK )
     {
-        msg_Err( p_vout, "cannot get IDirectDrawSurface2 interface" );
-        return 1;
+        msg_Err( p_vout, "cannot query IDirectDrawSurface2 interface "
+                         "(error %i)", dxresult );
+        return VLC_EGENERIC;
     }
 
     /* The clipper will be used only in non-overlay mode */
@@ -667,13 +691,16 @@ static int DirectXCreateDisplay( vout_thread_t *p_vout )
     dxresult = IDirectDrawSurface2_GetPixelFormat( p_vout->p_sys->p_display,
                                                    &pixel_format );
     if( dxresult != DD_OK )
-        msg_Warn( p_vout, "DirectXUpdateOverlay GetPixelFormat failed" );
+    {
+        msg_Warn( p_vout, "DirectXUpdateOverlay GetPixelFormat failed "
+                          "(error %i)", dxresult );
+    }
     p_vout->p_sys->i_colorkey = (DWORD)((( p_vout->p_sys->i_rgb_colorkey
                                            * pixel_format.dwRBitMask) / 255)
-                                        & pixel_format.dwRBitMask);
+                                        & pixel_format.dwRBitMask );
 #endif
 
-    return 0;
+    return VLC_SUCCESS;
 }
 
 
@@ -696,17 +723,17 @@ static int DirectXCreateClipper( vout_thread_t *p_vout )
                                            &p_vout->p_sys->p_clipper, NULL );
     if( dxresult != DD_OK )
     {
-        msg_Warn( p_vout, "DirectXCreateClipper cannot create clipper" );
+        msg_Warn( p_vout, "cannot create clipper (error %i)", dxresult );
         goto error;
     }
 
-    /* associate the clipper to the window */
+    /* Associate the clipper to the window */
     dxresult = IDirectDrawClipper_SetHWnd(p_vout->p_sys->p_clipper, 0,
                                           p_vout->p_sys->hwnd);
     if( dxresult != DD_OK )
     {
-        msg_Warn( p_vout,
-                  "DirectXCreateClipper cannot attach clipper to window" );
+        msg_Warn( p_vout, "cannot attach clipper to window (error %i)",
+                          dxresult );
         goto error;
     }
 
@@ -715,19 +742,20 @@ static int DirectXCreateClipper( vout_thread_t *p_vout )
                                              p_vout->p_sys->p_clipper);
     if( dxresult != DD_OK )
     {
-        msg_Warn( p_vout,
-                  "DirectXCreateClipper cannot attach clipper to surface" );
+        msg_Warn( p_vout, "cannot attach clipper to surface (error %i)",
+                          dxresult );
         goto error;
     }    
 
-    return 0;
+    return VLC_SUCCESS;
 
  error:
     if( p_vout->p_sys->p_clipper )
+    {
         IDirectDrawClipper_Release( p_vout->p_sys->p_clipper );
+    }
     p_vout->p_sys->p_clipper = NULL;
-    return 1;
-
+    return VLC_EGENERIC;
 }
 
 /*****************************************************************************
@@ -784,7 +812,7 @@ static int DirectXCreateSurface( vout_thread_t *p_vout,
         if( dxresult != DD_OK )
         {
             *pp_surface_final = NULL;
-            return 0;
+            return VLC_EGENERIC;
         }
     }
 
@@ -825,7 +853,7 @@ static int DirectXCreateSurface( vout_thread_t *p_vout,
         if( dxresult != DD_OK )
         {
             *pp_surface_final = NULL;
-            return 0;
+            return VLC_EGENERIC;
         }
     }
 
@@ -836,12 +864,13 @@ static int DirectXCreateSurface( vout_thread_t *p_vout,
     IDirectDrawSurface_Release( p_surface );    /* Release the old interface */
     if ( dxresult != DD_OK )
     {
-        msg_Err( p_vout, "cannot get IDirectDrawSurface2 interface" );
+        msg_Err( p_vout, "cannot query IDirectDrawSurface2 interface "
+                         "(error %i)", dxresult );
         *pp_surface_final = NULL;
-        return 0;
+        return VLC_EGENERIC;
     }
 
-    return 1;
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -958,7 +987,7 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
                           int i_num_pics )
 {
     int i;
-    vlc_bool_t b_result_ok;
+    int i_ret = VLC_SUCCESS;
     LPDIRECTDRAWSURFACE2 p_surface;
 
     msg_Dbg( p_vout, "NewPictureVec" );
@@ -977,19 +1006,21 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
          * (you don't have to wait for the vsync) and provides for a very nice
          * video quality (no tearing). */
 
-        b_result_ok = DirectXCreateSurface( p_vout, &p_surface,
-                                            p_vout->output.i_chroma,
-                                            p_vout->p_sys->b_using_overlay,
-                                            2 /* number of backbuffers */ );
+        i_ret = DirectXCreateSurface( p_vout, &p_surface,
+                                      p_vout->output.i_chroma,
+                                      p_vout->p_sys->b_using_overlay,
+                                      2 /* number of backbuffers */ );
 
-        if( !b_result_ok )
+        if( i_ret != VLC_SUCCESS )
+        {
             /* Try to reduce the number of backbuffers */
-            b_result_ok = DirectXCreateSurface( p_vout, &p_surface,
-                                                p_vout->output.i_chroma,
-                                                p_vout->p_sys->b_using_overlay,
-                                                0 /* number of backbuffers */);
+            i_ret = DirectXCreateSurface( p_vout, &p_surface,
+                                          p_vout->output.i_chroma,
+                                          p_vout->p_sys->b_using_overlay,
+                                          0 /* number of backbuffers */ );
+        }
 
-        if( b_result_ok )
+        if( i_ret == VLC_SUCCESS )
         {
             DDSCAPS dds_caps;
             picture_t front_pic;
@@ -1001,7 +1032,7 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
             if( p_pic[0].p_sys == NULL )
             {
                 DirectXCloseSurface( p_vout, p_surface );
-                return -1;
+                return VLC_ENOMEM;
             }
 
             /* set front buffer */
@@ -1023,10 +1054,10 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
             p_vout->p_sys->p_current_surface = front_pic.p_sys->p_surface =
                 p_pic[0].p_sys->p_front_surface;
 
-            /* reset the front buffer memory */
-            if( DirectXGetSurfaceDesc( &front_pic ) &&
-                UpdatePictureStruct( p_vout, &front_pic,
-                                     p_vout->output.i_chroma ) )
+            /* Reset the front buffer memory */
+            if( !DirectXGetSurfaceDesc( &front_pic ) &&
+                !UpdatePictureStruct( p_vout, &front_pic,
+                                      p_vout->output.i_chroma ) )
             {
                 int i,j;
                 for( i = 0; i < front_pic.i_planes; i++ )
@@ -1050,14 +1081,15 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
      * want to display it */
     if( !p_vout->p_sys->b_using_overlay )
     {
-
         if( p_vout->p_sys->b_hw_yuv )
-            b_result_ok = DirectXCreateSurface( p_vout, &p_surface,
-                                                p_vout->output.i_chroma,
-                                                p_vout->p_sys->b_using_overlay,
-                                                0 /* no back buffers */ );
+        {
+            i_ret = DirectXCreateSurface( p_vout, &p_surface,
+                                          p_vout->output.i_chroma,
+                                          p_vout->p_sys->b_using_overlay,
+                                          0 /* no back buffers */ );
+        }
 
-        if( !p_vout->p_sys->b_hw_yuv || !b_result_ok )
+        if( i_ret || !p_vout->p_sys->b_hw_yuv )
         {
             /* Our last choice is to use a plain RGB surface */
             DDPIXELFORMAT ddpfPixelFormat;
@@ -1087,7 +1119,7 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
                     break;
                 default:
                     msg_Err( p_vout, "unknown screen depth" );
-                    return 0;
+                    return VLC_EGENERIC;
                 }
                 p_vout->output.i_rmask = ddpfPixelFormat.dwRBitMask;
                 p_vout->output.i_gmask = ddpfPixelFormat.dwGBitMask;
@@ -1096,20 +1128,20 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
 
             p_vout->p_sys->b_hw_yuv = 0;
 
-            b_result_ok = DirectXCreateSurface( p_vout, &p_surface,
-                                                p_vout->output.i_chroma,
-                                                p_vout->p_sys->b_using_overlay,
-                                                0 /* no back buffers */ );
+            i_ret = DirectXCreateSurface( p_vout, &p_surface,
+                                          p_vout->output.i_chroma,
+                                          p_vout->p_sys->b_using_overlay,
+                                          0 /* no back buffers */ );
         }
 
-        if( b_result_ok )
+        if( i_ret == VLC_SUCCESS )
         {
             /* Allocate internal structure */
             p_pic[0].p_sys = malloc( sizeof( picture_sys_t ) );
             if( p_pic[0].p_sys == NULL )
             {
                 DirectXCloseSurface( p_vout, p_surface );
-                return -1;
+                return VLC_ENOMEM;
             }
             p_pic[0].p_sys->p_surface = p_pic[0].p_sys->p_front_surface
                 = p_surface;
@@ -1129,28 +1161,27 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
         p_pic[i].i_type   = DIRECT_PICTURE;
         PP_OUTPUTPICTURE[i] = &p_pic[i];
 
-        if( !DirectXGetSurfaceDesc( &p_pic[i] ) )
+        if( DirectXGetSurfaceDesc( &p_pic[i] ) )
         {
             /* AAARRGG */
             FreePictureVec( p_vout, p_pic, I_OUTPUTPICTURES );
             I_OUTPUTPICTURES = 0;
-            return -1;
+            return VLC_EGENERIC;
         }
 
-        if( !UpdatePictureStruct(p_vout, &p_pic[i], p_vout->output.i_chroma) )
+        if( UpdatePictureStruct(p_vout, &p_pic[i], p_vout->output.i_chroma) )
         {
-
             /* Unknown chroma, tell the guy to get lost */
             msg_Err( p_vout, "never heard of chroma 0x%.8x (%4.4s)",
                      p_vout->output.i_chroma, (char*)&p_vout->output.i_chroma );
             FreePictureVec( p_vout, p_pic, I_OUTPUTPICTURES );
             I_OUTPUTPICTURES = 0;
-            return -1;
+            return VLC_EGENERIC;
         }
     }
 
     msg_Dbg( p_vout, "End NewPictureVec");
-    return 0;
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -1182,7 +1213,6 @@ static void FreePictureVec( vout_thread_t *p_vout, picture_t *p_pic,
 static int UpdatePictureStruct( vout_thread_t *p_vout, picture_t *p_pic,
                                 int i_chroma )
 {
-
     switch( p_vout->output.i_chroma )
     {
         case VLC_FOURCC('R','G','B','2'):
@@ -1207,7 +1237,7 @@ static int UpdatePictureStruct( vout_thread_t *p_vout, picture_t *p_pic,
                     p_pic->p->i_pixel_pitch = 4;
                     break;
                 default:
-                    return -1;
+                    return VLC_EGENERIC;
             }
             p_pic->p->i_visible_pitch = p_vout->output.i_width *
               p_pic->p->i_pixel_pitch;
@@ -1284,11 +1314,10 @@ static int UpdatePictureStruct( vout_thread_t *p_vout, picture_t *p_pic,
 
         default:
             /* Not supported */
-            return 0;
-
+            return VLC_EGENERIC;
     }
 
-    return 1;
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -1374,11 +1403,11 @@ static int DirectXGetSurfaceDesc( picture_t *p_pic )
     if( dxresult != DD_OK )
     {
 //X        msg_Err( p_vout, "DirectXGetSurfaceDesc cannot lock surface" );
-        return 0;
+        return VLC_EGENERIC;
     }
 
     /* Unlock the Surface */
     dxresult = IDirectDrawSurface2_Unlock( p_pic->p_sys->p_surface, NULL );
 
-    return 1;
+    return VLC_SUCCESS;
 }
index 712e73d087321957c85c501711f698012c3ce765..7f5dc56835fcc2679f62e1eda99fcca76fdcd8c1 100644 (file)
@@ -2,7 +2,7 @@
  * events.c: Windows DirectX video output events handler
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: events.c,v 1.5 2002/10/17 17:30:10 ipkiss Exp $
+ * $Id: events.c,v 1.6 2002/10/25 18:17:59 sam Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -49,7 +49,6 @@
  *****************************************************************************/
 static int  DirectXCreateWindow( vout_thread_t *p_vout );
 static void DirectXCloseWindow ( vout_thread_t *p_vout );
-static void DirectXUpdateRects( vout_thread_t *p_vout );
 static long FAR PASCAL DirectXEventProc ( HWND hwnd, UINT message,
                                           WPARAM wParam, LPARAM lParam );
 
@@ -72,11 +71,11 @@ void DirectXEventThread( event_thread_t *p_event )
 
     /* Create a window for the video */
     /* Creating a window under Windows also initializes the thread's event
-     * message qeue */
+     * message queue */
     if( DirectXCreateWindow( p_event->p_vout ) )
     {
         msg_Err( p_event, "out of memory" );
-        p_event->b_dead = 1;
+        p_event->b_dead = VLC_TRUE;
     }
 
     /* signal the creation of the window */
@@ -164,7 +163,7 @@ void DirectXEventThread( event_thread_t *p_event )
             {
             case VK_ESCAPE:
                 /* exit application */
-                p_event->p_vlc->b_die = 1;
+                p_event->p_vlc->b_die = VLC_TRUE;
                 break;
 
             case VK_F1: network_ChannelJoin( p_event, 1 ); break;
@@ -189,7 +188,7 @@ void DirectXEventThread( event_thread_t *p_event )
             case 'q':
             case 'Q':
                 /* exit application */
-                p_event->p_vlc->b_die = 1;
+                p_event->p_vlc->b_die = VLC_TRUE;
                 break;
 
             case 'f':                            /* switch to fullscreen */
@@ -241,7 +240,7 @@ void DirectXEventThread( event_thread_t *p_event )
         p_event->p_vout->p_sys->hwnd = NULL; /* Window already destroyed */
     }
 
-    msg_Dbg( p_event, "DirectXEventThread Terminating" );
+    msg_Dbg( p_event, "DirectXEventThread terminating" );
 
     /* clear the changes formerly signaled */
     p_event->p_vout->p_sys->i_changes = 0;
@@ -262,17 +261,14 @@ void DirectXEventThread( event_thread_t *p_event )
 static int DirectXCreateWindow( vout_thread_t *p_vout )
 {
     HINSTANCE  hInstance;
-    WNDCLASSEX wc;                                /* window class components */
-    RECT       rect_window;
-    COLORREF   colorkey; 
+    COLORREF   colorkey;
     HDC        hdc;
     HMENU      hMenu;
-    HICON      vlc_icon = NULL;
-    char       vlc_path[MAX_PATH+1];
+    RECT       rect_window;
 
     msg_Dbg( p_vout, "DirectXCreateWindow" );
 
-    /* get this module's instance */
+    /* Get this module's instance */
     hInstance = GetModuleHandle(NULL);
 
     /* Create a BRUSH that will be used by Windows to paint the window
@@ -288,14 +284,16 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
      * comes from the potential dithering (depends on the display depth)
      * because we need to know the real RGB value of the chosen colorkey */
     hdc = GetDC( NULL );
-    for( colorkey = 5; colorkey < 0xFF /*all shades of red*/; colorkey++ )
+    for( colorkey = 0x0a; colorkey < 0xff /* all shades of red */; colorkey++ )
     {
         if( colorkey == GetNearestColor( hdc, colorkey ) )
-          break;
+        {
+            break;
+        }
     }
     msg_Dbg( p_vout, "background color: %i", colorkey );
 
-    /* create the actual brush */  
+    /* Create the actual brush */
     p_vout->p_sys->hbrush = CreateSolidBrush(colorkey);
     p_vout->p_sys->i_rgb_colorkey = (int)colorkey;
 
@@ -310,66 +308,98 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
 
     ReleaseDC( NULL, hdc );
 
-    /* Get the Icon from the main app */
-    vlc_icon = NULL;
-    if( GetModuleFileName( NULL, vlc_path, MAX_PATH ) )
+    /* If an external window was specified, we'll draw in it. */
+    p_vout->p_sys->hparent = p_vout->p_sys->hwnd =
+                (void*)(ptrdiff_t)config_GetInt( p_vout, "directx-window" );
+
+    if( p_vout->p_sys->hparent )
     {
-        vlc_icon = ExtractIcon( hInstance, vlc_path, 0 );
+        msg_Dbg( p_vout, "using external window %p\n", p_vout->p_sys->hwnd );
+
+        /* Set stuff in the window that we can not put directly in
+         * a class (see below). */
+        SetClassLong( p_vout->p_sys->hwnd,
+                      GCL_STYLE, CS_DBLCLKS );
+        SetClassLong( p_vout->p_sys->hwnd,
+                      GCL_HBRBACKGROUND, (LONG)p_vout->p_sys->hbrush );
+        SetClassLong( p_vout->p_sys->hwnd,
+                      GCL_HCURSOR, (LONG)LoadCursor(NULL, IDC_ARROW) );
+        p_vout->p_sys->pf_wndproc =
+               (WNDPROC)SetWindowLong( p_vout->p_sys->hwnd,
+                                       GWL_WNDPROC, (LONG)DirectXEventProc );
+
+        /* Blam! Erase everything that might have been there. */
+        RedrawWindow( p_vout->p_sys->hwnd, NULL, NULL,
+                      RDW_INVALIDATE | RDW_ERASE );
     }
-
-
-    /* fill in the window class structure */
-    wc.cbSize        = sizeof(WNDCLASSEX);
-    wc.style         = CS_DBLCLKS;                       /* style: dbl click */
-    wc.lpfnWndProc   = (WNDPROC)DirectXEventProc;           /* event handler */
-    wc.cbClsExtra    = 0;                             /* no extra class data */
-    wc.cbWndExtra    = 0;                            /* no extra window data */
-    wc.hInstance     = hInstance;                                /* instance */
-    wc.hIcon         = vlc_icon;                        /* load the vlc icon */
-    wc.hCursor       = LoadCursor(NULL, IDC_ARROW); /* load a default cursor */
-    wc.hbrBackground = p_vout->p_sys->hbrush;            /* background color */
-    wc.lpszMenuName  = NULL;                                      /* no menu */
-    wc.lpszClassName = "VLC DirectX";                 /* use a special class */
-    wc.hIconSm       = vlc_icon;                        /* load the vlc icon */
-
-    /* register the window class */
-    if (!RegisterClassEx(&wc))
+    else
     {
-        WNDCLASS wndclass;
+        WNDCLASSEX wc;                            /* window class components */
+        HICON      vlc_icon = NULL;
+        char       vlc_path[MAX_PATH+1];
 
-        /* free window background brush */
-        if( p_vout->p_sys->hbrush )
+        /* Get the Icon from the main app */
+        vlc_icon = NULL;
+        if( GetModuleFileName( NULL, vlc_path, MAX_PATH ) )
         {
-            DeleteObject( p_vout->p_sys->hbrush );
-            p_vout->p_sys->hbrush = NULL;
+            vlc_icon = ExtractIcon( hInstance, vlc_path, 0 );
         }
 
-        if( vlc_icon )
-            DestroyIcon( vlc_icon );
-
-        /* Check why it failed. If it's because one already exists then fine */
-        if( !GetClassInfo( hInstance, "VLC DirectX", &wndclass ) )
+        /* Fill in the window class structure */
+        wc.cbSize        = sizeof(WNDCLASSEX);
+        wc.style         = CS_DBLCLKS;                   /* style: dbl click */
+        wc.lpfnWndProc   = (WNDPROC)DirectXEventProc;       /* event handler */
+        wc.cbClsExtra    = 0;                         /* no extra class data */
+        wc.cbWndExtra    = 0;                        /* no extra window data */
+        wc.hInstance     = hInstance;                            /* instance */
+        wc.hIcon         = vlc_icon;                /* load the vlc big icon */
+        wc.hCursor       = LoadCursor(NULL, IDC_ARROW);    /* default cursor */
+        wc.hbrBackground = p_vout->p_sys->hbrush;        /* background color */
+        wc.lpszMenuName  = NULL;                                  /* no menu */
+        wc.lpszClassName = "VLC DirectX";             /* use a special class */
+        wc.hIconSm       = vlc_icon;              /* load the vlc small icon */
+
+        /* Register the window class */
+        if( !RegisterClassEx(&wc) )
         {
-            msg_Err( p_vout, "DirectXCreateWindow RegisterClass FAILED" );
-            return (1);
+            WNDCLASS wndclass;
+
+            /* Free window background brush */
+            if( p_vout->p_sys->hbrush )
+            {
+                DeleteObject( p_vout->p_sys->hbrush );
+                p_vout->p_sys->hbrush = NULL;
+            }
+
+            if( vlc_icon )
+            {
+                DestroyIcon( vlc_icon );
+            }
+
+            /* Check why it failed. If it's because one already exists
+             * then fine, otherwise return with an error. */
+            if( !GetClassInfo( hInstance, "VLC DirectX", &wndclass ) )
+            {
+                msg_Err( p_vout, "DirectXCreateWindow RegisterClass FAILED" );
+                return VLC_EGENERIC;
+            }
         }
-    }
 
-    /* when you create a window you give the dimensions you wish it to have.
-     * Unfortunatly these dimensions will include the borders and title bar.
-     * We use the following function to find out the size of the window
-     * corresponding to the useable surface we want */
-    rect_window.top    = 10;
-    rect_window.left   = 10;
-    rect_window.right  = rect_window.left + p_vout->p_sys->i_window_width;
-    rect_window.bottom = rect_window.top + p_vout->p_sys->i_window_height;
-    AdjustWindowRect( &rect_window, WS_OVERLAPPEDWINDOW|WS_SIZEBOX, 0 );
-
-    /* create the window */
-    p_vout->p_sys->hwnd = CreateWindow("VLC DirectX",/* name of window class */
+        /* When you create a window you give the dimensions you wish it to
+         * have. Unfortunatly these dimensions will include the borders and
+         * titlebar. We use the following function to find out the size of
+         * the window corresponding to the useable surface we want */
+        rect_window.top    = 10;
+        rect_window.left   = 10;
+        rect_window.right  = rect_window.left + p_vout->p_sys->i_window_width;
+        rect_window.bottom = rect_window.top + p_vout->p_sys->i_window_height;
+        AdjustWindowRect( &rect_window, WS_OVERLAPPEDWINDOW|WS_SIZEBOX, 0 );
+
+        /* Create the window */
+        p_vout->p_sys->hwnd =
+            CreateWindow( "VLC DirectX",             /* name of window class */
                     VOUT_TITLE " (DirectX Output)", /* window title bar text */
-                    WS_OVERLAPPEDWINDOW
-                    | WS_SIZEBOX,               /* window style */
+                    WS_OVERLAPPEDWINDOW | WS_SIZEBOX,        /* window style */
                     CW_USEDEFAULT,                   /* default X coordinate */
                     0,                               /* default Y coordinate */
                     rect_window.right - rect_window.left,    /* window width */
@@ -379,25 +409,28 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
                     hInstance,            /* handle of this program instance */
                     NULL);                        /* no additional arguments */
 
-    if (p_vout->p_sys->hwnd == NULL) {
-        msg_Warn( p_vout, "DirectXCreateWindow create window FAILED" );
-        return (1);
+        if( !p_vout->p_sys->hwnd )
+        {
+            msg_Warn( p_vout, "DirectXCreateWindow create window FAILED" );
+            return VLC_EGENERIC;
+        }
     }
 
-    /* store a p_vout pointer into the window local storage (for later use
+    /* Store a p_vout pointer into the window local storage (for later use
      * in DirectXEventProc).
      * We need to use SetWindowLongPtr when it is available in mingw */
     SetWindowLong( p_vout->p_sys->hwnd, GWL_USERDATA, (LONG)p_vout );
 
-    /* append a "Always On Top" entry in the system menu */
+    /* Append a "Always On Top" entry in the system menu */
     hMenu = GetSystemMenu( p_vout->p_sys->hwnd, FALSE );
     AppendMenu( hMenu, MF_SEPARATOR, 0, "" );
-    AppendMenu( hMenu, MF_STRING | MF_UNCHECKED, IDM_TOGGLE_ON_TOP, "Always on &Top");
+    AppendMenu( hMenu, MF_STRING | MF_UNCHECKED,
+                       IDM_TOGGLE_ON_TOP, "Always on &Top" );
 
-    /* now display the window */
-    ShowWindow(p_vout->p_sys->hwnd, SW_SHOW);
+    /* Now display the window */
+    ShowWindow( p_vout->p_sys->hwnd, SW_SHOW );
 
-    return ( 0 );
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -409,50 +442,77 @@ static void DirectXCloseWindow( vout_thread_t *p_vout )
 {
     msg_Dbg( p_vout, "DirectXCloseWindow" );
 
-    if( p_vout->p_sys->hwnd != NULL )
+    if( p_vout->p_sys->hwnd && !p_vout->p_sys->hparent )
     {
         DestroyWindow( p_vout->p_sys->hwnd );
-        p_vout->p_sys->hwnd = NULL;
     }
 
+    p_vout->p_sys->hwnd = NULL;
+
     /* We don't unregister the Window Class because it could lead to race
      * conditions and it will be done anyway by the system when the app will
      * exit */
 }
 
 /*****************************************************************************
- * DirectXUpdateRects: 
+ * DirectXUpdateRects: update clipping rectangles
  *****************************************************************************
- * This function is called when the window position and size is changed, and
+ * This function is called when the window position or size are changed, and
  * its job is to update the source and destination RECTs used to display the
  * picture.
  *****************************************************************************/
-static void DirectXUpdateRects( vout_thread_t *p_vout )
+void DirectXUpdateRects( vout_thread_t *p_vout, vlc_bool_t b_force )
 {
-    int i_width, i_height, i_x, i_y;
-
 #define rect_src p_vout->p_sys->rect_src
 #define rect_src_clipped p_vout->p_sys->rect_src_clipped
 #define rect_dest p_vout->p_sys->rect_dest
 #define rect_dest_clipped p_vout->p_sys->rect_dest_clipped
-#define rect_display p_vout->p_sys->rect_display
 
-    vout_PlacePicture( p_vout, p_vout->p_sys->i_window_width,
-                       p_vout->p_sys->i_window_height,
+    int i_width, i_height, i_x, i_y;
+
+    RECT  rect;
+    POINT point;
+
+    /* Retrieve the window size */
+    GetClientRect( p_vout->p_sys->hwnd, &rect );
+
+    /* Retrieve the window position */
+    point.x = point.y = 0;
+    ClientToScreen( p_vout->p_sys->hwnd, &point );
+
+    /* If nothing changed, we can return */
+    if( !b_force
+         && p_vout->p_sys->i_window_width == rect.right
+         && p_vout->p_sys->i_window_height == rect.bottom
+         && p_vout->p_sys->i_window_x == point.x
+         && p_vout->p_sys->i_window_y == point.y )
+    {
+        return;
+    }
+
+    /* Update the window position and size */
+    p_vout->p_sys->i_window_x = point.x;
+    p_vout->p_sys->i_window_y = point.y;
+    p_vout->p_sys->i_window_width = rect.right;
+    p_vout->p_sys->i_window_height = rect.bottom;
+
+    vout_PlacePicture( p_vout, rect.right, rect.bottom,
                        &i_x, &i_y, &i_width, &i_height );
 
     /* Destination image position and dimensions */
-    rect_dest.left = i_x + p_vout->p_sys->i_window_x;
-    rect_dest.top = i_y + p_vout->p_sys->i_window_y;
+    rect_dest.left = point.x + i_x;
     rect_dest.right = rect_dest.left + i_width;
+    rect_dest.top = point.y + i_y;
     rect_dest.bottom = rect_dest.top + i_height;
 
 
     /* UpdateOverlay directdraw function doesn't automatically clip to the
-     * display size so we need to do it otherwise it will fails */
+     * display size so we need to do it otherwise it will fail */
 
     /* Clip the destination window */
-    IntersectRect( &rect_dest_clipped, &rect_dest, &rect_display );
+    IntersectRect( &rect_dest_clipped,
+                   &rect_dest,
+                   &p_vout->p_sys->rect_display );
 
 #if 0
     msg_Dbg( p_vout, "DirectXUpdateRects image_dst_clipped coords:"
@@ -478,7 +538,7 @@ static void DirectXUpdateRects( vout_thread_t *p_vout )
     /* Clip the source image */
     rect_src_clipped.left = (rect_dest_clipped.left - rect_dest.left) *
       p_vout->render.i_width / (rect_dest.right - rect_dest.left);
-    rect_src_clipped.right = p_vout->render.i_width - 
+    rect_src_clipped.right = p_vout->render.i_width -
       (rect_dest.right - rect_dest_clipped.right) * p_vout->render.i_width /
       (rect_dest.right - rect_dest.left);
     rect_src_clipped.top = (rect_dest_clipped.top - rect_dest.top) *
@@ -494,11 +554,23 @@ static void DirectXUpdateRects( vout_thread_t *p_vout )
                      rect_src_clipped.right, rect_src_clipped.bottom );
 #endif
 
+    /* Signal the size change */
+    if( !p_vout->p_sys->p_event->b_die )
+    {
+        if( p_vout->p_sys->b_using_overlay )
+        {
+            DirectXUpdateOverlay( p_vout );
+        }
+        else
+        {
+            p_vout->p_sys->i_changes |= VOUT_SIZE_CHANGE;
+        }
+    }
+
 #undef rect_src
 #undef rect_src_clipped
 #undef rect_dest
 #undef rect_dest_clipped
-#undef rect_display
 }
 
 /*****************************************************************************
@@ -518,47 +590,25 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
     vout_thread_t *p_vout =
             (vout_thread_t *)GetWindowLong( hwnd, GWL_USERDATA );
 
+    /* Just in case the window wasn't properly initialized yet */
+    if( !p_vout )
+    {
+        return DefWindowProc( hwnd, message, wParam, lParam );
+    }
+
     switch( message )
     {
 
     case WM_WINDOWPOSCHANGED:
-        {
-        RECT     rect_window;
-        POINT    point_window;
-
-        /* update the window position */
-        point_window.x = 0;
-        point_window.y = 0;
-        ClientToScreen( hwnd, &point_window );
-        p_vout->p_sys->i_window_x = point_window.x;
-        p_vout->p_sys->i_window_y = point_window.y;
-
-        /* update the window size */
-        GetClientRect( hwnd, &rect_window );
-        p_vout->p_sys->i_window_width = rect_window.right;
-        p_vout->p_sys->i_window_height = rect_window.bottom;
-
-        DirectXUpdateRects( p_vout );
-        if( p_vout->p_sys->b_using_overlay &&
-            !p_vout->p_sys->p_event->b_die )
-            DirectXUpdateOverlay( p_vout );
-
-        /* signal the size change */
-        if( !p_vout->p_sys->b_using_overlay &&
-            !p_vout->p_sys->p_event->b_die )
-            p_vout->p_sys->i_changes |= VOUT_SIZE_CHANGE;
-
+        DirectXUpdateRects( p_vout, VLC_TRUE );
         return 0;
-        }
-        break;
 
     /* the user wants to close the window */
     case WM_CLOSE:
         msg_Dbg( p_vout, "WinProc WM_CLOSE" );
         /* exit application */
-        p_vout->p_vlc->b_die = 1;
+        p_vout->p_vlc->b_die = VLC_TRUE;
         return 0;
-        break;
 
     /* the window has been closed so shut down everything now */
     case WM_DESTROY:
@@ -566,7 +616,6 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
         /* just destroy the window */
         PostQuitMessage( 0 );
         return 0;
-        break;
 
     case WM_SYSCOMMAND:
         switch (wParam)
@@ -632,3 +681,4 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
 
     return DefWindowProc(hwnd, message, wParam, lParam);
 }
+
index 0dc675a6fe658058fa8c8f709f538942f6db88ce..7b97d4a15042de6f12d3dd1edc1757a0eab7a6c9 100644 (file)
@@ -2,7 +2,7 @@
  * vout.h: Windows DirectX video output header file
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vout.h,v 1.2 2002/10/01 20:43:35 ipkiss Exp $
+ * $Id: vout.h,v 1.3 2002/10/25 18:17:59 sam Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -46,7 +46,10 @@ struct vout_sys_t
     LPDIRECTDRAWCLIPPER  p_clipper;             /* clipper used for blitting */
     HINSTANCE            hddraw_dll;       /* handle of the opened ddraw dll */
     HBRUSH               hbrush;           /* window backgound brush (color) */
+
     HWND                 hwnd;                  /* Handle of the main window */
+    HWND                 hparent;             /* Handle of the parent window */
+    WNDPROC              pf_wndproc;             /* Window handling callback */
 
     vlc_bool_t   b_using_overlay;         /* Are we using an overlay surface */
     vlc_bool_t   b_use_sysmem;   /* Should we use system memory for surfaces */
@@ -99,12 +102,13 @@ struct picture_sys_t
 /*****************************************************************************
  * Prototypes from vout.c
  *****************************************************************************/
+void DirectXUpdateOverlay( vout_thread_t *p_vout );
 
 /*****************************************************************************
  * Prototypes from events.c
  *****************************************************************************/
 void DirectXEventThread ( event_thread_t *p_event );
-void DirectXUpdateOverlay( vout_thread_t *p_vout );
+void DirectXUpdateRects ( vout_thread_t *p_vout, vlc_bool_t b_force );
 
 /*****************************************************************************
  * Constants
index 99c40cdcb413b478b486005ab260365e4c19fdfc..2a098b94559112e2344d94cc94a5e5826badd15f 100644 (file)
@@ -1,3 +1,4 @@
+*.dll
 vlcintf.h
 vlcintf.xpt
 .deps
index 02546a5a8d09fa5dec132570866dc3b67dd5bb6f..e98292c069d804a0abe82ab92f8ef2b3cea5b732 100644 (file)
@@ -2,7 +2,7 @@
  * vlcplugin.h: a VideoLAN plugin for Mozilla
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: vlcplugin.h,v 1.6 2002/10/22 21:10:28 sam Exp $
+ * $Id: vlcplugin.h,v 1.7 2002/10/25 18:17:59 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -37,17 +37,20 @@ public:
     void     SetFileName( const char* );
 
     /* Window settings */
-    NPWindow* fWindow;
-    uint16 fMode;
+    NPWindow* p_npwin;
+    uint16    i_npmode;
+    uint32    i_width, i_height;
 
-#ifdef WIN32
+#ifdef XP_WIN
+    /* Windows data members */
+    HWND     p_hwnd;
+    WNDPROC  pf_wndproc;
+#endif
 
-#else
+#ifdef XP_UNIX
     /* UNIX data members */
-    Window window;
-    Display *display;
-    uint32 x, y;
-    uint32 width, height;
+    Window   window;
+    Display *p_display;
 #endif
 
     /* vlc data members */
index 8ec4e6a3d5cdf84a22cda7a5e6618d6a04e2ccf1..e14f97efe4d0536d96a2d5d5da94f3453633d8be 100644 (file)
@@ -2,7 +2,7 @@
  * vlcshell.c: a VideoLAN Client plugin for Mozilla
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: vlcshell.cpp,v 1.5 2002/10/22 21:10:28 sam Exp $
+ * $Id: vlcshell.cpp,v 1.6 2002/10/25 18:17:59 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
 /* Mozilla stuff */
 #include <npapi.h>
 
-#ifdef WIN32
+#ifdef XP_WIN
+    /* Windows stuff */
+#endif
 
-#else
+#ifdef XP_UNIX
     /* X11 stuff */
 #   include <X11/Xlib.h>
 #   include <X11/Intrinsic.h>
 #include "vlcpeer.h"
 #include "vlcplugin.h"
 
+/* XXX: disable VLC */
+#define USE_LIBVLC 1
+
+#if USE_LIBVLC
+#   define WINDOW_TEXT "(no picture)"
+#else
+#   define WINDOW_TEXT "(no libvlc)"
+#endif
+
 /*****************************************************************************
  * Unix-only declarations
 ******************************************************************************/
-#ifndef WIN32
+#ifdef XP_UNIX
+#   define VOUT_PLUGINS "xvideo,x11,dummy"
+#   define AOUT_PLUGINS "dsp,dummy"
+
 static void Redraw( Widget w, XtPointer closure, XEvent *event );
 #endif
 
 /*****************************************************************************
  * Windows-only declarations
  *****************************************************************************/
-#ifdef WIN32
+#ifdef XP_WIN
+#   define VOUT_PLUGINS "directx,dummy"
+#   define AOUT_PLUGINS "none" /* "directx,waveout,dummy" */
+
 HINSTANCE g_hDllInstance = NULL;
 
 BOOL WINAPI
@@ -63,17 +80,20 @@ DllMain( HINSTANCE  hinstDLL,                   // handle of DLL module
                     DWORD  fdwReason,       // reason for calling function
                     LPVOID  lpvReserved)
 {
-        switch (fdwReason) {
-                case DLL_PROCESS_ATTACH:
-                  g_hDllInstance = hinstDLL;
-                  break;
-                case DLL_THREAD_ATTACH:
-                case DLL_PROCESS_DETACH:
-                case DLL_THREAD_DETACH:
-                break;
-        }
-        return TRUE;
+    switch (fdwReason)
+    {
+        case DLL_PROCESS_ATTACH:
+            g_hDllInstance = hinstDLL;
+            break;
+        case DLL_THREAD_ATTACH:
+        case DLL_PROCESS_DETACH:
+        case DLL_THREAD_DETACH:
+            break;
+    }
+    return TRUE;
 }
+
+LRESULT CALLBACK Manage( HWND, UINT, WPARAM, LPARAM );
 #endif
 
 /******************************************************************************
@@ -96,7 +116,11 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value )
             return NPERR_NO_ERROR;
 
         case NPPVpluginDescriptionString:
+#if USE_LIBVLC
             snprintf( psz_desc, 1000-1, PLUGIN_DESCRIPTION, VLC_Version() );
+#else
+            snprintf( psz_desc, 1000-1, PLUGIN_DESCRIPTION, "(disabled)" );
+#endif
             psz_desc[1000-1] = 0;
             *((char **)value) = psz_desc;
             return NPERR_NO_ERROR;
@@ -160,15 +184,17 @@ void NPP_Shutdown( void )
 NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
                  char* argn[], char* argv[], NPSavedData* saved )
 {
+    int i;
+#if USE_LIBVLC
     vlc_value_t value;
     int i_ret;
-    int i;
 
     char *ppsz_foo[] =
     {
         "vlc"
         /*, "--plugin-path", "/home/sam/videolan/vlc_MAIN/plugins"*/
     };
+#endif
 
     if( instance == NULL )
     {
@@ -184,14 +210,22 @@ NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
 
     instance->pdata = p_plugin;
 
-    p_plugin->fMode = mode;
-    p_plugin->fWindow = NULL;
-#ifdef WIN32
+#ifdef XP_WIN
+    p_plugin->p_hwnd = NULL;
+    p_plugin->pf_wndproc = NULL;
+#endif
 
-#else
+#ifdef XP_UNIX
     p_plugin->window = 0;
+    p_plugin->p_display = NULL;
 #endif
 
+    p_plugin->p_npwin = NULL;
+    p_plugin->i_npmode = mode;
+    p_plugin->i_width = 0;
+    p_plugin->i_height = 0;
+
+#if USE_LIBVLC
     p_plugin->i_vlc = VLC_Create();
     if( p_plugin->i_vlc < 0 )
     {
@@ -213,21 +247,18 @@ NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
 
     value.psz_string = "dummy";
     VLC_Set( p_plugin->i_vlc, "conf::intf", value );
-#ifdef WIN32
-    value.psz_string = "directx,dummy";
-#else
-    value.psz_string = "xvideo,x11,dummy";
-#endif
+    value.psz_string = VOUT_PLUGINS;
     VLC_Set( p_plugin->i_vlc, "conf::vout", value );
-#ifdef WIN32
-    value.psz_string = "none";//"directx,waveout,dummy";
-#else
-    value.psz_string = "dsp,dummy";
-#endif
+    value.psz_string = AOUT_PLUGINS;
     VLC_Set( p_plugin->i_vlc, "conf::aout", value );
 
-    p_plugin->b_stream = 0;
-    p_plugin->b_autoplay = 0;
+#else
+    p_plugin->i_vlc = 1;
+
+#endif /* USE_LIBVLC */
+
+    p_plugin->b_stream = VLC_FALSE;
+    p_plugin->b_autoplay = VLC_FALSE;
     p_plugin->psz_target = NULL;
 
     for( i = 0; i < argc ; i++ )
@@ -243,6 +274,7 @@ NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
                 p_plugin->b_autoplay = 1;
             }
         }
+#if USE_LIBVLC
         else if( !strcmp( argn[i], "loop" ) )
         {
             if( !strcmp( argv[i], "yes" ) )
@@ -251,6 +283,7 @@ NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
                 VLC_Set( p_plugin->i_vlc, "conf::loop", value );
             }
         }
+#endif
     }
 
     if( p_plugin->psz_target )
@@ -274,8 +307,10 @@ NPError NPP_Destroy( NPP instance, NPSavedData** save )
     {
         if( p_plugin->i_vlc )
         {
+#if USE_LIBVLC
             VLC_Stop( p_plugin->i_vlc );
             VLC_Destroy( p_plugin->i_vlc );
+#endif
             p_plugin->i_vlc = 0;
         }
 
@@ -295,8 +330,6 @@ NPError NPP_Destroy( NPP instance, NPSavedData** save )
 
 NPError NPP_SetWindow( NPP instance, NPWindow* window )
 {
-    vlc_value_t value;
-
     if( instance == NULL )
     {
         return NPERR_INVALID_INSTANCE_ERROR;
@@ -305,13 +338,18 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
     VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
 
     /* Write the window ID for vlc */
-    //value.p_address = (void*)window->window;
-    //VLC_Set( p_plugin->i_vlc, "drawable", value );
+#if USE_LIBVLC
+    vlc_value_t value;
+
     /* FIXME: this cast sucks */
-    value.i_int = (int) (long long) (void *) window->window;
+    value.i_int = (int) (ptrdiff_t) (void *) window->window;
     VLC_Set( p_plugin->i_vlc, "conf::x11-drawable", value );
     VLC_Set( p_plugin->i_vlc, "conf::xvideo-drawable", value );
 
+    value.i_int = (int) (ptrdiff_t) (void *) window->window;
+    VLC_Set( p_plugin->i_vlc, "conf::directx-window", value );
+#endif
+
     /*
      * PLUGIN DEVELOPERS:
      *  Before setting window to point to the
@@ -320,26 +358,67 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
      *  size changes, etc.
      */
 
-#ifdef WIN32
+#ifdef XP_WIN
+    if( !window || !window->window )
+    {
+        /* Window was destroyed. Invalidate everything. */
+        if( p_plugin->p_npwin )
+        {
+            SetWindowLong( p_plugin->p_hwnd, GWL_WNDPROC,
+                           (LONG)p_plugin->pf_wndproc );
+            p_plugin->pf_wndproc = NULL;
+            p_plugin->p_hwnd = NULL;
+        }
 
-#else
-    Widget netscape_widget;
+        p_plugin->p_npwin = window;
+        return NPERR_NO_ERROR;
+    }
 
+    if( p_plugin->p_npwin )
+    {
+        if( p_plugin->p_hwnd == (HWND)window->window )
+        {
+            /* Same window, but something may have changed. First we
+             * update the plugin structure, then we redraw the window */
+            InvalidateRect( p_plugin->p_hwnd, NULL, TRUE );
+            p_plugin->i_width = window->width;
+            p_plugin->i_height = window->height;
+            p_plugin->p_npwin = window;
+            UpdateWindow( p_plugin->p_hwnd );
+            return NPERR_NO_ERROR;
+        }
+
+        /* Window has changed. Destroy the one we have, and go
+         * on as if it was a real initialization. */
+        SetWindowLong( p_plugin->p_hwnd, GWL_WNDPROC,
+                       (LONG)p_plugin->pf_wndproc );
+        p_plugin->pf_wndproc = NULL;
+        p_plugin->p_hwnd = NULL;
+    }
+
+    p_plugin->pf_wndproc = (WNDPROC)SetWindowLong( (HWND)window->window,
+                                                   GWL_WNDPROC, (LONG)Manage );
+    p_plugin->p_hwnd = (HWND)window->window;
+    SetProp( p_plugin->p_hwnd, "w00t", (HANDLE)p_plugin );
+    InvalidateRect( p_plugin->p_hwnd, NULL, TRUE );
+    UpdateWindow( p_plugin->p_hwnd );
+#endif
+
+#ifdef XP_UNIX
     p_plugin->window = (Window) window->window;
-    p_plugin->x = window->x;
-    p_plugin->y = window->y;
-    p_plugin->width = window->width;
-    p_plugin->height = window->height;
-    p_plugin->display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
-
-    netscape_widget = XtWindowToWidget(p_plugin->display, p_plugin->window);
-    XtAddEventHandler(netscape_widget, ExposureMask, FALSE, (XtEventHandler)Redraw, p_plugin);
-    Redraw(netscape_widget, (XtPointer)p_plugin, NULL);
+    p_plugin->p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
+
+    Widget w = XtWindowToWidget( p_plugin->p_display, p_plugin->window );
+    XtAddEventHandler( w, ExposureMask, FALSE,
+                       (XtEventHandler)Redraw, p_plugin );
+    Redraw( w, (XtPointer)p_plugin, NULL );
 #endif
 
-    p_plugin->fWindow = window;
+    p_plugin->p_npwin = window;
+
+    p_plugin->i_width = window->width;
+    p_plugin->i_height = window->height;
 
-#if 1
     if( !p_plugin->b_stream )
     {
         int i_mode = PLAYLIST_APPEND;
@@ -351,12 +430,13 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
 
         if( p_plugin->psz_target )
         {
+#if USE_LIBVLC
             VLC_AddTarget( p_plugin->i_vlc, p_plugin->psz_target,
                            i_mode, PLAYLIST_END );
-            p_plugin->b_stream = 1;
+#endif
+            p_plugin->b_stream = VLC_TRUE;
         }
     }
-#endif
 
     return NPERR_NO_ERROR;
 }
@@ -379,10 +459,10 @@ NPError NPP_NewStream( NPP instance, NPMIMEType type, NPStream *stream,
     *stype = NP_ASFILE;
 
 #if 0
-    if( p_plugin->b_stream == 0 )
+    if( !p_plugin->b_stream )
     {
         p_plugin->psz_target = strdup( stream->url );
-        p_plugin->b_stream = 1;
+        p_plugin->b_stream = VLC_TRUE;
     }
 #endif
 
@@ -447,22 +527,15 @@ void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname )
         return;
     }
 
+    fprintf(stderr, "NPP_StreamAsFile %s\n", fname);
+
+#if USE_LIBVLC
     VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
 
-    fprintf(stderr, "NPP_StreamAsFile\n");
     VLC_AddTarget( p_plugin->i_vlc, fname,
                    PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
-}
-
-#if 0
-void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname )
-{
-    fprintf(stderr,"filename : %s\n", fname);
-    ((VlcPlugin*) instance->pdata)->SetFileName(fname);
-
-    fprintf(stderr,"SetFileNeme ok. \n");
-}
 #endif
+}
 
 
 void NPP_URLNotify( NPP instance, const char* url,
@@ -543,31 +616,66 @@ void NPP_Print( NPP instance, NPPrint* printInfo )
     }
 }
 
+/******************************************************************************
+ * Windows-only methods
+ *****************************************************************************/
+#ifdef XP_WIN
+LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar )
+{
+    VlcPlugin* p_plugin = (VlcPlugin*) GetProp( p_hwnd, "w00t" );
+
+    switch( i_msg )
+    {
+#if !USE_LIBVLC
+        case WM_PAINT:
+        {
+            PAINTSTRUCT paintstruct;
+            HDC hdc;
+            RECT rect;
+
+            hdc = BeginPaint( p_hwnd, &paintstruct );
+
+            GetClientRect( p_hwnd, &rect );
+            FillRect( hdc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH) );
+            TextOut( hdc, p_plugin->i_width / 2 - 40, p_plugin->i_height / 2,
+                     WINDOW_TEXT, strlen(WINDOW_TEXT) );
+
+            EndPaint( p_hwnd, &paintstruct );
+            break;
+        }
+#endif
+        default:
+            p_plugin->pf_wndproc( p_hwnd, i_msg, wpar, lpar );
+            break;
+    }
+    return 0;
+}
+#endif
+
 /******************************************************************************
  * UNIX-only methods
  *****************************************************************************/
-#ifndef WIN32
+#ifdef XP_UNIX
 static void Redraw( Widget w, XtPointer closure, XEvent *event )
 {
     VlcPlugin* p_plugin = (VlcPlugin*)closure;
     GC gc;
     XGCValues gcv;
-    const char * psz_text = "(no picture)";
 
-    gcv.foreground = BlackPixel( p_plugin->display, 0 );
-    gc = XCreateGC( p_plugin->display, p_plugin->window, GCForeground, &gcv );
+    gcv.foreground = BlackPixel( p_plugin->p_display, 0 );
+    gc = XCreateGC( p_plugin->p_display, p_plugin->window, GCForeground, &gcv );
 
-    XFillRectangle( p_plugin->display, p_plugin->window, gc,
-                    0, 0, p_plugin->width, p_plugin->height );
+    XFillRectangle( p_plugin->p_display, p_plugin->window, gc,
+                    0, 0, p_plugin->i_width, p_plugin->i_height );
 
-    gcv.foreground = WhitePixel( p_plugin->display, 0 );
-    XChangeGC( p_plugin->display, gc, GCForeground, &gcv );
+    gcv.foreground = WhitePixel( p_plugin->p_display, 0 );
+    XChangeGC( p_plugin->p_display, gc, GCForeground, &gcv );
 
-    XDrawString( p_plugin->display, p_plugin->window, gc,
-                 p_plugin->width / 2 - 40, p_plugin->height / 2,
-                 psz_text, strlen(psz_text) );
+    XDrawString( p_plugin->p_display, p_plugin->window, gc,
+                 p_plugin->i_width / 2 - 40, p_plugin->i_height / 2,
+                 WINDOW_TEXT, strlen(WINDOW_TEXT) );
 
-    XFreeGC( p_plugin->display, gc );
+    XFreeGC( p_plugin->p_display, gc );
 }
 #endif