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