Wacommands.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. #include "WACommands.h"
  2. #include "gen_hotkeys.h"
  3. #include "../nu/AutoWide.h"
  4. typedef struct {
  5. UINT strId;
  6. genHotkeysAddStruct ghk;
  7. } genHotkeysAddStructLocalised;
  8. genHotkeysAddStructLocalised WADefCommands[] = {
  9. {IDS_PLAYBACK__PLAY,{0, 0, WM_COMMAND, WINAMP_BUTTON2, 0, "ghkdc play"}},
  10. {IDS_PLAYBACK__PAUSE,{0, 0, WM_COMMAND, WINAMP_BUTTON3, 0, "ghkdc pause"}},
  11. {IDS_PLAYBACK__STOP,{0, 0, WM_COMMAND, WINAMP_BUTTON4, 0, "ghkdc stop"}},
  12. {IDS_PLAYBACK__PREVIOUS_IN_PLAYLIST,{0, 0, WM_COMMAND, WINAMP_BUTTON1, 0, "ghkdc prev"}},
  13. {IDS_PLAYBACK__NEXT_IN_PLAYLIST,{0, 0, WM_COMMAND, WINAMP_BUTTON5, 0, "ghkdc next"}},
  14. {IDS_PLAYBACK__VOLUME_UP,{0, 0, WM_COMMAND, WINAMP_VOLUMEUP, 0, "ghkdc vup"}},
  15. {IDS_PLAYBACK__VOLUME_DOWN,{0, 0, WM_COMMAND, WINAMP_VOLUMEDOWN, 0, "ghkdc vdown"}},
  16. {IDS_PLAYBACK__FORWARD,{0, 0, WM_COMMAND, WINAMP_FFWD5S, 0, "ghkdc forward"}},
  17. {IDS_PLAYBACK__REWIND,{0, 0, WM_COMMAND, WINAMP_REW5S, 0, "ghkdc rewind"}},
  18. {IDS_PLAYBACK__REPEAT_ON,{0, 0, WM_WA_IPC, 1, IPC_SET_REPEAT, "ghkdc repeat on"}},
  19. {IDS_PLAYBACK__REPEAT_OFF,{0, 0, WM_WA_IPC, 0, IPC_SET_REPEAT, "ghkdc repeat off"}},
  20. {IDS_UI__TOGGLE_EQ,{0, 0, WM_COMMAND, WINAMP_OPTIONS_EQ, 0, "ghkdc t eq"}},
  21. {IDS_UI__TOGGLE_PLAYLIST,{0, 0, WM_COMMAND, WINAMP_OPTIONS_PLEDIT, 0, "ghkdc t pl"}},
  22. {IDS_UI__TOGGLE_AOT,{0, 0, WM_COMMAND, WINAMP_OPTIONS_AOT, 0, "ghkdc t aot"}},
  23. {IDS_UI__ABOUT,{0, HKF_BRING_TO_FRONT, WM_COMMAND, WINAMP_HELP_ABOUT, 0, "ghkdc about"}},
  24. {IDS_PLAYBACK__JUMP_TO_BOX,{0, HKF_BRING_TO_FRONT, WM_COMMAND, 40194, 0, "ghkdc jump"}},
  25. {IDS_PLAYBACK__OPEN_FILE_DIALOG,{0, HKF_BRING_TO_FRONT|HKF_WPARAM_HWND, WM_WA_IPC, 0, IPC_OPENFILEBOX, "ghkdc file"}},
  26. {IDS_PLAYBACK__OPEN_LOC_DIALOG,{0, HKF_BRING_TO_FRONT, WM_COMMAND, WINAMP_BUTTON2_CTRL, 0, "ghkdc url"}},
  27. {IDS_PLAYBACK__OPEN_FOLDER_DIALOG,{0, HKF_BRING_TO_FRONT|HKF_WPARAM_HWND, WM_WA_IPC, 0, IPC_OPENDIRBOX, "ghkdc dir"}},
  28. {IDS_GENERAL__QUIT,{0, 0, WM_CLOSE, 0, 0, "ghkdc quit"}},
  29. {IDS_UI__PREFERENCES,{0, HKF_BRING_TO_FRONT, WM_WA_IPC, (WPARAM)(-1), IPC_OPENPREFSTOPAGE, "ghkdc prefs"}},
  30. {IDS_GENERAL__COPY_TITLE,{0, HKF_COPY_RET|HKF_PLPOS_WPARAM, WM_WA_IPC, 0, IPC_GETPLAYLISTTITLE, "ghkdc copy"}},
  31. {IDS_GENERAL__COPY_FILE_PATH,{0, HKF_COPY_RET|HKF_WPARAM_PLPOS, WM_WA_IPC, 0, IPC_GETPLAYLISTFILE, "ghkdc copy path"}},
  32. {IDS_PLAYBACK__PLAY_PAUSE,{0, HKF_ISPLAYING_WL, WM_COMMAND, WINAMP_BUTTON3, WINAMP_BUTTON2, "ghkdc play/pause"}},
  33. {IDS_PLAYBACK__TOGGLE_REPEAT,{0, 0, WM_COMMAND, 40022, 0, "ghkdc t repeaat"}},
  34. {IDS_PLAYBACK__TOGGLE_SHUFFLE,{0, 0, WM_COMMAND, 40023, 0, "ghkdc t shuffle"}},
  35. {IDS_UI__TOGGLE_WINSHADE,{0, 0, WM_COMMAND, 40064, 0, "ghkdc ws"}},
  36. {IDS_UI__TOGGLE_PLAYLIST_WINSHADE,{0, 0, WM_COMMAND, 40266, 0, "ghkdc pl ws"}},
  37. {IDS_UI__TOGGLE_DOUBLESIZE,{0, 0, WM_COMMAND, 40165, 0, "ghkdc ds"}},
  38. {IDS_UI__TOGGLE_MAIN_WINDOW,{0, 0, WM_COMMAND, 40258, 0, "ghkdc t main"}},
  39. // removed due to it not being in current winamp builds now {IDS_UI__TOGGLE_MINIBROWSER,{0, 0, WM_COMMAND, 40298, 0, "ghkdc t mb"}},
  40. {IDS_VIS__PREFERENCES,{0, HKF_BRING_TO_FRONT, WM_COMMAND, 40191, 0, "ghkdc vis prefs"}},
  41. {IDS_VIS_TOGGLE_VIS_ON_OFF,{0, 0, WM_COMMAND, 40192, 0, "ghkdc t vis"}},
  42. // added in 1.91 based on user feedback (ID_VIS_* options) and also from finding the correct menu id to use
  43. {IDS_VIS__PLUGIN_PREFERENCES,{0, HKF_BRING_TO_FRONT, WM_COMMAND, 40221, 0, "ghkdc prefs vis"}},
  44. {IDS_VIS_NEXT_PRESET,{0, 0, WM_COMMAND, ID_VIS_NEXT, 0, "ghkdc vis next"}},
  45. {IDS_VIS_PREV_PRESET,{0, 0, WM_COMMAND, ID_VIS_PREV, 0, "ghkdc vis prev"}},
  46. {IDS_VIS_RAND_PRESET,{0, 0, WM_COMMAND, ID_VIS_RANDOM, 0, "ghkdc vis rand"}},
  47. {IDS_VIS_FULL_SCREEN,{0, 0, WM_COMMAND, ID_VIS_FS, 0, "ghkdc vis fs"}},
  48. {IDS_UI__SELECT_SKIN,{0, HKF_BRING_TO_FRONT, WM_COMMAND, 40219, 0, "ghkdc skin"}},
  49. {IDS_PLAYBACK__STOP_WITH_FADEOUT,{0, 0, WM_COMMAND, WINAMP_BUTTON4_SHIFT, 0, "ghkdc stop fade"}},
  50. {IDS_PLAYBACK__STOP_AFTER_CURRENT,{0, 0, WM_COMMAND, WINAMP_BUTTON4_CTRL, 0, "ghkdc stop ac"}},
  51. {IDS_PLAYBACK__START_OF_LIST,{0, 0, WM_COMMAND, WINAMP_BUTTON1_CTRL, 0, "ghkdc sol"}},
  52. {IDS_PLAYBACK__END_OF_LIST,{0, 0, WM_COMMAND, WINAMP_BUTTON5_CTRL, 0, "ghkdc eol"}},
  53. {IDS_UI__BRING_TO_FRONT_OR_HIDE,{0, HKF_SHOWHIDE, WM_SHOWWINDOW, 0, 0, "ghkdc show/hide"}},
  54. {IDS_RATING__5_STARS,{0, 0, WM_WA_IPC, 5, IPC_SETRATING, "ghkdc rating 5"}},
  55. {IDS_RATING__4_STARS,{0, 0, WM_WA_IPC, 4, IPC_SETRATING, "ghkdc rating 4"}},
  56. {IDS_RATING__3_STARS,{0, 0, WM_WA_IPC, 3, IPC_SETRATING, "ghkdc rating 3"}},
  57. {IDS_RATING__2_STARS,{0, 0, WM_WA_IPC, 2, IPC_SETRATING, "ghkdc rating 2"}},
  58. {IDS_RATING__1_STAR,{0, 0, WM_WA_IPC, 1, IPC_SETRATING, "ghkdc rating 1"}},
  59. {IDS_RATING__NO_RATING,{0, 0, WM_WA_IPC, 0, IPC_SETRATING, "ghkdc rating 0"}},
  60. // added in 1.4+ so that we can deal with unicode strings on 5.3x+ Winamp versions
  61. {IDS_GENERAL__COPY_TITLEW,{0, HKF_COPYW_RET|HKF_PLPOS_WPARAM, WM_WA_IPC, 0, IPC_GETPLAYLISTTITLEW, "ghkdc copyw"}},
  62. {IDS_GENERAL__COPY_FILE_PATHW,{0, HKF_COPYW_RET|HKF_WPARAM_PLPOS, WM_WA_IPC, 0, IPC_GETPLAYLISTFILEW, "ghkdc copy pathw"}},
  63. // added in 1.6+ for neorth
  64. {IDS_RATING__INC,{0, 0, WM_WA_IPC, 6, IPC_SETRATING, "ghkdc inc rating"}},
  65. {IDS_RATING__DEC,{0, 0, WM_WA_IPC, (WPARAM)(-1), IPC_SETRATING, "ghkdc dec rating"}},
  66. // added in 1.91 for kzuse
  67. {IDS_PLAYBACK__MANUAL_ADVANCE,{0, 0, WM_COMMAND, 40395, 0, "ghkdc man adv"}},
  68. // added in 1.92 as killing of separate gen_find_on_disk.dll to be native
  69. {IDS_GENERAL_FFOD,{0, 0, WM_COMMAND, 40468, 0, "FFOD_Cur"}},
  70. {IDS_PLAYBACK_EDIT_ID3,{0, 0, WM_COMMAND, 40188, 0, "VCFI"}},
  71. };
  72. static unsigned int WACommandsNum;
  73. static unsigned int WACommandsAllocated;
  74. WACommand *WACommands=0;
  75. inline unsigned int GetCommandsNum()
  76. {
  77. return WACommandsNum;
  78. }
  79. static bool ReallocateCommands()
  80. {
  81. if (WACommandsNum < WACommandsAllocated)
  82. return true;
  83. WACommand *newCommands = new WACommand[ WACommandsNum * 2 + 16];
  84. if (newCommands)
  85. memcpy(newCommands, WACommands, WACommandsAllocated*sizeof(WACommand));
  86. WACommandsAllocated = WACommandsNum * 2 + 16;
  87. delete [] WACommands;
  88. WACommands = newCommands;
  89. if (!WACommands)
  90. {
  91. WACommandsAllocated = 0;
  92. return false;
  93. }
  94. return true;
  95. }
  96. void InitCommands()
  97. {
  98. int l = sizeof(WADefCommands) / sizeof(WADefCommands[0]);
  99. while (l--)
  100. {
  101. wchar_t rateBuf[1024] = {0};
  102. wchar_t* rateStr = rateBuf;
  103. WADefCommands[l].ghk.name = (char*)WASABI_API_LNGSTRINGW_BUF(WADefCommands[l].strId, rateBuf, 1024);
  104. switch(WADefCommands[l].strId)
  105. {
  106. // for the rating entries force any asterisks to a unicode star
  107. case IDS_RATING__1_STAR:
  108. case IDS_RATING__2_STARS:
  109. case IDS_RATING__3_STARS:
  110. case IDS_RATING__4_STARS:
  111. case IDS_RATING__5_STARS:
  112. while(rateStr && *rateStr)
  113. {
  114. if(*rateStr == L'*') *rateStr = L'\u2605';
  115. rateStr=CharNextW(rateStr);
  116. }
  117. break;
  118. }
  119. WADefCommands[l].ghk.flags |= HKF_UNICODE_NAME;
  120. AddCommand(&WADefCommands[l].ghk);
  121. }
  122. }
  123. int AddCommand(genHotkeysAddStruct *ghas)
  124. {
  125. unsigned int idx = WACommandsNum;
  126. if (!ghas)
  127. return -1;
  128. // legacy support
  129. if (!ghas->id)
  130. ghas->id = ghas->name;
  131. if (WACommands)
  132. {
  133. unsigned int l = WACommandsNum;
  134. while (l--)
  135. {
  136. if (!lstrcmpiW(WACommands[l].id, AutoWide(ghas->id)))
  137. {
  138. WACommands[l].bEnabled = !(ghas->flags & HKF_DISABLED);
  139. char *name = 0;
  140. if(!(ghas->flags & HKF_UNICODE_NAME))
  141. name = (char *) malloc(lstrlen(ghas->name) + 1);
  142. else
  143. name = (char *) malloc((lstrlenW((wchar_t*)ghas->name) + 1) * sizeof(wchar_t));
  144. if (name)
  145. {
  146. free(WACommands[l].name);
  147. WACommands[l].name = name;
  148. }
  149. WACommands[l].dwFlags = (ghas->flags & 0x7FFFFFFF);
  150. WACommands[l].uMsg = ghas->uMsg;
  151. WACommands[l].wParam = ghas->wParam;
  152. WACommands[l].lParam = ghas->lParam;
  153. WACommands[l].wnd = ghas->wnd;
  154. return l;
  155. }
  156. }
  157. }
  158. WACommandsNum++;
  159. if (!ReallocateCommands())
  160. {
  161. WACommandsNum--;
  162. return -2;
  163. }
  164. if(!(ghas->flags & HKF_UNICODE_NAME))
  165. WACommands[idx].name = _strdup(ghas->name);
  166. else
  167. WACommands[idx].name = (char*)_wcsdup((wchar_t*)ghas->name);
  168. if (!WACommands[idx].name)
  169. {
  170. WACommandsNum--;
  171. return -1;
  172. }
  173. WACommands[idx].id = AutoWideDup(ghas->id);
  174. if (!WACommands[idx].id)
  175. {
  176. free(WACommands[idx].name);
  177. WACommandsNum--;
  178. return -1;
  179. }
  180. WACommands[idx].dwFlags = (ghas->flags & 0x7FFFFFFF);
  181. WACommands[idx].uMsg = ghas->uMsg;
  182. WACommands[idx].wParam = ghas->wParam;
  183. WACommands[idx].lParam = ghas->lParam;
  184. WACommands[idx].bEnabled = !(ghas->flags & HKF_DISABLED);
  185. WACommands[idx].wnd = ghas->wnd;
  186. return idx;
  187. }
  188. inline char *GetCommandName(unsigned int i, bool *unicode)
  189. {
  190. if (i < WACommandsNum)
  191. {
  192. if(unicode) *unicode = !!(WACommands[i].dwFlags & HKF_UNICODE_NAME);
  193. return WACommands[i].name;
  194. }
  195. return "";
  196. }
  197. inline wchar_t *GetCommandId(unsigned int i)
  198. {
  199. if (i < WACommandsNum)
  200. return WACommands[i].id;
  201. return L"";
  202. }
  203. int GetCommandIdx(wchar_t *id)
  204. {
  205. if (WACommands)
  206. {
  207. unsigned int l = WACommandsNum;
  208. while (l--)
  209. {
  210. if (!lstrcmpiW(WACommands[l].id, id))
  211. {
  212. return l;
  213. }
  214. }
  215. }
  216. return -1;
  217. }
  218. int HandleByScript(unsigned int i)
  219. {
  220. if (i >= WACommandsNum) return 0;
  221. if (SendMessage(psPlugin.hwndParent, WM_WA_IPC, (WPARAM)WACommands[i].name, IPC_FF_NOTIFYHOTKEY)) return 0;
  222. return 1;
  223. }
  224. int DoCommand(unsigned int i)
  225. {
  226. if (i >= WACommandsNum)
  227. return 0;
  228. if (!WACommands[i].bEnabled)
  229. return 0;
  230. if (HandleByScript(i)) return 1;
  231. WPARAM wParam = WACommands[i].wParam;
  232. LPARAM lParam = WACommands[i].lParam;
  233. /*if (WACommands[i].dwFlags & HKF_CUSTOM_FUNC)
  234. {
  235. if (WACommands[i].uMsg)
  236. {
  237. pfnWAC pfn = (pfnWAC) WACommands[i].uMsg;
  238. pfn();
  239. }
  240. return 0;
  241. }*/
  242. if (WACommands[i].dwFlags & HKF_SHOWHIDE)
  243. {
  244. DWORD dwThisProcId, dwProcId;
  245. GetWindowThreadProcessId(psPlugin.hwndParent, &dwThisProcId);
  246. GetWindowThreadProcessId(GetForegroundWindow(), &dwProcId);
  247. if (IsWindowVisible(psPlugin.hwndParent) && dwProcId == dwThisProcId)
  248. ShowWindow(psPlugin.hwndParent, SW_MINIMIZE);
  249. else
  250. {
  251. ShowWindow(psPlugin.hwndParent, SW_SHOWNORMAL);
  252. SetForegroundWindow(psPlugin.hwndParent);
  253. }
  254. }
  255. HWND hwnddest=WACommands[i].wnd ? WACommands[i].wnd : psPlugin.hwndParent;
  256. if (WACommands[i].dwFlags & HKF_BRING_TO_FRONT)
  257. {
  258. SetForegroundWindow(psPlugin.hwndParent);
  259. }
  260. if (WACommands[i].dwFlags & HKF_WPARAM_HWND)
  261. {
  262. wParam = (WPARAM) psPlugin.hwndParent;
  263. }
  264. if (WACommands[i].dwFlags & HKF_WPARAM_PLPOS)
  265. {
  266. wParam = (WPARAM) SendMessage(psPlugin.hwndParent, WM_WA_IPC, 0, IPC_GETLISTPOS);
  267. }
  268. if (WACommands[i].dwFlags & HKF_WPARAM_ISPLAYING_WL)
  269. {
  270. if (SendMessage(psPlugin.hwndParent, WM_WA_IPC, 0, IPC_ISPLAYING))
  271. wParam = WACommands[i].wParam; // Pause
  272. else
  273. wParam = WACommands[i].lParam; // Play
  274. lParam = 0;
  275. }
  276. LRESULT lResult = SendMessage(hwnddest, WACommands[i].uMsg, wParam, lParam);
  277. if (WACommands[i].dwFlags & HKF_COPY && lResult)
  278. {
  279. char *szTitle = (char *) lResult;
  280. if (!OpenClipboard(psPlugin.hwndParent))
  281. return 0;
  282. EmptyClipboard();
  283. int bufLen = lstrlen(szTitle) + 1;
  284. HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, bufLen);
  285. if (!hglbCopy)
  286. {
  287. CloseClipboard();
  288. return 0;
  289. }
  290. char *szClipboardTitle = (char *) GlobalLock(hglbCopy);
  291. if (!szClipboardTitle)
  292. {
  293. CloseClipboard();
  294. return 0;
  295. }
  296. lstrcpyn(szClipboardTitle, szTitle, bufLen);
  297. GlobalUnlock(hglbCopy);
  298. SetClipboardData(CF_TEXT, hglbCopy);
  299. CloseClipboard();
  300. }
  301. if (WACommands[i].dwFlags & HKF_COPYW && lResult)
  302. {
  303. wchar_t *szTitle = (wchar_t *) lResult;
  304. if (!OpenClipboard(psPlugin.hwndParent))
  305. return 0;
  306. EmptyClipboard();
  307. int bufLen = (lstrlenW(szTitle) + 1) * sizeof(wchar_t);
  308. HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, bufLen);
  309. if (!hglbCopy)
  310. {
  311. CloseClipboard();
  312. return 0;
  313. }
  314. wchar_t *szClipboardTitle = (wchar_t *) GlobalLock(hglbCopy);
  315. if (!szClipboardTitle)
  316. {
  317. CloseClipboard();
  318. return 0;
  319. }
  320. lstrcpynW(szClipboardTitle, szTitle, bufLen);
  321. GlobalUnlock(hglbCopy);
  322. SetClipboardData(CF_UNICODETEXT, hglbCopy);
  323. CloseClipboard();
  324. }
  325. return (int)lResult;
  326. }