]> git.sesse.net Git - vlc/blob - modules/gui/qt4/main_interface_win32.cpp
8426a9035596d81819059dda96251021ed1b940b
[vlc] / modules / gui / qt4 / main_interface_win32.cpp
1 /*****************************************************************************
2  * main_interface_win32.cpp : Main interface
3  ****************************************************************************
4  * Copyright (C) 2006-2010 VideoLAN and AUTHORS
5  * $Id$
6  *
7  * Authors: Jean-Baptiste Kempf <jb@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 Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24
25 #include "main_interface.hpp"
26
27 #include "input_manager.hpp"
28 #include "actions_manager.hpp"
29 #include "dialogs_provider.hpp"
30
31 #include <QBitmap>
32 #include <vlc_windows_interfaces.h>
33
34 #if defined(_WIN32) && HAS_QT5
35 # include <QWindow>
36 # include <qpa/qplatformnativeinterface.h>
37 #endif
38
39
40 #define WM_APPCOMMAND 0x0319
41
42 #define APPCOMMAND_VOLUME_MUTE            8
43 #define APPCOMMAND_VOLUME_DOWN            9
44 #define APPCOMMAND_VOLUME_UP              10
45 #define APPCOMMAND_MEDIA_NEXTTRACK        11
46 #define APPCOMMAND_MEDIA_PREVIOUSTRACK    12
47 #define APPCOMMAND_MEDIA_STOP             13
48 #define APPCOMMAND_MEDIA_PLAY_PAUSE       14
49 #define APPCOMMAND_LAUNCH_MEDIA_SELECT    16
50 #define APPCOMMAND_BASS_DOWN              19
51 #define APPCOMMAND_BASS_BOOST             20
52 #define APPCOMMAND_BASS_UP                21
53 #define APPCOMMAND_TREBLE_DOWN            22
54 #define APPCOMMAND_TREBLE_UP              23
55 #define APPCOMMAND_MICROPHONE_VOLUME_MUTE 24
56 #define APPCOMMAND_MICROPHONE_VOLUME_DOWN 25
57 #define APPCOMMAND_MICROPHONE_VOLUME_UP   26
58 #define APPCOMMAND_HELP                   27
59 #define APPCOMMAND_OPEN                   30
60 #define APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE    43
61 #define APPCOMMAND_MIC_ON_OFF_TOGGLE      44
62 #define APPCOMMAND_MEDIA_PLAY             46
63 #define APPCOMMAND_MEDIA_PAUSE            47
64 #define APPCOMMAND_MEDIA_RECORD           48
65 #define APPCOMMAND_MEDIA_FAST_FORWARD     49
66 #define APPCOMMAND_MEDIA_REWIND           50
67 #define APPCOMMAND_MEDIA_CHANNEL_UP       51
68 #define APPCOMMAND_MEDIA_CHANNEL_DOWN     52
69
70 #define FAPPCOMMAND_MOUSE 0x8000
71 #define FAPPCOMMAND_KEY   0
72 #define FAPPCOMMAND_OEM   0x1000
73 #define FAPPCOMMAND_MASK  0xF000
74
75 #define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK))
76 #define GET_DEVICE_LPARAM(lParam)     ((WORD)(HIWORD(lParam) & FAPPCOMMAND_MASK))
77 #define GET_MOUSEORKEY_LPARAM         GET_DEVICE_LPARAM
78 #define GET_FLAGS_LPARAM(lParam)      (LOWORD(lParam))
79 #define GET_KEYSTATE_LPARAM(lParam)   GET_FLAGS_LPARAM(lParam)
80
81 HWND MainInterface::WinId()
82 {
83 #if HAS_QT5
84     QWindow *window = windowHandle();
85     HWND id = static_cast<HWND>(QGuiApplication::platformNativeInterface()->
86             nativeResourceForWindow("handle", window));
87     return id;
88 #else
89     return winId();
90 #endif
91 }
92
93 #if defined(_WIN32) && !HAS_QT5
94 static const int PremultipliedAlpha = QPixmap::PremultipliedAlpha;
95 static HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0)
96 {
97     return p.toWinHBITMAP((enum QBitmap::HBitmapFormat)hbitmapFormat);
98 }
99 #else
100 Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0);
101 enum HBitmapFormat
102 {
103     NoAlpha,
104     PremultipliedAlpha,
105     Alpha
106 };
107 #endif
108
109 void MainInterface::createTaskBarButtons()
110 {
111     /*Here is the code for the taskbar thumb buttons
112     FIXME:We need pretty buttons in 16x16 px that are handled correctly by masks in Qt
113     FIXME:the play button's picture doesn't changed to pause when clicked
114     */
115
116     CoInitializeEx( NULL, COINIT_MULTITHREADED );
117
118     if( S_OK == CoCreateInstance( CLSID_TaskbarList,
119                 NULL, CLSCTX_INPROC_SERVER,
120                 IID_ITaskbarList3,
121                 (void **)&p_taskbl) )
122     {
123         p_taskbl->HrInit();
124
125         if( (himl = ImageList_Create( 16, //cx
126                         16, //cy
127                         ILC_COLOR32,//flags
128                         4,//initial nb of images
129                         0//nb of images that can be added
130                         ) ) != NULL )
131         {
132             QPixmap img   = QPixmap(":/win7/prev");
133             QPixmap img2  = QPixmap(":/win7/pause");
134             QPixmap img3  = QPixmap(":/win7/play");
135             QPixmap img4  = QPixmap(":/win7/next");
136             QBitmap mask  = img.createMaskFromColor(Qt::transparent);
137             QBitmap mask2 = img2.createMaskFromColor(Qt::transparent);
138             QBitmap mask3 = img3.createMaskFromColor(Qt::transparent);
139             QBitmap mask4 = img4.createMaskFromColor(Qt::transparent);
140
141             if(-1 == ImageList_Add(himl, qt_pixmapToWinHBITMAP(img, PremultipliedAlpha), qt_pixmapToWinHBITMAP(mask)))
142                 msg_Err( p_intf, "First ImageList_Add failed" );
143             if(-1 == ImageList_Add(himl, qt_pixmapToWinHBITMAP(img2, PremultipliedAlpha), qt_pixmapToWinHBITMAP(mask2)))
144                 msg_Err( p_intf, "Second ImageList_Add failed" );
145             if(-1 == ImageList_Add(himl, qt_pixmapToWinHBITMAP(img3, PremultipliedAlpha), qt_pixmapToWinHBITMAP(mask3)))
146                 msg_Err( p_intf, "Third ImageList_Add failed" );
147             if(-1 == ImageList_Add(himl, qt_pixmapToWinHBITMAP(img4, PremultipliedAlpha), qt_pixmapToWinHBITMAP(mask4)))
148                 msg_Err( p_intf, "Fourth ImageList_Add failed" );
149         }
150
151         // Define an array of two buttons. These buttons provide images through an
152         // image list and also provide tooltips.
153         THUMBBUTTONMASK dwMask = THUMBBUTTONMASK(THB_BITMAP | THB_FLAGS);
154
155         THUMBBUTTON thbButtons[3];
156         thbButtons[0].dwMask = dwMask;
157         thbButtons[0].iId = 0;
158         thbButtons[0].iBitmap = 0;
159         thbButtons[0].dwFlags = THBF_HIDDEN;
160
161         thbButtons[1].dwMask = dwMask;
162         thbButtons[1].iId = 1;
163         thbButtons[1].iBitmap = 2;
164         thbButtons[1].dwFlags = THBF_HIDDEN;
165
166         thbButtons[2].dwMask = dwMask;
167         thbButtons[2].iId = 2;
168         thbButtons[2].iBitmap = 3;
169         thbButtons[2].dwFlags = THBF_HIDDEN;
170
171         HRESULT hr = p_taskbl->ThumbBarSetImageList(WinId(), himl );
172         if(S_OK != hr)
173             msg_Err( p_intf, "ThumbBarSetImageList failed with error %08lx", hr );
174         else
175         {
176             hr = p_taskbl->ThumbBarAddButtons(WinId(), 3, thbButtons);
177             if(S_OK != hr)
178                 msg_Err( p_intf, "ThumbBarAddButtons failed with error %08lx", hr );
179         }
180         CONNECT( THEMIM->getIM(), playingStatusChanged( int ), this, changeThumbbarButtons( int ) );
181     }
182     else
183     {
184         himl = NULL;
185         p_taskbl = NULL;
186     }
187
188 }
189
190 bool MainInterface::winEvent ( MSG * msg, long * result )
191 {
192     if (msg->message == taskbar_wmsg)
193     {
194         //We received the taskbarbuttoncreated, now we can really create the buttons
195         createTaskBarButtons();
196     }
197
198     short cmd;
199     switch( msg->message )
200     {
201         case WM_COMMAND:
202             if (HIWORD(msg->wParam) == THBN_CLICKED)
203             {
204                 switch(LOWORD(msg->wParam))
205                 {
206                     case 0:
207                         THEMIM->prev();
208                         break;
209                     case 1:
210                         THEMIM->togglePlayPause();
211                         break;
212                     case 2:
213                         THEMIM->next();
214                         break;
215                 }
216             }
217             break;
218         case WM_APPCOMMAND:
219             cmd = GET_APPCOMMAND_LPARAM(msg->lParam);
220
221             if( p_intf->p_sys->disable_volume_keys &&
222                     (   cmd == APPCOMMAND_VOLUME_DOWN   ||
223                         cmd == APPCOMMAND_VOLUME_UP     ||
224                         cmd == APPCOMMAND_VOLUME_MUTE ) )
225             {
226                 break;
227             }
228
229             *result = TRUE;
230
231             switch(cmd)
232             {
233                 case APPCOMMAND_MEDIA_PLAY_PAUSE:
234                     THEMIM->togglePlayPause();
235                     break;
236                 case APPCOMMAND_MEDIA_PLAY:
237                     THEMIM->play();
238                     break;
239                 case APPCOMMAND_MEDIA_PAUSE:
240                     THEMIM->pause();
241                     break;
242                 case APPCOMMAND_MEDIA_CHANNEL_DOWN:
243                 case APPCOMMAND_MEDIA_PREVIOUSTRACK:
244                     THEMIM->prev();
245                     break;
246                 case APPCOMMAND_MEDIA_CHANNEL_UP:
247                 case APPCOMMAND_MEDIA_NEXTTRACK:
248                     THEMIM->next();
249                     break;
250                 case APPCOMMAND_MEDIA_STOP:
251                     THEMIM->stop();
252                     break;
253                 case APPCOMMAND_MEDIA_RECORD:
254                     THEAM->record();
255                     break;
256                 case APPCOMMAND_VOLUME_DOWN:
257                     THEAM->AudioDown();
258                     break;
259                 case APPCOMMAND_VOLUME_UP:
260                     THEAM->AudioUp();
261                     break;
262                 case APPCOMMAND_VOLUME_MUTE:
263                     THEAM->toggleMuteAudio();
264                     break;
265                 case APPCOMMAND_MEDIA_FAST_FORWARD:
266                     THEMIM->getIM()->faster();
267                     break;
268                 case APPCOMMAND_MEDIA_REWIND:
269                     THEMIM->getIM()->slower();
270                     break;
271                 case APPCOMMAND_HELP:
272                     THEDP->mediaInfoDialog();
273                     break;
274                 case APPCOMMAND_OPEN:
275                     THEDP->simpleOpenDialog();
276                     break;
277                 default:
278                      msg_Dbg( p_intf, "unknown APPCOMMAND = %d", cmd);
279                      *result = FALSE;
280                      break;
281             }
282             if (*result) return true;
283             break;
284     }
285     return false;
286 }
287
288 void MainInterface::changeThumbbarButtons( int i_status )
289 {
290     if( p_taskbl == NULL )
291         return;
292
293     // Define an array of three buttons. These buttons provide images through an
294     // image list and also provide tooltips.
295     THUMBBUTTONMASK dwMask = THUMBBUTTONMASK(THB_BITMAP | THB_FLAGS);
296
297     THUMBBUTTON thbButtons[3];
298     //prev
299     thbButtons[0].dwMask = dwMask;
300     thbButtons[0].iId = 0;
301     thbButtons[0].iBitmap = 0;
302
303     //play/pause
304     thbButtons[1].dwMask = dwMask;
305     thbButtons[1].iId = 1;
306
307     //next
308     thbButtons[2].dwMask = dwMask;
309     thbButtons[2].iId = 2;
310     thbButtons[2].iBitmap = 3;
311
312     switch( i_status )
313     {
314         case OPENING_S:
315         case PLAYING_S:
316             {
317                 thbButtons[0].dwFlags = THBF_ENABLED;
318                 thbButtons[1].dwFlags = THBF_ENABLED;
319                 thbButtons[2].dwFlags = THBF_ENABLED;
320                 thbButtons[1].iBitmap = 1;
321                 break;
322             }
323         case END_S:
324         case PAUSE_S:
325         case ERROR_S:
326             {
327                 thbButtons[0].dwFlags = THBF_ENABLED;
328                 thbButtons[1].dwFlags = THBF_ENABLED;
329                 thbButtons[2].dwFlags = THBF_ENABLED;
330                 thbButtons[1].iBitmap = 2;
331                 break;
332             }
333         default:
334             return;
335     }
336     HRESULT hr =  p_taskbl->ThumbBarUpdateButtons(WinId(), 3, thbButtons);
337     if(S_OK != hr)
338         msg_Err( p_intf, "ThumbBarUpdateButtons failed with error %08lx", hr );
339 }