* added transparency in X11 skins
[vlc.git] / modules / gui / skins / x11 / x11_window.cpp
1 /*****************************************************************************
2  * x11_window.cpp: X11 implementation of the Window class
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: x11_window.cpp,v 1.4 2003/05/18 17:48:05 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 #ifdef X11_SKINS
26
27 //--- GENERAL ---------------------------------------------------------------
28 //#include <math.h>
29
30 //--- VLC -------------------------------------------------------------------
31 #include <vlc/intf.h>
32
33 //--- X11 -------------------------------------------------------------------
34 #include <X11/Xlib.h>
35 #include <X11/extensions/shape.h>
36
37 //--- SKIN ------------------------------------------------------------------
38 #include "../os_api.h"
39 #include "../src/anchor.h"
40 #include "../controls/generic.h"
41 #include "../src/window.h"
42 #include "../os_window.h"
43 #include "../src/event.h"
44 #include "../os_event.h"
45 #include "../src/graphics.h"
46 #include "../os_graphics.h"
47 #include "../src/skin_common.h"
48 #include "../src/theme.h"
49
50
51 //---------------------------------------------------------------------------
52 // Skinable Window
53 //---------------------------------------------------------------------------
54 X11Window::X11Window( intf_thread_t *p_intf, Window wnd, int x, int y,
55     bool visible, int transition, int normalalpha, int movealpha,
56     bool dragdrop, string name )
57     : SkinWindow( p_intf, x, y, visible, transition, normalalpha, movealpha,
58               dragdrop )
59 {
60     // Set handles
61     Wnd           = wnd;
62
63     display = p_intf->p_sys->display;
64     int screen = DefaultScreen( display );
65
66     Gc = DefaultGC( display, screen );
67
68     Name        = name;
69
70     LButtonDown = false;
71     RButtonDown = false;
72
73     // Removing fading effect
74     Transition  = 0;
75 /*
76     // Set position parameters
77     CursorPos    = new POINT;
78     WindowPos    = new POINT;
79
80     // Create Tool Tip Window
81     ToolTipWindow = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
82         WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
83         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
84         hWnd, 0, GetModuleHandle( NULL ), 0);
85
86     // Create Tool Tip infos
87     ToolTipInfo.cbSize = sizeof(TOOLINFO);
88     ToolTipInfo.uFlags = TTF_SUBCLASS|TTF_IDISHWND;
89     ToolTipInfo.hwnd = hWnd;
90     ToolTipInfo.hinst = GetModuleHandle( NULL );
91     ToolTipInfo.uId = (unsigned int)hWnd;
92     ToolTipInfo.lpszText = NULL;
93     ToolTipInfo.rect.left = ToolTipInfo.rect.top = 0;
94         ToolTipInfo.rect.right = ToolTipInfo.rect.bottom = 0;
95
96     SendMessage( ToolTipWindow, TTM_ADDTOOL, 0,
97                     (LPARAM)(LPTOOLINFO) &ToolTipInfo );
98 */
99     if( DragDrop )
100     {
101         // register the listview as a drop target
102         DropObject = new X11DropObject( p_intf );
103     //    gdk_window_register_dnd( gwnd );
104     }
105
106     // Create Tool Tip window
107 /*    GdkWindowAttr attr;
108     attr.event_mask = GDK_ALL_EVENTS_MASK;
109     attr.width = 100;
110     attr.height = 100;
111     attr.window_type = GDK_WINDOW_CHILD;
112     attr.wclass = GDK_INPUT_OUTPUT;
113     gint mask = 0;
114     ToolTipWindow = gdk_window_new( gwnd, &attr, mask);*/
115
116 }
117 //---------------------------------------------------------------------------
118 X11Window::~X11Window()
119 {
120 /*    delete CursorPos;
121     delete WindowPos;
122
123     if( hWnd != NULL )
124     {
125         DestroyWindow( hWnd );
126     }
127     if( ToolTipWindow != NULL )
128     {
129         DestroyWindow( ToolTipWindow );
130     }
131     if( DragDrop )
132     {
133         // Remove the listview from the list of drop targets
134         RevokeDragDrop( hWnd );
135         DropTarget->Release();
136         // Uninitialize the OLE library
137         OleUninitialize();
138     }*/
139  /*   if( gWnd )
140     {
141         gdk_window_destroy( gWnd );
142     }*/
143 }
144 //---------------------------------------------------------------------------
145 void X11Window::OSShow( bool show )
146 {
147     if( show )
148     {
149 /*        gdk_window_show( gWnd );
150         gdk_window_move( gWnd, Left, Top );*/
151     }
152     else
153     {
154 /*        gdk_window_hide( gWnd );*/
155     }
156 }
157 //---------------------------------------------------------------------------
158 bool X11Window::ProcessOSEvent( Event *evt )
159 {
160     unsigned int msg = evt->GetMessage();
161     unsigned int p1  = evt->GetParam1();
162     int          p2  = evt->GetParam2();
163     
164     switch( msg )
165     {
166         case Expose:
167             RefreshFromImage( 0, 0, Width, Height );
168             return true;
169  
170         case MotionNotify:
171  /*           if( LButtonDown )
172                 MouseMove( (int)( (GdkEventButton *)p2 )->x,
173                            (int)( (GdkEventButton *)p2 )->y, 1 );
174             else if( RButtonDown )
175                 MouseMove( (int)( (GdkEventButton *)p2 )->x,
176                            (int)( (GdkEventButton *)p2 )->y, 2 );
177             else
178                 MouseMove( (int)( (GdkEventButton *)p2 )->x,
179                            (int)( (GdkEventButton *)p2 )->y, 0 );
180             gdk_window_get_pointer( gWnd, 0, 0, 0 );*/
181             return true;
182
183
184         case ButtonPress:
185             // Raise all the windows
186 /*            for( list<SkinWindow *>::const_iterator win = 
187                     p_intf->p_sys->p_theme->WindowList.begin();
188                     win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
189             {
190                 gdk_window_raise( ( (X11Window *)(*win) )->GetHandle() );
191             }
192           
193             switch( ( (GdkEventButton *)p2 )->button )
194             {
195                 case 1:
196                     // Left button
197                     LButtonDown = true;
198                     MouseDown( (int)( (GdkEventButton *)p2 )->x,
199                                (int)( (GdkEventButton *)p2 )->y, 1 );
200                     break;
201
202                 case 3:
203                     // Right button
204                     RButtonDown = true;
205                     MouseDown( (int)( (GdkEventButton *)p2 )->x,
206                                (int)( (GdkEventButton *)p2 )->y, 2 );
207                     break;
208
209                 default:
210                     break;
211             }*/
212             return true;
213
214         case ButtonRelease:
215 /*            switch( ( (GdkEventButton *)p2 )->button )
216             {
217                 case 1:
218                     // Left button
219                     LButtonDown = false;
220                     MouseUp( (int)( (GdkEventButton *)p2 )->x,
221                              (int)( (GdkEventButton *)p2 )->y, 1 );
222                     break;
223
224                 case 3:
225                     // Right button
226                     RButtonDown = false;
227                     MouseUp( (int)( (GdkEventButton *)p2 )->x,
228                              (int)( (GdkEventButton *)p2 )->y, 2 );
229                     break;
230
231                 default:
232                     break;
233             }*/
234             return true;
235
236         case LeaveNotify:
237             OSAPI_PostMessage( this, WINDOW_LEAVE, 0, 0 );
238             return true;
239
240 /*        case GDK_2BUTTON_PRESS:
241             MouseDblClick( (int)( (GdkEventButton *)p2 )->x,
242                            (int)( (GdkEventButton *)p2 )->y, 1 );
243             return true;
244
245         case GDK_DROP_START:
246             DropObject->HandleDropStart( ( (GdkEventDND *)p2 )->context );
247             return true;
248
249         case GDK_SCROLL:
250             switch( ( (GdkEventScroll *)p2 )->direction )
251             {
252                 case GDK_SCROLL_UP:
253                     MouseScroll( ( (GdkEventScroll *)p2 )->x,
254                                  ( (GdkEventScroll *)p2 )->y,
255                                  MOUSE_SCROLL_UP);
256                     break;
257                 case GDK_SCROLL_DOWN:
258                     MouseScroll( ( (GdkEventScroll *)p2 )->x,
259                                  ( (GdkEventScroll *)p2 )->y,
260                                  MOUSE_SCROLL_DOWN);
261                     break;
262             }
263             return true;
264 */
265         default:
266             return false;
267     }
268 }
269 //---------------------------------------------------------------------------
270 void X11Window::SetTransparency( int Value )
271 {
272 /*    if( Value > -1 )
273         Alpha = Value;
274     SetLayeredWindowAttributes( hWnd, 0, Alpha, LWA_ALPHA | LWA_COLORKEY );
275     UpdateWindow( hWnd );*/
276 }
277 //---------------------------------------------------------------------------
278 void X11Window::RefreshFromImage( int x, int y, int w, int h )
279 {
280     Drawable drawable = (( X11Graphics* )Image )->GetImage();
281     
282     XCopyArea( display, drawable, Wnd, Gc, x, y, w, h, x, y );
283  
284     XImage *image = XGetImage( display, drawable, 0, 0, Width, Height, 
285                                AllPlanes, ZPixmap );
286  
287     // Mask for transparency
288     Region region = XCreateRegion();
289     for( int line = 0; line < Height; line++ )
290     {
291         int start = 0, end = 0;
292         while( start < Width )
293         {
294             while( start < Width && XGetPixel( image, start, line ) == 0 )
295             {
296                 start++;
297             } 
298             end = start;
299             while( end < Width && XGetPixel( image, end, line ) != 0)
300             {
301                 end++;
302             }
303             XRectangle rect;
304             rect.x = start;
305             rect.y = line;
306             rect.width = end - start + 1;
307             rect.height = 1;
308             Region newRegion = XCreateRegion();
309             XUnionRectWithRegion( &rect, region, newRegion );
310             XDestroyRegion( region );
311             region = newRegion;
312             start = end + 1;
313         }
314     }
315     XShapeCombineRegion( display, Wnd, ShapeBounding, 0, 0, region, ShapeSet );
316     XDestroyRegion( region );
317
318     XSync( display, 0);
319 }
320 //---------------------------------------------------------------------------
321 void X11Window::WindowManualMove()
322 {
323     // Get mouse cursor position
324     int x, y;
325     OSAPI_GetMousePos( x, y );
326
327     // Move window and chek for magnetism
328     p_intf->p_sys->p_theme->MoveSkinMagnet( this,
329         WindowX + x - CursorX, WindowY + y - CursorY );
330
331 }
332 //---------------------------------------------------------------------------
333 void X11Window::WindowManualMoveInit()
334 {
335 /*    gdk_window_get_pointer( gdk_get_default_root_window(), &CursorX, &CursorY,
336                             NULL );*/
337     WindowX = Left;
338     WindowY = Top;
339 }
340 //---------------------------------------------------------------------------
341 void X11Window::Move( int left, int top )
342 {
343     Left = left;
344     Top  = top;
345     XMoveWindow( display, Wnd, left, top );
346    
347 }
348 //---------------------------------------------------------------------------
349 void X11Window::Size( int width, int height )
350 {
351     Width  = width;
352     Height = height;
353     XResizeWindow( display, Wnd, width, height );
354 }
355 //---------------------------------------------------------------------------
356 void X11Window::ChangeToolTipText( string text )
357 {
358 /*    if( text == "none" )
359     {
360         if( ToolTipText != "none" )
361         {
362             ToolTipText = "none";
363             ToolTipInfo.lpszText = NULL;
364             SendMessage( ToolTipWindow, TTM_ACTIVATE, 0 , 0 );
365         }
366     }
367     else
368     {
369         if( text != ToolTipText )
370         {
371             ToolTipText = text;
372             ToolTipInfo.lpszText = (char *)ToolTipText.c_str();
373             SendMessage( ToolTipWindow, TTM_ACTIVATE, 1 , 0 );
374             SendMessage( ToolTipWindow, TTM_UPDATETIPTEXT, 0,
375                              (LPARAM)(LPTOOLINFO)&ToolTipInfo );
376         }
377     }
378 */
379 }
380 //---------------------------------------------------------------------------
381
382 #endif