* at last, transpareny WORKS !!!!!
[vlc.git] / modules / gui / skins / gtk2 / gtk2_window.cpp
1 /*****************************************************************************
2  * gtk2_window.cpp: GTK2 implementation of the Window class
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: gtk2_window.cpp,v 1.16 2003/04/16 14:38:04 asmax Exp $
6  *
7  * Authors: Cyril Deguet     <asmax@videolan.org>
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,
22  * USA.
23  *****************************************************************************/
24
25 #if !defined WIN32
26
27 //--- GENERAL ---------------------------------------------------------------
28 //#include <math.h>
29
30 //--- VLC -------------------------------------------------------------------
31 #include <vlc/intf.h>
32
33 //--- GTK2 ------------------------------------------------------------------
34 #include <gdk/gdk.h>
35 #include <glib.h>
36
37 //--- SKIN ------------------------------------------------------------------
38 #include "os_api.h"
39 #include "anchor.h"
40 #include "generic.h"
41 #include "window.h"
42 #include "os_window.h"
43 #include "event.h"
44 #include "os_event.h"
45 #include "graphics.h"
46 #include "os_graphics.h"
47 #include "skin_common.h"
48 #include "theme.h"
49
50
51 //---------------------------------------------------------------------------
52 // Fading API
53 //---------------------------------------------------------------------------
54 /*#define LWA_COLORKEY  0x00000001
55 #define LWA_ALPHA     0x00000002
56 typedef BOOL (WINAPI *SLWA)(HWND, COLORREF, BYTE, DWORD);
57 HMODULE hModule = LoadLibrary( "user32.dll" );
58 SLWA SetLayeredWindowAttributes =
59     (SLWA)GetProcAddress( hModule, "SetLayeredWindowAttributes" );
60 */
61
62 //---------------------------------------------------------------------------
63 // Skinable Window
64 //---------------------------------------------------------------------------
65 GTK2Window::GTK2Window( intf_thread_t *p_intf, GdkWindow *gwnd, int x, int y,
66     bool visible, int transition, int normalalpha, int movealpha,
67     bool dragdrop, string name )
68     : Window( p_intf, x, y, visible, transition, normalalpha, movealpha,
69               dragdrop )
70 {
71     // Set handles
72     gWnd           = gwnd;
73     gc = gdk_gc_new( gwnd );
74
75     Name        = name;
76
77     LButtonDown = false;
78     RButtonDown = false;
79 /*
80     // Set position parameters
81     CursorPos    = new POINT;
82     WindowPos    = new POINT;
83
84     // Create Tool Tip Window
85     ToolTipWindow = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
86         WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
87         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
88         hWnd, 0, GetModuleHandle( NULL ), 0);
89
90     // Create Tool Tip infos
91     ToolTipInfo.cbSize = sizeof(TOOLINFO);
92     ToolTipInfo.uFlags = TTF_SUBCLASS|TTF_IDISHWND;
93     ToolTipInfo.hwnd = hWnd;
94     ToolTipInfo.hinst = GetModuleHandle( NULL );
95     ToolTipInfo.uId = (unsigned int)hWnd;
96     ToolTipInfo.lpszText = NULL;
97     ToolTipInfo.rect.left = ToolTipInfo.rect.top = 0;
98         ToolTipInfo.rect.right = ToolTipInfo.rect.bottom = 0;
99
100     SendMessage( ToolTipWindow, TTM_ADDTOOL, 0,
101                     (LPARAM)(LPTOOLINFO) &ToolTipInfo );
102
103     // Drag & drop
104     if( DragDrop )
105     {
106         // Initialize the OLE library
107         OleInitialize( NULL );
108         DropTarget = (LPDROPTARGET) new GTK2DropObject();
109         // register the listview as a drop target
110         RegisterDragDrop( hWnd, DropTarget );
111     }
112 */
113     // Create Tool Tip window
114 /*    GdkWindowAttr attr;
115     attr.event_mask = GDK_ALL_EVENTS_MASK;
116     attr.width = 100;
117     attr.height = 100;
118     attr.window_type = GDK_WINDOW_CHILD;
119     attr.wclass = GDK_INPUT_OUTPUT;
120     gint mask = 0;
121     ToolTipWindow = gdk_window_new( gwnd, &attr, mask);*/
122
123 }
124 //---------------------------------------------------------------------------
125 GTK2Window::~GTK2Window()
126 {
127 /*    delete CursorPos;
128     delete WindowPos;
129
130     if( hWnd != NULL )
131     {
132         DestroyWindow( hWnd );
133     }
134     if( ToolTipWindow != NULL )
135     {
136         DestroyWindow( ToolTipWindow );
137     }
138     if( DragDrop )
139     {
140         // Remove the listview from the list of drop targets
141         RevokeDragDrop( hWnd );
142         DropTarget->Release();
143         // Uninitialize the OLE library
144         OleUninitialize();
145     }
146 */
147 }
148 //---------------------------------------------------------------------------
149 void GTK2Window::OSShow( bool show )
150 {
151     if( show )
152     {
153         gdk_window_show( gWnd );
154     }
155     else
156     {
157         gdk_window_hide( gWnd );
158     }
159 }
160 //---------------------------------------------------------------------------
161 bool GTK2Window::ProcessOSEvent( Event *evt )
162 {
163     unsigned int msg = evt->GetMessage();
164     unsigned int p1  = evt->GetParam1();
165     int          p2  = evt->GetParam2();
166
167     switch( msg )
168     {
169         case GDK_EXPOSE:
170             RefreshFromImage( 0, 0, Width, Height );
171             return true;
172
173         case GDK_MOTION_NOTIFY:
174             if( LButtonDown )
175                 MouseMove( (int)( (GdkEventButton *)p2 )->x,
176                            (int)( (GdkEventButton *)p2 )->y, 1 );
177             else if( RButtonDown )
178                 MouseMove( (int)( (GdkEventButton *)p2 )->x,
179                            (int)( (GdkEventButton *)p2 )->y, 2 );
180             else
181                 MouseMove( (int)( (GdkEventButton *)p2 )->x,
182                            (int)( (GdkEventButton *)p2 )->y, 0 );
183             gdk_window_get_pointer( gWnd, 0, 0, 0 );
184             return true;
185
186
187         case GDK_BUTTON_PRESS:
188             switch( ( (GdkEventButton *)p2 )->button )
189             {
190                 case 1:
191                     // Left button
192                     LButtonDown = true;
193                     MouseDown( (int)( (GdkEventButton *)p2 )->x,
194                                (int)( (GdkEventButton *)p2 )->y, 1 );
195                     break;
196
197                 case 3:
198                     // Right button
199                     RButtonDown = true;
200                     MouseDown( (int)( (GdkEventButton *)p2 )->x,
201                                (int)( (GdkEventButton *)p2 )->y, 2 );
202                     break;
203
204                 default:
205                     break;
206             }
207             return true;
208
209         case GDK_BUTTON_RELEASE:
210             switch( ( (GdkEventButton *)p2 )->button )
211             {
212                 case 1:
213                     // Left button
214                     LButtonDown = false;
215                     MouseUp( (int)( (GdkEventButton *)p2 )->x,
216                              (int)( (GdkEventButton *)p2 )->y, 1 );
217                     break;
218
219                 case 3:
220                     // Right button
221                     RButtonDown = false;
222                     MouseUp( (int)( (GdkEventButton *)p2 )->x,
223                              (int)( (GdkEventButton *)p2 )->y, 2 );
224                     break;
225
226                 default:
227                     break;
228             }
229             return true;
230
231         case GDK_LEAVE_NOTIFY:
232             OSAPI_PostMessage( this, WINDOW_LEAVE, 0, 0 );
233             return true;
234 /*
235         case WM_LBUTTONDBLCLK:
236             MouseDblClick( LOWORD( p2 ), HIWORD( p2 ), 1 );
237             return true;
238
239 */
240         default:
241             return false;
242     }
243 }
244 //---------------------------------------------------------------------------
245 void GTK2Window::SetTransparency( int Value )
246 {
247 /*    if( Value > -1 )
248         Alpha = Value;
249     SetLayeredWindowAttributes( hWnd, 0, Alpha, LWA_ALPHA | LWA_COLORKEY );
250     UpdateWindow( hWnd );*/
251 }
252 //---------------------------------------------------------------------------
253 void GTK2Window::RefreshFromImage( int x, int y, int w, int h )
254 {
255     // Initialize painting
256 /*    HDC DC = GetWindowDC( hWnd );
257
258     // Draw image on window
259     BitBlt( DC, x, y, w, h, ( (GTK2Graphics *)Image )->GetImageHandle(),
260             x, y, SRCCOPY );
261
262     // Release window device context
263     ReleaseDC( hWnd, DC );
264
265 */ 
266     GdkDrawable *drawable = (( GTK2Graphics* )Image )->GetImage();
267     GdkImage *image = gdk_drawable_get_image( drawable, 0, 0, Width, Height );
268     
269     gdk_draw_drawable( gWnd, gc, drawable, x, y, x, y, w, h );
270
271     // Mask for transparency
272     GdkRegion *region = gdk_region_new();
273     for( int line = 0; line < Height; line++ )
274     {
275         int start = 0;
276         while( gdk_image_get_pixel( image, start, line ) == 0 && start < Width-1)
277         {
278             start++;
279         } 
280         int end = Width - 1;
281         while( end >=0 && gdk_image_get_pixel( image, end, line ) == 0)
282         {
283             end--;
284         }
285         GdkRectangle rect;
286         rect.x = start;
287         rect.y = line;
288         rect.width = end - start + 1;
289         rect.height = 1;
290         GdkRegion *rectReg = gdk_region_rectangle( &rect );
291         gdk_region_union( region, rectReg );
292         gdk_region_destroy( rectReg );
293     }
294     gdk_window_shape_combine_region( gWnd, region, 0, 0 );
295     gdk_region_destroy( region );
296 }
297 //---------------------------------------------------------------------------
298 void GTK2Window::WindowManualMove()
299 {
300     // Get mouse cursor position
301     int x, y;
302     gdk_window_get_pointer( gdk_get_default_root_window(), &x, &y, NULL );
303
304     // Move window and chek for magnetism
305     p_intf->p_sys->p_theme->MoveSkinMagnet( this,
306         WindowX + x - CursorX, WindowY + y - CursorY );
307
308 }
309 //---------------------------------------------------------------------------
310 void GTK2Window::WindowManualMoveInit()
311 {
312     gdk_window_get_pointer( gdk_get_default_root_window(), &CursorX, &CursorY,
313                             NULL );
314     WindowX = Left;
315     WindowY = Top;
316 }
317 //---------------------------------------------------------------------------
318 void GTK2Window::Move( int left, int top )
319 {
320     Left = left;
321     Top  = top;
322     gdk_window_move( gWnd, left, top );
323 }
324 //---------------------------------------------------------------------------
325 void GTK2Window::Size( int width, int height )
326 {
327     Width  = width;
328     Height = height;
329     gdk_window_resize( gWnd, width, height );
330 }
331 //---------------------------------------------------------------------------
332 void GTK2Window::ChangeToolTipText( string text )
333 {
334 /*    if( text == "none" )
335     {
336         if( ToolTipText != "none" )
337         {
338             ToolTipText = "none";
339             ToolTipInfo.lpszText = NULL;
340             SendMessage( ToolTipWindow, TTM_ACTIVATE, 0 , 0 );
341         }
342     }
343     else
344     {
345         if( text != ToolTipText )
346         {
347             ToolTipText = text;
348             ToolTipInfo.lpszText = (char *)ToolTipText.c_str();
349             SendMessage( ToolTipWindow, TTM_ACTIVATE, 1 , 0 );
350             SendMessage( ToolTipWindow, TTM_UPDATETIPTEXT, 0,
351                              (LPARAM)(LPTOOLINFO)&ToolTipInfo );
352         }
353     }
354 */
355 }
356 //---------------------------------------------------------------------------
357
358 #endif