ed514c41248eedc4b4b5c078143511927cea7b87
[vlc.git] / plugins / sdl / intf_sdl.c
1 /*****************************************************************************
2  * intf_sdl.c: SDL interface plugin
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  * $Id: intf_sdl.c,v 1.20 2001/01/08 01:07:21 bozo Exp $
6  *
7  * Authors:
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  * 
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include "defs.h"
28
29 #include <errno.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <SDL/SDL.h>                                /* for all the SDL stuff */
33
34 #include "config.h"
35 #include "common.h"
36 #include "threads.h"
37 #include "mtime.h"
38 #include "plugins.h"
39
40 #include "stream_control.h"
41 #include "input_ext-intf.h"
42
43 #include "video.h"
44 #include "video_output.h"
45
46
47 #include "interface.h"
48 #include "intf_msg.h"
49 #include "keystrokes.h"
50
51 #include "main.h"
52
53 /*****************************************************************************
54  * intf_sys_t: description and status of SDL interface
55  *****************************************************************************/
56 typedef struct intf_sys_s
57 {
58     /* SDL system information */
59     SDL_Surface * p_display;
60     boolean_t b_Fullscreen;
61 } intf_sys_t;
62
63 typedef struct vout_sys_s
64 {
65     int i_width;
66     int i_height;
67     SDL_Surface *   p_display;                             /* display device */
68     SDL_Overlay *   p_overlay;
69     boolean_t   b_fullscreen;
70     boolean_t   b_reopen_display;
71     Uint8   *   p_buffer[2];
72                                                      /* Buffers informations */
73 }   vout_sys_t;
74
75
76 /* local prototype */
77 void intf_SDL_Keymap( intf_thread_t * p_intf );
78 void intf_SDL_Resize( intf_thread_t * p_intf, int width, int height );
79 void intf_SDL_Fullscreen(intf_thread_t * p_intf);
80 void intf_SDL_YUVSwitch(intf_thread_t * p_intf);
81   
82
83 /*****************************************************************************
84  * intf_SDLCreate: initialize and create SDL interface
85  *****************************************************************************/
86 int intf_SDLCreate( intf_thread_t *p_intf )
87 {
88     /* Check that b_video is set */
89     if( !p_main->b_video )
90     {
91         intf_ErrMsg( "error: SDL interface requires a video output thread" );
92         return( 1 );
93     }
94
95     /* Allocate instance and initialize some members */
96     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
97     if( p_intf->p_sys == NULL )
98     {
99         intf_ErrMsg("error: %s", strerror(ENOMEM) );
100         return( 1 );
101     }
102
103     /* Spawn video output thread */
104     p_intf->p_vout = vout_CreateThread( main_GetPszVariable( VOUT_DISPLAY_VAR,
105                                                              NULL), 0,
106                                         main_GetIntVariable( VOUT_WIDTH_VAR,
107                                                          VOUT_WIDTH_DEFAULT ),
108                                         main_GetIntVariable( VOUT_HEIGHT_VAR,
109                                                         VOUT_HEIGHT_DEFAULT ),
110                                         NULL, 0,
111                                         (void *)&p_intf->p_sys->p_display );
112
113     if( p_intf->p_vout == NULL )                                  /* error */
114     {
115         intf_ErrMsg( "error: can't create video output thread" );
116         free( p_intf->p_sys );
117         return( 1 );
118     }
119     intf_SDL_Keymap( p_intf );
120     return( 0 );
121 }
122
123 /*****************************************************************************
124  * intf_SDLDestroy: destroy interface
125  *****************************************************************************/
126 void intf_SDLDestroy( intf_thread_t *p_intf )
127 {
128     /* Close input thread, if any (blocking) */
129     if( p_intf->p_input )
130     {
131         input_DestroyThread( p_intf->p_input, NULL );
132     }
133
134     /* Close video output thread, if any (blocking) */
135     if( p_intf->p_vout )
136     {
137         vout_DestroyThread( p_intf->p_vout, NULL );
138     }
139
140     /* Destroy structure */
141     
142     SDL_FreeSurface( p_intf->p_sys->p_display );     /* destroy the "screen" */
143     SDL_Quit();
144     free( p_intf->p_sys );
145 }
146
147
148 /*****************************************************************************
149  * intf_SDLManage: event loop
150  *****************************************************************************/
151 void intf_SDLManage( intf_thread_t *p_intf )
152 {
153     SDL_Event event;                                            /* SDL event */
154     Uint8   i_key;
155     
156     while ( SDL_PollEvent(&event) )
157     {
158         i_key = event.key.keysym.sym;                          /* forward it */
159
160         switch (event.type) {
161             case SDL_VIDEORESIZE:                      /* Resizing of window */
162                 intf_SDL_Resize( p_intf, event.resize.w, event.resize.h );
163                 break;
164             case SDL_KEYDOWN:                         /* if a key is pressed */
165                 switch(i_key) {
166                                                     /* switch to fullscreen  */
167                     case SDLK_f:
168                         intf_SDL_Fullscreen(p_intf);
169                         break;
170                     case SDLK_y:
171                         intf_SDL_YUVSwitch(p_intf);
172                         break; 
173                   default :
174                         if( intf_ProcessKey( p_intf, (char ) i_key ) )
175                         {
176                             intf_DbgMsg( "unhandled key '%c' (%i)",
177                                          (char) i_key, i_key );
178                         }
179                         break;
180                 }
181                 break;
182             case SDL_QUIT:
183                 intf_ProcessKey( p_intf, INTF_KEY_QUIT ); 
184                 break;
185            default:
186                 break;
187         }
188     }
189 }
190
191 void intf_SDL_Resize( intf_thread_t * p_intf, int width, int height )
192 {
193     intf_Msg( "Video display resized (%dx%d)", width, height ); 
194     vlc_mutex_lock( &p_intf->p_vout->change_lock );
195     p_intf->p_vout->p_sys->i_width = width;
196     p_intf->p_vout->p_sys->i_height = height;
197     p_intf->p_vout->p_sys->b_reopen_display = 1;
198     vlc_mutex_unlock( &p_intf->p_vout->change_lock );
199 }
200
201 void intf_SDL_YUVSwitch(intf_thread_t * p_intf)
202 {
203     vlc_mutex_lock( &p_intf->p_vout->change_lock );
204 //    p_intf->p_vout->p_sys->b_must_acquire = 0;
205     p_intf->p_vout->b_need_render = 1 - p_intf->p_vout->b_need_render;
206     intf_DbgMsg( "need render now : '%d'",p_intf->p_vout->b_need_render); 
207     p_intf->p_vout->p_sys->b_reopen_display = 1;
208     vlc_mutex_unlock( &p_intf->p_vout->change_lock );
209 }
210 void intf_SDL_Fullscreen(intf_thread_t * p_intf)
211 {
212     vlc_mutex_lock( &p_intf->p_vout->change_lock );
213     p_intf->p_vout->p_sys->b_fullscreen = 1-p_intf->p_vout->p_sys->b_fullscreen;
214     p_intf->p_vout->p_sys->b_reopen_display = 1;
215     vlc_mutex_unlock( &p_intf->p_vout->change_lock );
216
217     
218
219
220
221 void intf_SDL_Keymap(intf_thread_t * p_intf )
222 {
223     /* p_intf->p_intf_getKey = intf_getKey; */
224     intf_AssignKey(p_intf, SDLK_q,      INTF_KEY_QUIT, 0);
225     intf_AssignKey(p_intf, SDLK_ESCAPE, INTF_KEY_QUIT, 0);
226     /* intf_AssignKey(p_intf,3,'Q'); */
227     intf_AssignKey(p_intf, SDLK_0,      INTF_KEY_SET_CHANNEL,0);
228     intf_AssignKey(p_intf, SDLK_1,      INTF_KEY_SET_CHANNEL,1);
229     intf_AssignKey(p_intf, SDLK_2,      INTF_KEY_SET_CHANNEL,2);
230     intf_AssignKey(p_intf, SDLK_3,      INTF_KEY_SET_CHANNEL,3);
231     intf_AssignKey(p_intf, SDLK_4,      INTF_KEY_SET_CHANNEL,4);
232     intf_AssignKey(p_intf, SDLK_5,      INTF_KEY_SET_CHANNEL,5);
233     intf_AssignKey(p_intf, SDLK_6,      INTF_KEY_SET_CHANNEL,6);
234     intf_AssignKey(p_intf, SDLK_7,      INTF_KEY_SET_CHANNEL,7);
235     intf_AssignKey(p_intf, SDLK_8,      INTF_KEY_SET_CHANNEL,8);
236     intf_AssignKey(p_intf, SDLK_9,      INTF_KEY_SET_CHANNEL,9);
237     intf_AssignKey(p_intf, SDLK_PLUS,   INTF_KEY_INC_VOLUME, 0);
238     intf_AssignKey(p_intf, SDLK_MINUS,  INTF_KEY_DEC_VOLUME, 0);
239     intf_AssignKey(p_intf, SDLK_m,      INTF_KEY_TOGGLE_VOLUME, 0);
240     /* intf_AssignKey(p_intf,'M','M'); */
241     intf_AssignKey(p_intf, SDLK_g,      INTF_KEY_DEC_GAMMA, 0);
242     /* intf_AssignKey(p_intf,'G','G'); */
243     intf_AssignKey(p_intf, SDLK_c,      INTF_KEY_TOGGLE_GRAYSCALE, 0);
244     intf_AssignKey(p_intf, SDLK_SPACE,  INTF_KEY_TOGGLE_INTERFACE, 0);
245     intf_AssignKey(p_intf, SDLK_i,         INTF_KEY_TOGGLE_INFO, 0);
246     intf_AssignKey(p_intf, SDLK_s,      INTF_KEY_TOGGLE_SCALING, 0);
247
248 }
249