/src/main.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 213 lines · 144 code · 37 blank · 32 comment · 16 complexity · 5608c7ef7ebb2db367acab0f77a7426a MD5 · raw file

  1. /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2. *
  3. * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  4. *
  5. * Tomahawk is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * Tomahawk is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "TomahawkApp.h"
  19. #include "thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.h"
  20. #include "UbuntuUnityHack.h"
  21. #include "TomahawkSettings.h"
  22. #include "utils/TomahawkUtils.h"
  23. #include "config.h"
  24. #include "utils/Logger.h"
  25. #ifdef Q_WS_MAC
  26. #include "TomahawkApp_Mac.h"
  27. #include </System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/Headers/AppleEvents.h>
  28. static pascal OSErr appleEventHandler( const AppleEvent*, AppleEvent*, long );
  29. #endif
  30. #ifndef ENABLE_HEADLESS
  31. #include "TomahawkSettingsGui.h"
  32. #include "breakpad/BreakPad.h"
  33. #endif
  34. #ifdef Q_OS_WIN
  35. // code from patch attached to QTBUG-19064 by Honglei Zhang
  36. LRESULT QT_WIN_CALLBACK qt_LowLevelKeyboardHookProc( int nCode, WPARAM wParam, LPARAM lParam );
  37. HHOOK hKeyboardHook;
  38. HINSTANCE hGuiLibInstance;
  39. LRESULT QT_WIN_CALLBACK qt_LowLevelKeyboardHookProc( int nCode, WPARAM wParam, LPARAM lParam )
  40. {
  41. LPKBDLLHOOKSTRUCT kbHookStruct = reinterpret_cast<LPKBDLLHOOKSTRUCT>(lParam);
  42. switch(kbHookStruct->vkCode)
  43. {
  44. case VK_VOLUME_MUTE:
  45. case VK_VOLUME_DOWN:
  46. case VK_VOLUME_UP:
  47. case VK_MEDIA_NEXT_TRACK:
  48. case VK_MEDIA_PREV_TRACK:
  49. case VK_MEDIA_STOP:
  50. case VK_MEDIA_PLAY_PAUSE:
  51. case VK_LAUNCH_MEDIA_SELECT:
  52. // send message
  53. {
  54. HWND hWnd = NULL;
  55. foreach ( QWidget *widget, QApplication::topLevelWidgets() )
  56. {
  57. // relay message to each top level widgets(window)
  58. // if the window has focus, we don't send a duplicate message
  59. if ( QApplication::activeWindow() == widget )
  60. continue;
  61. hWnd = widget->winId();
  62. // generate message and post it to the message queue
  63. LPKBDLLHOOKSTRUCT pKeyboardHookStruct = reinterpret_cast<LPKBDLLHOOKSTRUCT>(lParam);
  64. WPARAM _wParam = pKeyboardHookStruct->vkCode;
  65. LPARAM _lParam = MAKELPARAM( pKeyboardHookStruct->scanCode, pKeyboardHookStruct->flags );
  66. PostMessage( hWnd, wParam, _wParam, _lParam );
  67. }
  68. }
  69. break;
  70. default:
  71. break;
  72. }
  73. return CallNextHookEx( 0, nCode, wParam, lParam );
  74. }
  75. #include <io.h>
  76. #define argc __argc
  77. #define argv __argv
  78. // code taken from AbiWord, (c) AbiSource Inc.
  79. int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )
  80. {
  81. hKeyboardHook = NULL;
  82. hGuiLibInstance = hInstance;
  83. // setup keyboard hook to receive multimedia key events when application is at background
  84. hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL,(HOOKPROC) qt_LowLevelKeyboardHookProc, hGuiLibInstance, 0 );
  85. if ( fileno( stdout ) != -1 && _get_osfhandle( fileno( stdout ) ) != -1 )
  86. {
  87. /* stdout is fine, presumably redirected to a file or pipe */
  88. }
  89. else
  90. {
  91. typedef BOOL (WINAPI * AttachConsole_t) (DWORD);
  92. AttachConsole_t p_AttachConsole = (AttachConsole_t) GetProcAddress( GetModuleHandleW( L"kernel32.dll" ), "AttachConsole" );
  93. if ( p_AttachConsole != NULL && p_AttachConsole( ATTACH_PARENT_PROCESS ) )
  94. {
  95. _wfreopen ( L"CONOUT$", L"w", stdout );
  96. dup2( fileno( stdout ), 1 );
  97. _wfreopen ( L"CONOUT$", L"w", stderr );
  98. dup2( fileno( stderr ), 2 );
  99. }
  100. }
  101. #else // Q_OS_WIN
  102. int
  103. main( int argc, char *argv[] )
  104. {
  105. #ifdef Q_WS_MAC
  106. // Do Mac specific startup to get media keys working.
  107. // This must go before QApplication initialisation.
  108. Tomahawk::macMain();
  109. // Fixes focus issue with NSSearchField, see QTBUG-11401
  110. // code taken from clementine:main.cpp:336
  111. QCoreApplication::setAttribute( Qt::AA_NativeWindows, true );
  112. // used for url handler
  113. AEEventHandlerUPP h = AEEventHandlerUPP( appleEventHandler );
  114. AEInstallEventHandler( 'GURL', 'GURL', h, 0, false );
  115. #endif // Q_WS_MAC
  116. #endif //Q_OS_WIN
  117. TomahawkApp a( argc, argv );
  118. // MUST register StateHash ****before*** initing TomahawkSettingsGui as constructor of settings does upgrade before Gui subclass registers type
  119. TomahawkSettings::registerCustomSettingsHandlers();
  120. TomahawkSettingsGui::registerCustomSettingsHandlers();
  121. #ifdef ENABLE_HEADLESS
  122. new TomahawkSettings( &a );
  123. #else
  124. new TomahawkSettingsGui( &a );
  125. #endif
  126. #ifndef ENABLE_HEADLESSs
  127. #ifdef WITH_BREAKPAD
  128. new BreakPad( QDir::tempPath(), TomahawkSettings::instance()->crashReporterEnabled() && !TomahawkUtils::headless() );
  129. #endif
  130. #endif
  131. KDSingleApplicationGuard guard( KDSingleApplicationGuard::AutoKillOtherInstances );
  132. QObject::connect( &guard, SIGNAL( instanceStarted( KDSingleApplicationGuard::Instance ) ), &a, SLOT( instanceStarted( KDSingleApplicationGuard::Instance ) ) );
  133. if ( guard.isPrimaryInstance() )
  134. a.init();
  135. if ( argc > 1 )
  136. {
  137. QString arg = a.arguments()[ 1 ];
  138. a.loadUrl( arg );
  139. }
  140. int returnCode = 0;
  141. if ( guard.isPrimaryInstance() )
  142. returnCode = a.exec();
  143. #ifdef Q_OS_WIN
  144. // clean up keyboard hook
  145. if ( hKeyboardHook )
  146. {
  147. UnhookWindowsHookEx( hKeyboardHook );
  148. hKeyboardHook = NULL;
  149. }
  150. #endif
  151. return returnCode;
  152. }
  153. #ifdef Q_WS_MAC
  154. static pascal OSErr
  155. appleEventHandler( const AppleEvent* e, AppleEvent*, long )
  156. {
  157. OSType id = typeWildCard;
  158. AEGetAttributePtr( e, keyEventIDAttr, typeType, 0, &id, sizeof( id ), 0 );
  159. switch ( id )
  160. {
  161. case 'GURL':
  162. {
  163. DescType type;
  164. Size size;
  165. char buf[1024];
  166. AEGetParamPtr( e, keyDirectObject, typeChar, &type, &buf, 1023, &size );
  167. buf[size] = '\0';
  168. QString url = QString::fromUtf8( buf );
  169. static_cast<TomahawkApp*>(qApp)->loadUrl( url );
  170. return noErr;
  171. }
  172. default:
  173. return unimpErr;
  174. }
  175. }
  176. #endif