interface.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:86k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: interface.c 624 2006-02-01 17:48:42Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../../common/common.h"
  24. #include "../win.h"
  25. #include "interface.h"
  26. #include "resource.h"
  27. #include "openfile_win32.h"
  28. #include "../about.h"
  29. #include "../benchresult.h"
  30. #include "../mediainfo.h"
  31. #include "../settings.h"
  32. #include "playlst.h"
  33. #include "../skin.h"
  34. #include "../../config.h"
  35. #define CORETHEQUE_UI_ID FOURCC('C','T','Q','U')
  36. #if defined(TARGET_WINCE) || defined(TARGET_WIN32)
  37. #ifndef STRICT
  38. #define STRICT
  39. #endif
  40. #include <windows.h>
  41. #if _MSC_VER > 1000
  42. #pragma warning(disable : 4201)
  43. #endif
  44. #include <commctrl.h>
  45. #define REG_INITING 0x2400
  46. #define TIMER_CLIPPING 500
  47. #define TIMER_INITING 501
  48. #define TIMER_SLEEP 502
  49. #define TIMER_KEYINSEEK 503
  50. #define TIMER_SLIDERINSEEK 504
  51. #define TIMER_SLIDERINVOL 505
  52. #define TIMER_CLIPPING2 506
  53. #define TIMER_TITLESCROLL 507
  54. #define SLIDERINSEEK_CYCLE 250
  55. #define SLIDERINVOL_CYCLE 100
  56. #define KEYINSEEK_START 1000
  57. #define KEYINSEEK_REPEAT 500
  58. #define CLIPPING_CYCLE 200
  59. #define INITING_CYCLE 3000
  60. #define SLEEP_CYCLE 5000
  61. #define CLIPPING2_CYCLE 200
  62. #define TITLESCROLL_CYCLE 150
  63. #define TITLESCROLL_WAIT (4000/TITLESCROLL_CYCLE)
  64. #define TRACKMAX 30000
  65. #define TRACKHEIGHT 16
  66. #define TRACKTHUMB 12
  67. #define TITLEHEIGHT 16
  68. #define TITLEFONT 11
  69. #define VOLMINWIDTH 35
  70. #define VOLTHUMB 12
  71. #define IF_AUDIO 50000
  72. #define IF_VIDEO 51000
  73. #define IF_VIDEOACCEL 52000
  74. #define IF_CHAPTER 53000
  75. #define IF_STREAM_AUDIO 54000
  76. #define IF_STREAM_VIDEO 55000
  77. #define IF_STREAM_SUBTITLE 56000
  78. static int HotKey[] = 
  79. {
  80. IF_FILE_OPENFILE,
  81. IF_FILE_PLAYLIST,
  82. IF_PLAY,
  83. IF_PLAYPAUSE,
  84. IF_PLAY_FULLSCREEN,
  85. IF_STOP,
  86. IF_MOVE_FFWD,
  87. IF_MOVE_BACK,
  88. IF_NEXT,
  89. IF_PREV,
  90. IF_PREV_SMART,
  91. IF_NEXT2,
  92. IF_PREV_SMART2,
  93. IF_FASTFORWARD,
  94. IF_OPTIONS_VOLUME_UP,
  95. IF_OPTIONS_VOLUME_DOWN,
  96. IF_OPTIONS_VOLUME_UP_FINE,
  97. IF_OPTIONS_VOLUME_DOWN_FINE,
  98. IF_OPTIONS_MUTE,
  99. IF_OPTIONS_EQUALIZER,
  100. IF_OPTIONS_FULLSCREEN,
  101. IF_OPTIONS_ZOOM_FIT,
  102. IF_OPTIONS_ZOOM_IN,
  103. IF_OPTIONS_ZOOM_OUT,
  104. IF_OPTIONS_ROTATE,
  105. IF_OPTIONS_BRIGHTNESS_UP,
  106. IF_OPTIONS_BRIGHTNESS_DOWN,
  107. IF_OPTIONS_CONTRAST_UP,
  108. IF_OPTIONS_CONTRAST_DOWN,
  109. IF_OPTIONS_SATURATION_UP,
  110. IF_OPTIONS_SATURATION_DOWN,
  111. IF_OPTIONS_TOGGLE_VIDEO,
  112. IF_OPTIONS_TOGGLE_AUDIO,
  113. //!SUBTITLE IF_OPTIONS_TOGGLE_SUBTITLE,
  114. IF_OPTIONS_AUDIO_STEREO_TOGGLE,
  115. IF_OPTIONS_SCREEN,
  116. IF_FILE_EXIT,
  117. };
  118. #define HOTKEYCOUNT (sizeof(HotKey)/sizeof(int))
  119. typedef struct intface
  120. {
  121. win Win;
  122. DWORD ThreadId;
  123. player* Player;
  124. node* Color;
  125. node* Equalizer;
  126. WNDPROC DefTrackProc;
  127. WNDPROC DefVolProc;
  128. HWND WndTrack;
  129. HWND WndTitle;
  130. HWND WndVol;
  131. HWND WndVolBack;
  132. int TrackThumb;
  133. RECT ClientRect;
  134. rect SkinViewport;
  135. rect SkinArea;
  136. rect Viewport;
  137. int InSkin;
  138. bool_t InVol;
  139. bool_t InSeek;
  140. bool_t Capture;
  141. bool_t ForceFullScreen;
  142. bool_t TrackBar;
  143. bool_t TitleBar;
  144. bool_t TaskBar;
  145. bool_t Buttons;
  146. bool_t Focus;
  147. bool_t Clipping;
  148. bool_t Overlap;
  149. bool_t VolResizeNeeded;
  150. bool_t VolResizeNeeded2;
  151. bool_t Exited;
  152. POINT Offset;
  153. bool_t Bench;
  154. bool_t Wait;
  155. bool_t CmdLineMode;
  156. int Vol;
  157. int HotKey[HOTKEYCOUNT];
  158. // refresh states
  159. int TrackSetPos;
  160. int TrackPos;
  161. bool_t Play;
  162. bool_t FFwd;
  163. bool_t FullScreen;
  164. bool_t Mute;
  165. HFONT TitleFont;
  166. int TitleFontSize;
  167. tick_t TitleTime;
  168. int TitleTimeWidth;
  169. int TitleNameWidth;
  170. int TitleNameSize;
  171. int TitleNameOffset;
  172. int ScrollMode;
  173. bool_t UpdateScroll;
  174. int TitleDurWidth;
  175. int TitleBorder;
  176. int TitleTop;
  177. int TitleWidth;
  178. int TitleHeight;
  179. HBRUSH TitleBrush;
  180. rgbval_t TitleFace;
  181. rgbval_t TitleText;
  182. tchar_t TitleName[256];
  183. tchar_t TitleDur[32];
  184. int MenuPreAmp;
  185. int MenuStreams;
  186. int MenuAStream;
  187. int MenuVStream;
  188. int MenuSubStream;
  189. array VOutput;
  190. array AOutput;
  191. bool_t AllKeys;
  192. bool_t AllKeysWarning;
  193. int SkinNo;
  194. skin Skin[MAX_SKIN];
  195. tchar_t SkinPath[MAXPATH];
  196. } intface;
  197. static void ResizeVolume(intface* p)
  198. {
  199. if (p->WndVolBack)
  200. {
  201. RECT rv;
  202. RECT r;
  203. POINT o;
  204. int Width;
  205. int i;
  206. GetClientRect(p->Win.WndTB,&r);
  207. if (r.left<r.right)
  208. {
  209. SendMessage(p->Win.WndTB,TB_GETRECT,IF_OPTIONS_MUTE,(LPARAM)&rv);
  210. #if defined(TARGET_WINCE)
  211. if (p->Win.ToolBarHeight) // decrease width by 'X' button on right
  212. r.right = max(r.left,r.right-(rv.right-rv.left));
  213. #endif
  214. Width = r.right-rv.right;
  215. if (Width < 16)
  216. Width = 16;
  217. i = WinUnitToPixelX(&p->Win,50);
  218. if (Width > i)
  219. Width = i;
  220. o.x = o.y = 0;
  221. if (!p->Win.ToolBarHeight)
  222. ClientToScreen(p->Win.WndTB,&o);
  223. MoveWindow(p->WndVolBack,rv.right+o.x,o.y+1,Width,r.bottom-1,TRUE);
  224. GetClientRect(p->WndVolBack,&r);
  225. i = WinUnitToPixelX(&p->Win,2);
  226. MoveWindow(p->WndVol,-i,0,r.right+2*i,r.bottom,TRUE);
  227. SendMessage(p->WndVol, TBM_SETTHUMBLENGTH,WinUnitToPixelY(&p->Win,VOLTHUMB),0);
  228. }
  229. }
  230. }
  231. static bool_t Toggle(intface* p,int Param,int Force);
  232. static void UpdateVolume(intface* p);
  233. static void UpdateClipping(intface* p,bool_t Suggest,bool_t HotKey);
  234. static void ShowVol(intface* p,bool_t Show)
  235. {
  236. if (p->WndVolBack && !p->Win.ToolBarHeight)
  237. {
  238. if (Show)
  239. SetWindowPos(p->WndVolBack,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_SHOWWINDOW);
  240. else
  241. ShowWindow(p->WndVolBack,SW_HIDE);
  242. if (p->VolResizeNeeded2>1)
  243. p->VolResizeNeeded2=1;
  244. }
  245. }
  246. static void Resize(intface* p)
  247. {
  248. RECT r;
  249. bool_t Rotated = IsOrientationChanged();
  250. DEBUG_MSG(DEBUG_VIDEO,T("Resize begin"));
  251. if (Rotated)
  252. {
  253. p->Player->Set(p->Player,PLAYER_ROTATEBEGIN,NULL,0);
  254. p->Player->Set(p->Player,PLAYER_RESETVIDEO,NULL,0);
  255. if (!p->Win.ToolBarHeight)
  256. {
  257. p->VolResizeNeeded2 = 1; // toolbar position may change later
  258. if (p->WndVolBack && IsWindowVisible(p->WndVolBack))
  259. {
  260. ShowVol(p,0);
  261. p->VolResizeNeeded2 = 2;
  262. }
  263. }
  264. else
  265. p->VolResizeNeeded = 1;
  266. if (p->Win.FullScreen)
  267. PostMessage(p->Win.Wnd,MSG_PLAYER,PLAYER_FULLSCREEN,0);
  268. }
  269. p->Offset.x = 0;
  270. p->Offset.y = 0;
  271. ClientToScreen(p->Win.Wnd,&p->Offset);
  272. if (!p->Win.FullScreen)
  273. {
  274. #if !defined(TARGET_WINCE) && defined(MAXIMIZE_FULLSCREEN)
  275. WINDOWPLACEMENT Place;
  276. Place.length = sizeof(Place);
  277. GetWindowPlacement(p->Win.Wnd,&Place);
  278. if (Place.showCmd != SW_MAXIMIZE)
  279. #endif
  280. {
  281. GetClientRect(p->Win.Wnd,&r);
  282. if (r.right != p->ClientRect.right || r.bottom != p->ClientRect.bottom)
  283. {
  284. bool_t Skin = p->Skin[p->SkinNo].Valid;
  285. int TrackThumb;
  286. int TrackHeight = 0;
  287. p->TitleHeight = 0;
  288. p->ClientRect = r;
  289. r.top += p->Win.ToolBarHeight;
  290. if (p->WndTrack)
  291. {
  292. TrackHeight = WinUnitToPixelY(&p->Win,TRACKHEIGHT);
  293. r.bottom -= TrackHeight;
  294. MoveWindow(p->WndTrack,r.left,r.bottom,r.right,TrackHeight,TRUE);
  295. TrackThumb = WinUnitToPixelY(&p->Win,TRACKTHUMB);
  296. if (p->TrackThumb != TrackThumb)
  297. {
  298. p->TrackThumb = TrackThumb; // avoid calling this regulary because it shows the trackbar
  299. SendMessage(p->WndTrack, TBM_SETTHUMBLENGTH,TrackThumb,0);
  300. }
  301. }
  302. if (p->WndTitle)
  303. {
  304. p->TitleTimeWidth = 0;
  305. p->TitleFontSize = TITLEFONT;
  306. p->TitleFont = WinFont(&p->Win,&p->TitleFontSize,0);
  307. p->TitleHeight = WinUnitToPixelY(&p->Win,TITLEHEIGHT);
  308. p->TitleBorder = WinUnitToPixelX(&p->Win,3);
  309. p->TitleWidth = r.right - r.left;
  310. if (Skin) 
  311. {
  312. skinitem* i = &p->Skin[p->SkinNo].Item[SKIN_TITLE];
  313. p->TitleWidth = i->Rect.Width;
  314. p->TitleHeight = i->Rect.Height;
  315. MoveWindow(p->WndTitle,r.left + i->Rect.x,r.top + i->Rect.y,p->TitleWidth,p->TitleHeight,TRUE);
  316. }
  317. else
  318. {
  319. if (p->Win.ToolBarHeight)
  320. {
  321. r.bottom -= p->TitleHeight;
  322. MoveWindow(p->WndTitle,r.left,r.bottom,p->TitleWidth,p->TitleHeight,TRUE);
  323. }
  324. else
  325. {
  326. MoveWindow(p->WndTitle,r.left,r.top,p->TitleWidth,p->TitleHeight,TRUE);
  327. r.top += p->TitleHeight;
  328. }
  329. }
  330. p->TitleTop = (p->TitleHeight-WinUnitToPixelY(&p->Win,p->TitleFontSize))/2;
  331. }
  332. p->SkinArea.x = r.left;
  333. p->SkinArea.y = r.top;
  334. p->SkinArea.Width = r.right - r.left;
  335. p->SkinArea.Height = r.bottom - r.top;
  336. if (!Skin)
  337. p->SkinViewport = p->SkinArea;
  338. else
  339. {
  340. p->SkinViewport = p->Skin[p->SkinNo].Item[SKIN_VIEWPORT].Rect;
  341. p->SkinViewport.x += p->SkinArea.x;
  342. p->SkinViewport.y += p->SkinArea.y;
  343. }
  344. if (p->Win.ToolBarHeight && !p->VolResizeNeeded)
  345. ResizeVolume(p);
  346. }
  347. p->Viewport = p->SkinViewport;
  348. p->Viewport.x += p->Offset.x;
  349. p->Viewport.y += p->Offset.y;
  350. p->Player->Set(p->Player,PLAYER_SKIN_VIEWPORT,&p->Viewport,sizeof(rect));
  351. p->Player->Set(p->Player,PLAYER_UPDATEVIDEO,NULL,0);
  352. if (p->VolResizeNeeded)
  353. {
  354. ResizeVolume(p);
  355. p->VolResizeNeeded = 0;
  356. }
  357. }
  358. }
  359. else
  360. {
  361. GetClientRect(p->Win.Wnd,&r);
  362. p->Viewport.x = r.left + p->Offset.x;
  363. p->Viewport.y = r.top + p->Offset.y;
  364. p->Viewport.Width = r.right - r.left;
  365. p->Viewport.Height = r.bottom - r.top;
  366. }
  367. if (Rotated)
  368. p->Player->Set(p->Player,PLAYER_ROTATEEND,NULL,0);
  369. DEBUG_MSG4(DEBUG_VIDEO,T("Resize end %d,%d,%d,%d"),p->Viewport.x,p->Viewport.y,p->Viewport.Width,p->Viewport.Height);
  370. }
  371. static BOOL CALLBACK EnumCheck(HWND Wnd, LPARAM lParam )
  372. {
  373. intface* p = (intface*) lParam;
  374. RECT r;
  375. if (Wnd == p->Win.Wnd)
  376. return 0;
  377. if (IsWindowVisible(Wnd))
  378. {
  379. GetWindowRect(Wnd,&r);
  380. if (p->Viewport.x < r.right &&
  381. p->Viewport.x + p->Viewport.Width > r.left &&
  382. p->Viewport.y < r.bottom &&
  383. p->Viewport.y + p->Viewport.Height > r.top)
  384. {
  385. p->Overlap = 1;
  386. return 0;
  387. }
  388. }
  389. return 1;
  390. }
  391. static void UpdateHotKey(intface* p,bool_t State,bool_t NoKeep)
  392. {
  393. int i;
  394. if (!p->AllKeys)
  395. {
  396. for (i=0;i<HOTKEYCOUNT;++i)
  397. if (p->HotKey[i])
  398. {
  399. if (State)
  400. {
  401. if (!WinEssentialKey(p->HotKey[i]))
  402. WinRegisterHotKey(&p->Win,HotKey[i],p->HotKey[i]);
  403. }
  404. else
  405. if (NoKeep || !(p->HotKey[i] & HOTKEY_KEEP))
  406. WinUnRegisterHotKey(&p->Win,HotKey[i]);
  407. else
  408. if (WinEssentialKey(p->HotKey[i])) //essential keys -> register in the background
  409. WinRegisterHotKey(&p->Win,HotKey[i],p->HotKey[i]);
  410. }
  411. }
  412. else
  413. {
  414. WinAllKeys(State);
  415. if (!State && !NoKeep)
  416. for (i=0;i<HOTKEYCOUNT;++i)
  417. if (p->HotKey[i] & HOTKEY_KEEP)
  418. WinRegisterHotKey(&p->Win,HotKey[i],p->HotKey[i]);
  419. }
  420. }
  421. static void UpdateSleepTimer(intface* p)
  422. {
  423. #if defined(TARGET_WINCE)
  424. if (p->Play>0 || p->FFwd>0)
  425. {
  426. SleepTimerReset();
  427. SetTimer(p->Win.Wnd,TIMER_SLEEP,SLEEP_CYCLE,NULL);
  428. }
  429. else
  430. KillTimer(p->Win.Wnd,TIMER_SLEEP);
  431. #endif
  432. }
  433. static void UpdateTitleScroll(intface* p)
  434. {
  435. if (p->Focus && p->TitleNameSize < p->TitleNameWidth)
  436. {
  437. if (p->TitleNameOffset >= p->TitleNameWidth - p->TitleNameSize)
  438. p->TitleNameOffset = p->TitleNameWidth - p->TitleNameSize;
  439. SetTimer(p->Win.Wnd,TIMER_TITLESCROLL,TITLESCROLL_CYCLE,NULL);
  440. }
  441. else
  442. {
  443. p->TitleNameOffset = 0;
  444. p->ScrollMode = 0;
  445. KillTimer(p->Win.Wnd,TIMER_TITLESCROLL);
  446. }
  447. }
  448. static void TitleScroll(intface* p)
  449. {
  450. if (p->ScrollMode<TITLESCROLL_WAIT)
  451. ++p->ScrollMode;
  452. else
  453. if (p->ScrollMode==TITLESCROLL_WAIT)
  454. {
  455. p->TitleNameOffset += 3;
  456. if (p->TitleNameOffset >= p->TitleNameWidth - p->TitleNameSize)
  457. {
  458. p->TitleNameOffset = p->TitleNameWidth - p->TitleNameSize;
  459. ++p->ScrollMode;
  460. }
  461. InvalidateRect(p->WndTitle,NULL,1); 
  462. }
  463. else
  464. if (p->ScrollMode<TITLESCROLL_WAIT*2+1)
  465. ++p->ScrollMode;
  466. else
  467. {
  468. p->TitleNameOffset -= 3;
  469. if (p->TitleNameOffset<=0)
  470. {
  471. p->TitleNameOffset=0;
  472. p->ScrollMode = 0;
  473. }
  474. InvalidateRect(p->WndTitle,NULL,1); 
  475. }
  476. UpdateTitleScroll(p);
  477. }
  478. static bool_t ShowVideo(intface* p)
  479. {
  480. bool_t b = p->Focus;
  481. if (!b)
  482. p->Player->Get(p->Player,PLAYER_SHOWINBACKGROUND,&b,sizeof(b));
  483. return b;
  484. }
  485. static void UpdateClippingTimer(intface* p)
  486. {
  487. if (p->Clipping && ShowVideo(p))
  488. SetTimer(p->Win.Wnd,TIMER_CLIPPING,CLIPPING_CYCLE,NULL);
  489. else
  490. KillTimer(p->Win.Wnd,TIMER_CLIPPING);
  491. }
  492. static bool_t IsOverlay(intface* p)
  493. {
  494. bool_t b = 0;
  495. p->Player->Get(p->Player,PLAYER_VIDEO_OVERLAY,&b,sizeof(b));
  496. return b;
  497. }
  498. static bool_t IsOverlapped(intface* p)
  499. {
  500. if (!p->Win.FullScreen || p->Wait)
  501. {
  502. // check for overlapping top-level windows
  503. p->Overlap = 0;
  504. EnumWindows(EnumCheck,(LPARAM)p);
  505. if (p->Overlap)
  506. return 1;
  507. }
  508. return 0;
  509. }
  510. static void UpdateClipping(intface* p,bool_t Suggest,bool_t HotKey)
  511. {
  512. if (p->Clipping != Suggest)
  513. {
  514. KillTimer(p->Win.Wnd,TIMER_CLIPPING2);
  515. if (!Suggest && IsOverlapped(p))
  516. return; // overlapping window -> clipping still needed
  517. p->Clipping = Suggest;
  518. p->Player->Set(p->Player,PLAYER_CLIPPING,&p->Clipping,sizeof(bool_t));
  519. if (HotKey)
  520. UpdateHotKey(p,!p->Clipping,0);
  521. UpdateClippingTimer(p);
  522. }
  523. }
  524. static void RefreshButton(intface* p,int No,bool_t* State,int Id,int Off,int On)
  525. {
  526. int i;
  527. bool_t b;
  528. if (p->Player->Get(p->Player,No,&b,sizeof(b)) != ERR_NONE)
  529. b = -1;
  530. switch (No)
  531. {
  532. case PLAYER_PLAY: i = SKIN_PLAY; break;
  533. case PLAYER_FFWD: i = SKIN_FFWD; break;
  534. case PLAYER_MUTE: i = SKIN_MUTE; break;
  535. case PLAYER_FULLSCREEN: i = SKIN_FULLSCREEN; break;
  536. case PLAYER_REPEAT: i = SKIN_REPEAT; break;
  537. default: i = -1; break;
  538. }
  539. if (i>=0 && p->Skin[p->SkinNo].Item[i].Pushed != b)
  540. {
  541. p->Skin[p->SkinNo].Item[i].Pushed = b;
  542. SkinDrawItem(p->Skin+p->SkinNo,p->Win.Wnd,i,&p->SkinArea);
  543. }
  544. if (State && b != *State)
  545. {
  546. if (b == -1 || *State == -1)
  547. SendMessage(p->Win.WndTB,TB_ENABLEBUTTON,Id,MAKELPARAM(b!=-1,0));
  548. *State = b;
  549. if (b != -1)
  550. {
  551. SendMessage(p->Win.WndTB,TB_CHECKBUTTON,Id,MAKELPARAM(b,0));
  552. if (On>=0)
  553. SendMessage(p->Win.WndTB,TB_CHANGEBITMAP,Id,MAKELPARAM(p->Win.BitmapNo+(b?On:Off),0));
  554. }
  555. }
  556. }
  557. static void SetTrackThumb(HWND Wnd, bool_t State)
  558. {
  559. int Style = GetWindowLong(Wnd,GWL_STYLE);
  560. if ((Style & TBS_NOTHUMB) != (State?0:TBS_NOTHUMB))
  561. {
  562. Style ^= TBS_NOTHUMB;
  563. SetWindowLong(Wnd,GWL_STYLE,Style);
  564. }
  565. }
  566. static void UpdateTitleTime(intface* p)
  567. {
  568. if (p->WndTitle)
  569. {
  570. tick_t Time;
  571. if (p->Player->Get(p->Player,PLAYER_POSITION,&Time,sizeof(tick_t)) == ERR_NONE)
  572. {
  573. Time = (Time / TICKSPERSEC) * TICKSPERSEC;
  574. if (Time<0)
  575. Time=0;
  576. }
  577. else
  578. Time = -1;
  579. if (Time != p->TitleTime)
  580. {
  581. RECT r;
  582. r.left = p->TitleWidth - p->TitleTimeWidth - p->TitleDurWidth - p->TitleBorder;
  583. r.right = r.left + p->TitleTimeWidth;
  584. r.top = 0;
  585. r.bottom = p->TitleHeight;
  586. p->TitleTime = Time;
  587. InvalidateRect(p->WndTitle,&r,0);
  588. }
  589. }
  590. }
  591. static void UpdateMenuBool(intface* p,int MenuId,int Param)
  592. {
  593. bool_t b = 0;
  594. WinMenuEnable(&p->Win,1,MenuId,p->Player->Get(p->Player,Param,&b,sizeof(b)) != ERR_NOT_SUPPORTED);
  595. WinMenuCheck(&p->Win,1,MenuId,b);
  596. }
  597. static void UpdateMenuInt(intface* p,int MenuId,int Param,int Value)
  598. {
  599. int v = 0;
  600. WinMenuEnable(&p->Win,1,MenuId,p->Player->Get(p->Player,Param,&v,sizeof(v)) != ERR_NOT_SUPPORTED);
  601. WinMenuCheck(&p->Win,1,MenuId,v==Value);
  602. }
  603. static void UpdateMenuFrac(intface* p,int MenuId,int Param,int Num,int Den)
  604. {
  605. fraction f = {0,0};
  606. WinMenuEnable(&p->Win,1,MenuId,p->Player->Get(p->Player,Param,&f,sizeof(f)) != ERR_NOT_SUPPORTED);
  607. WinMenuCheck(&p->Win,1,MenuId,f.Num*Den==f.Den*Num);
  608. }
  609. static void UpdateMenu(intface* p)
  610. {
  611. packetformat PacketFormat;
  612. node* AOutput;
  613. bool_t Stereo;
  614. bool_t b;
  615. int* i;
  616. int No,Id;
  617. int PreAmp;
  618. bool_t Accel;
  619. tchar_t Name[20+1];
  620. int ACurrent = -1;
  621. int VCurrent = -1;
  622. int SubCurrent = -1;
  623. // remove old chapters
  624. if (!WinMenuEnable(&p->Win,0,IF_FILE_CHAPTERS_NONE,0))
  625. {
  626. WinMenuInsert(&p->Win,0,IF_CHAPTER+1,IF_FILE_CHAPTERS_NONE,LangStr(INTERFACE_ID,IF_FILE_CHAPTERS_NONE));
  627. for (No=1;No<MAXCHAPTER;++No)
  628. if (!WinMenuDelete(&p->Win,0,IF_CHAPTER+No))
  629. break;
  630. }
  631. // add new chapters
  632. for (No=1;No<MAXCHAPTER && PlayerGetChapter(p->Player,No,Name,TSIZEOF(Name))>=0;++No)
  633. WinMenuInsert(&p->Win,0,IF_FILE_CHAPTERS_NONE,IF_CHAPTER+No,Name);
  634. if (No>1)
  635. WinMenuDelete(&p->Win,0,IF_FILE_CHAPTERS_NONE);
  636. else
  637. WinMenuEnable(&p->Win,0,IF_FILE_CHAPTERS_NONE,0);
  638. // remove old streams
  639. if (p->MenuVStream >= 0)
  640. {
  641. WinMenuInsert(&p->Win,1,p->MenuVStream,IF_OPTIONS_VIDEO_STREAM_NONE, LangStr(INTERFACE_ID,IF_OPTIONS_VIDEO_STREAM_NONE));
  642. for (No=0;No<p->MenuStreams;++No)
  643. WinMenuDelete(&p->Win,1,IF_STREAM_VIDEO+No);
  644. }
  645. if (p->MenuAStream >= 0)
  646. {
  647. WinMenuInsert(&p->Win,1,p->MenuAStream,IF_OPTIONS_AUDIO_STREAM_NONE, LangStr(INTERFACE_ID,IF_OPTIONS_AUDIO_STREAM_NONE));
  648. for (No=0;No<p->MenuStreams;++No)
  649. WinMenuDelete(&p->Win,1,IF_STREAM_AUDIO+No);
  650. }
  651. if (p->MenuSubStream >= 0)
  652. for (No=0;No<p->MenuStreams;++No)
  653. WinMenuDelete(&p->Win,1,IF_STREAM_SUBTITLE+No);
  654. // add new streams
  655. p->MenuStreams = 0;
  656. p->MenuAStream = -1;
  657. p->MenuVStream = -1;
  658. p->MenuSubStream = -1;
  659. for (No=0;PlayerGetStream(p->Player,No,&PacketFormat,Name,TSIZEOF(Name),NULL);++No)
  660. switch (PacketFormat.Type)
  661. {
  662. case PACKET_VIDEO:
  663. p->MenuVStream = IF_STREAM_VIDEO+No;
  664. WinMenuInsert(&p->Win,1,IF_OPTIONS_VIDEO_STREAM_NONE,IF_STREAM_VIDEO+No,Name);
  665. break;
  666. case PACKET_AUDIO:
  667. p->MenuAStream = IF_STREAM_AUDIO+No;
  668. WinMenuInsert(&p->Win,1,IF_OPTIONS_AUDIO_STREAM_NONE,IF_STREAM_AUDIO+No,Name);
  669. break;
  670. case PACKET_SUBTITLE:
  671. p->MenuSubStream = IF_STREAM_SUBTITLE+No;
  672. WinMenuInsert(&p->Win,1,IF_OPTIONS_SUBTITLE_STREAM_NONE,IF_STREAM_SUBTITLE+No,Name);
  673. break;
  674. }
  675. p->MenuStreams = No;
  676. p->Player->Get(p->Player,PLAYER_VSTREAM,&VCurrent,sizeof(int));
  677. p->Player->Get(p->Player,PLAYER_ASTREAM,&ACurrent,sizeof(int));
  678. p->Player->Get(p->Player,PLAYER_SUBSTREAM,&SubCurrent,sizeof(int));
  679. if (p->MenuVStream<0)
  680. WinMenuEnable(&p->Win,1,IF_OPTIONS_VIDEO_STREAM_NONE,0);
  681. else
  682. {
  683. WinMenuCheck(&p->Win,1,IF_STREAM_VIDEO+VCurrent,1);
  684. WinMenuDelete(&p->Win,1,IF_OPTIONS_VIDEO_STREAM_NONE);
  685. }
  686. if (p->MenuAStream<0)
  687. WinMenuEnable(&p->Win,1,IF_OPTIONS_AUDIO_STREAM_NONE,0);
  688. else
  689. {
  690. WinMenuCheck(&p->Win,1,IF_STREAM_AUDIO+ACurrent,1);
  691. WinMenuDelete(&p->Win,1,IF_OPTIONS_AUDIO_STREAM_NONE);
  692. }
  693. if (SubCurrent >= MAXSTREAM) 
  694. SubCurrent = -1;
  695. WinMenuEnable(&p->Win,1,IF_OPTIONS_SUBTITLE_STREAM_NONE,p->MenuSubStream>=0);
  696. WinMenuCheck(&p->Win,1,IF_OPTIONS_SUBTITLE_STREAM_NONE,SubCurrent<0);
  697. if (SubCurrent>=0)
  698. WinMenuCheck(&p->Win,1,IF_STREAM_SUBTITLE+SubCurrent,1);
  699. UpdateMenuFrac(p,IF_OPTIONS_ASPECT_AUTO,PLAYER_ASPECT,0,1);
  700. UpdateMenuFrac(p,IF_OPTIONS_ASPECT_SQUARE,PLAYER_ASPECT,1,1);
  701. UpdateMenuFrac(p,IF_OPTIONS_ASPECT_4_3_SCREEN,PLAYER_ASPECT,-4,3);
  702. UpdateMenuFrac(p,IF_OPTIONS_ASPECT_4_3_NTSC,PLAYER_ASPECT,10,11);
  703. UpdateMenuFrac(p,IF_OPTIONS_ASPECT_4_3_PAL,PLAYER_ASPECT,12,11);
  704. UpdateMenuFrac(p,IF_OPTIONS_ASPECT_16_9_SCREEN,PLAYER_ASPECT,-16,9);
  705. UpdateMenuFrac(p,IF_OPTIONS_ASPECT_16_9_NTSC,PLAYER_ASPECT,40,33);
  706. UpdateMenuFrac(p,IF_OPTIONS_ASPECT_16_9_PAL,PLAYER_ASPECT,16,11);
  707. UpdateMenuFrac(p,IF_OPTIONS_ZOOM_FIT_SCREEN,PLAYER_FULL_ZOOM,0,1);
  708. UpdateMenuFrac(p,IF_OPTIONS_ZOOM_FIT_110,PLAYER_FULL_ZOOM,-11,10);
  709. UpdateMenuFrac(p,IF_OPTIONS_ZOOM_FIT_120,PLAYER_FULL_ZOOM,-12,10);
  710. UpdateMenuFrac(p,IF_OPTIONS_ZOOM_FIT_130,PLAYER_FULL_ZOOM,-13,10);
  711. UpdateMenuFrac(p,IF_OPTIONS_ZOOM_FILL_SCREEN,PLAYER_FULL_ZOOM,-4,SCALE_ONE);
  712. UpdateMenuFrac(p,IF_OPTIONS_ZOOM_STRETCH_SCREEN,PLAYER_FULL_ZOOM,-3,SCALE_ONE);
  713. UpdateMenuFrac(p,IF_OPTIONS_ZOOM_50,PLAYER_FULL_ZOOM,1,2);
  714. UpdateMenuFrac(p,IF_OPTIONS_ZOOM_100,PLAYER_FULL_ZOOM,1,1);
  715. UpdateMenuFrac(p,IF_OPTIONS_ZOOM_150,PLAYER_FULL_ZOOM,3,2);
  716. UpdateMenuFrac(p,IF_OPTIONS_ZOOM_200,PLAYER_FULL_ZOOM,2,1);
  717. UpdateMenuBool(p,IF_OPTIONS_VIDEO_ZOOM_SMOOTH50,PLAYER_SMOOTH50);
  718. UpdateMenuBool(p,IF_OPTIONS_VIDEO_ZOOM_SMOOTHALWAYS,PLAYER_SMOOTHALWAYS);
  719. WinMenuCheck(&p->Win,1,IF_OPTIONS_VIEW_TITLEBAR,p->TitleBar);
  720. WinMenuCheck(&p->Win,1,IF_OPTIONS_VIEW_TRACKBAR,p->TrackBar);
  721. WinMenuCheck(&p->Win,1,IF_OPTIONS_VIEW_TASKBAR,p->TaskBar);
  722. //UpdateMenuInt(p,IF_OPTIONS_AUDIO_QUALITY_LOW,PLAYER_AUDIO_QUALITY,0);
  723. //UpdateMenuInt(p,IF_OPTIONS_AUDIO_QUALITY_MEDIUM,PLAYER_AUDIO_QUALITY,1);
  724. //UpdateMenuInt(p,IF_OPTIONS_AUDIO_QUALITY_HIGH,PLAYER_AUDIO_QUALITY,2);
  725. if (p->Player->Get(p->Player,PLAYER_PREAMP,&PreAmp,sizeof(PreAmp)) != ERR_NONE)
  726. PreAmp = 0;
  727. if (PreAmp != p->MenuPreAmp)
  728. {
  729. p->MenuPreAmp = PreAmp;
  730. stprintf_s(Name,TSIZEOF(Name),LangStr(INTERFACE_ID,IF_OPTIONS_AUDIO_PREAMP),PreAmp);
  731. WinMenuDelete(&p->Win,1,IF_OPTIONS_AUDIO_PREAMP);
  732. WinMenuInsert(&p->Win,1,IF_OPTIONS_AUDIO_PREAMP_INC,IF_OPTIONS_AUDIO_PREAMP,Name);
  733. }
  734. UpdateMenuInt(p,IF_OPTIONS_VIDEO_QUALITY_LOWEST,PLAYER_VIDEO_QUALITY,0);
  735. UpdateMenuInt(p,IF_OPTIONS_VIDEO_QUALITY_LOW,PLAYER_VIDEO_QUALITY,1);
  736. UpdateMenuInt(p,IF_OPTIONS_VIDEO_QUALITY_NORMAL,PLAYER_VIDEO_QUALITY,2);
  737. UpdateMenuInt(p,IF_OPTIONS_ROTATE_GUI,PLAYER_FULL_DIR,-1);
  738. UpdateMenuInt(p,IF_OPTIONS_ROTATE_0,PLAYER_FULL_DIR,0);
  739. UpdateMenuInt(p,IF_OPTIONS_ROTATE_90,PLAYER_FULL_DIR,DIR_SWAPXY | DIR_MIRRORLEFTRIGHT);
  740. UpdateMenuInt(p,IF_OPTIONS_ROTATE_270,PLAYER_FULL_DIR,DIR_SWAPXY | DIR_MIRRORUPDOWN);
  741. UpdateMenuInt(p,IF_OPTIONS_ROTATE_180,PLAYER_FULL_DIR,DIR_MIRRORUPDOWN | DIR_MIRRORLEFTRIGHT);
  742. UpdateMenuFrac(p,IF_OPTIONS_SPEED_10,PLAYER_PLAY_SPEED,1,10);
  743. UpdateMenuFrac(p,IF_OPTIONS_SPEED_25,PLAYER_PLAY_SPEED,1,4);
  744. UpdateMenuFrac(p,IF_OPTIONS_SPEED_50,PLAYER_PLAY_SPEED,1,2);
  745. UpdateMenuFrac(p,IF_OPTIONS_SPEED_80,PLAYER_PLAY_SPEED,8,10);
  746. UpdateMenuFrac(p,IF_OPTIONS_SPEED_90,PLAYER_PLAY_SPEED,9,10);
  747. UpdateMenuFrac(p,IF_OPTIONS_SPEED_100,PLAYER_PLAY_SPEED,1,1);
  748. UpdateMenuFrac(p,IF_OPTIONS_SPEED_110,PLAYER_PLAY_SPEED,11,10);
  749. UpdateMenuFrac(p,IF_OPTIONS_SPEED_120,PLAYER_PLAY_SPEED,12,10);
  750. UpdateMenuFrac(p,IF_OPTIONS_SPEED_150,PLAYER_PLAY_SPEED,3,2);
  751. UpdateMenuFrac(p,IF_OPTIONS_SPEED_200,PLAYER_PLAY_SPEED,2,1);
  752. UpdateMenuFrac(p,IF_OPTIONS_SPEED_BENCHMARK,PLAYER_PLAY_SPEED,0,1);
  753. UpdateMenuBool(p,IF_PLAY,PLAYER_PLAY);
  754. WinMenuEnable(&p->Win,1,IF_OPTIONS_VIDEO_DITHER,p->Color->Get(p->Color,COLOR_DITHER,&b,sizeof(b)) != ERR_NOT_SUPPORTED);
  755. WinMenuCheck(&p->Win,1,IF_OPTIONS_VIDEO_DITHER,b);
  756. UpdateMenuInt(p,IF_OPTIONS_AUDIO_STEREO,PLAYER_STEREO,STEREO_NORMAL);
  757. UpdateMenuInt(p,IF_OPTIONS_AUDIO_STEREO_SWAPPED,PLAYER_STEREO,STEREO_SWAPPED);
  758. UpdateMenuInt(p,IF_OPTIONS_AUDIO_STEREO_JOINED,PLAYER_STEREO,STEREO_JOINED);
  759. UpdateMenuInt(p,IF_OPTIONS_AUDIO_STEREO_LEFT,PLAYER_STEREO,STEREO_LEFT);
  760. UpdateMenuInt(p,IF_OPTIONS_AUDIO_STEREO_RIGHT,PLAYER_STEREO,STEREO_RIGHT);
  761. UpdateMenuBool(p,IF_OPTIONS_FULLSCREEN,PLAYER_FULLSCREEN);
  762. UpdateMenuBool(p,IF_OPTIONS_REPEAT,PLAYER_REPEAT);
  763. UpdateMenuBool(p,IF_OPTIONS_SHUFFLE,PLAYER_SHUFFLE);
  764. p->Equalizer->Get(p->Equalizer,EQUALIZER_ENABLED,&b,sizeof(b));
  765. WinMenuCheck(&p->Win,1,IF_OPTIONS_EQUALIZER,b);
  766. p->Player->Get(p->Player,PLAYER_VIDEO_ACCEL,&Accel,sizeof(Accel));
  767. p->Player->Get(p->Player,PLAYER_VOUTPUTID,&Id,sizeof(Id));
  768. WinMenuCheck(&p->Win,1,IF_OPTIONS_VIDEO_TURNOFF,!Id);
  769. for (No=0,i=ARRAYBEGIN(p->VOutput,int);i!=ARRAYEND(p->VOutput,int);++i,++No)
  770. {
  771. WinMenuCheck(&p->Win,1,IF_VIDEO+No,*i==Id && !Accel);
  772. WinMenuCheck(&p->Win,1,IF_VIDEOACCEL+No,*i==Id && Accel);
  773. }
  774. p->Player->Get(p->Player,PLAYER_AOUTPUTID,&Id,sizeof(Id));
  775. WinMenuCheck(&p->Win,1,IF_OPTIONS_AUDIO_TURNOFF,!Id);
  776. for (No=0,i=ARRAYBEGIN(p->AOutput,int);i!=ARRAYEND(p->AOutput,int);++i,++No)
  777. WinMenuCheck(&p->Win,1,IF_AUDIO+No,*i==Id);
  778. Stereo = 1;
  779. p->Player->Get(p->Player,PLAYER_AOUTPUT,&AOutput,sizeof(AOutput));
  780. if (AOutput && AOutput->Get(AOutput,OUT_INPUT|PIN_FORMAT,&PacketFormat,sizeof(PacketFormat))==ERR_NONE && 
  781. PacketFormat.Type == PACKET_AUDIO && PacketFormat.Format.Audio.Channels<2)
  782. Stereo = 0;
  783. WinMenuEnable(&p->Win,1,IF_OPTIONS_AUDIO_STEREO,Stereo);
  784. WinMenuEnable(&p->Win,1,IF_OPTIONS_AUDIO_STEREO_SWAPPED,Stereo);
  785. WinMenuEnable(&p->Win,1,IF_OPTIONS_AUDIO_STEREO_JOINED,Stereo);
  786. WinMenuEnable(&p->Win,1,IF_OPTIONS_AUDIO_STEREO_LEFT,Stereo);
  787. WinMenuEnable(&p->Win,1,IF_OPTIONS_AUDIO_STEREO_RIGHT,Stereo);
  788. }
  789. static void UpdatePosition(intface* p);
  790. static int Delta(intface* p,node* Node,int Param,int d,int Min,int Max)
  791. {
  792. int State;
  793. if (Node && Node->Get(Node,Param,&State,sizeof(State))==ERR_NONE)
  794. {
  795. State += d;
  796. if (State < Min)
  797. State = Min;
  798. if (State > Max)
  799. State = Max;
  800. Node->Set(Node,Param,&State,sizeof(State));
  801. if (Param == PLAYER_VOLUME)
  802. {
  803. if (State > Min) Toggle(p,PLAYER_MUTE,0);
  804. UpdateVolume(p);
  805. }
  806. }
  807. return State;
  808. }
  809. static bool_t IsCoverAtr(player *Player)
  810. {
  811. node* Format;
  812. int CoverArt;
  813. int VStream;
  814. return Player->Get(Player,PLAYER_FORMAT,&Format,sizeof(Format))==ERR_NONE && Format &&
  815. Format->Get(Format,FORMAT_COVERART,&CoverArt,sizeof(CoverArt))==ERR_NONE &&
  816. Player->Get(Player,PLAYER_VSTREAM,&VStream,sizeof(VStream))==ERR_NONE && VStream==CoverArt;
  817. }
  818. static bool_t ToggleFullScreen(intface* p,int Force,int CoverArtFullScreen)
  819. {
  820. bool_t State = 0;
  821. if (p->Player->Get(p->Player,PLAYER_FULLSCREEN,&State,sizeof(State))==ERR_NONE)
  822. {
  823. node* VOutput;
  824. bool_t Primary;
  825. packetformat Format;
  826. if (State==Force)
  827. return State;
  828. State = !State;
  829. if (p->Player->Get(p->Player,PLAYER_VOUTPUT,&VOutput,sizeof(VOutput))!=ERR_NONE ||
  830. !VOutput ||
  831. VOutput->Get(VOutput,VOUT_PRIMARY,&Primary,sizeof(Primary))!=ERR_NONE || !Primary ||
  832. (!CoverArtFullScreen && IsCoverAtr(p->Player)) ||
  833. (!p->ForceFullScreen && VOutput->Get(VOutput,OUT_INPUT|PIN_FORMAT,&Format,sizeof(Format))!=ERR_NONE) ||
  834. (!p->ForceFullScreen && !Format.Format.Video.Width))
  835. State = 0;
  836. UpdatePosition(p); // before returning from fullscreen
  837. if (!State)
  838. {
  839. p->Player->Set(p->Player,PLAYER_FULLSCREEN,&State,sizeof(State));
  840. p->Player->Set(p->Player,PLAYER_UPDATEVIDEO,NULL,0);
  841. RefreshButton(p,PLAYER_FULLSCREEN,&p->FullScreen,IF_OPTIONS_FULLSCREEN,-1,-1);
  842. }
  843. if (p->Skin[p->SkinNo].Valid) p->Skin[p->SkinNo].Hidden = State;
  844. if (p->WndTrack) ShowWindow(p->WndTrack,State ? SW_HIDE:SW_SHOWNA);
  845. if (p->WndTitle) ShowWindow(p->WndTitle,State ? SW_HIDE:SW_SHOWNA);
  846. WinSetFullScreen(&p->Win,State);
  847. if (p->Win.WndTB) UpdateWindow(p->Win.WndTB);
  848. ShowVol(p,!State); // called after WinSetFullScreen so TOPMOST is over taskbar
  849. if (State)
  850. {
  851. p->Player->Set(p->Player,PLAYER_FULLSCREEN,&State,sizeof(State));
  852. p->Player->Set(p->Player,PLAYER_UPDATEVIDEO,NULL,0);
  853. RefreshButton(p,PLAYER_FULLSCREEN,&p->FullScreen,IF_OPTIONS_FULLSCREEN,-1,-1);
  854. }
  855. }
  856. return State;
  857. }
  858. static bool_t Toggle(intface* p,int Param,int Force)
  859. {
  860. bool_t State = 0;
  861. if (p->Player->Get(p->Player,Param,&State,sizeof(State))==ERR_NONE)
  862. {
  863. assert(Param != PLAYER_FULLSCREEN);
  864. if (State==Force)
  865. return State;
  866. State = !State;
  867. p->Player->Set(p->Player,Param,&State,sizeof(State));
  868. if (Param == PLAYER_PLAY)
  869. RefreshButton(p,PLAYER_PLAY,&p->Play,IF_PLAY,0,1);
  870. else
  871. if (Param == PLAYER_FFWD)
  872. RefreshButton(p,PLAYER_FFWD,&p->FFwd,IF_FASTFORWARD,4,1);
  873. else
  874. RefreshButton(p,Param,NULL,0,0,0);
  875. }
  876. return State;
  877. }
  878. static bool_t IsAutoRun(intface* p, const tchar_t* CmdLine)
  879. {
  880. while (IsSpace(*CmdLine))
  881. ++CmdLine;
  882. return tcsnicmp(CmdLine,T("-autorun"),8)==0;
  883. }
  884. static void EnumDir(const tchar_t* Path,const tchar_t* Exts,player* Player)
  885. {
  886. streamdir DirItem;
  887. stream* Stream = GetStream(Path,1);
  888. if (Stream)
  889. {
  890. int Result = Stream->EnumDir(Stream,Path,Exts,1,&DirItem);
  891. while (Result == ERR_NONE)
  892. {
  893. tchar_t FullPath[MAXPATH];
  894. AbsPath(FullPath,TSIZEOF(FullPath),DirItem.FileName,Path);
  895. if (DirItem.Size < 0)
  896. EnumDir(FullPath,Exts,Player);
  897. else
  898. if (DirItem.Type == FTYPE_AUDIO || DirItem.Type == FTYPE_VIDEO)
  899. {
  900. int n;
  901. Player->Get(Player,PLAYER_LIST_COUNT,&n,sizeof(n));
  902. Player->Set(Player,PLAYER_LIST_URL+n,FullPath,sizeof(FullPath));
  903. }
  904. Result = Stream->EnumDir(Stream,NULL,NULL,0,&DirItem);
  905. }
  906. NodeDelete((node*)Stream);
  907. }
  908. }
  909. void ProcessCmdLine( intface* p, const tchar_t* CmdLine)
  910. {
  911. int n;
  912. tchar_t URL[MAXPATH];
  913. if (IsAutoRun(p,CmdLine))
  914. {
  915. // search for media files on SD card
  916. tchar_t Base[MAXPATH];
  917. int* i;
  918. array List;
  919. tchar_t* s;
  920. int ExtsLen = 1024;
  921. tchar_t* Exts = malloc(ExtsLen*sizeof(tchar_t));
  922. if (!Exts)
  923. return;
  924. Exts[0]=0;
  925. NodeEnumClass(&List,FORMAT_CLASS);
  926. for (i=ARRAYBEGIN(List,int);i!=ARRAYEND(List,int);++i)
  927. {
  928. const tchar_t* s = LangStr(*i,NODE_EXTS);
  929. if (s[0])
  930. {
  931. if (Exts[0]) tcscat_s(Exts,ExtsLen,T(";"));
  932. tcscat_s(Exts,ExtsLen,s);
  933. }
  934. }
  935. ArrayClear(&List);
  936. n = 0;
  937. p->Player->Set(p->Player,PLAYER_LIST_COUNT,&n,sizeof(n));
  938. GetModuleFileName(GetModuleHandle(NULL),Base,MAXPATH);
  939. s = tcsrchr(Base,'\');
  940. if (s) *s=0;
  941. s = tcsrchr(Base,'\');
  942. if (s) *s=0;
  943. EnumDir(Base,Exts,p->Player);
  944. free(Exts);
  945. }
  946. else
  947. {
  948. while (IsSpace(*CmdLine))
  949. ++CmdLine;
  950. if (*CmdLine == '"')
  951. {
  952. tchar_t* ch = tcschr(++CmdLine,'"');
  953. if (ch) *ch=0;
  954. }
  955. tcscpy_s(URL,TSIZEOF(URL),CmdLine);
  956. p->CmdLineMode = 1;
  957. n = 1;
  958. p->Player->Set(p->Player,PLAYER_LIST_COUNT,&n,sizeof(n));
  959. PlayerAdd(p->Player,0,URL,NULL);
  960. }
  961. n = 0;
  962. p->Player->Set(p->Player,PLAYER_LIST_CURRIDX,&n,sizeof(n));
  963. if (!IsWindowEnabled(p->Win.Wnd))
  964. Toggle(p,PLAYER_PLAY,0);
  965. }
  966. void SetTrackPos(intface* p,int x)
  967. {
  968. fraction Percent;
  969. RECT r,rt;
  970. int Adj;
  971. if (p->TrackSetPos == x)
  972. return;
  973. p->TrackSetPos = x;
  974. SendMessage(p->WndTrack,TBM_GETCHANNELRECT,0,(LONG)&r);
  975. SendMessage(p->WndTrack,TBM_GETTHUMBRECT,0,(LONG)&rt);
  976. Adj = (rt.right-rt.left) >> 1;
  977. r.left += Adj;
  978. r.right -= (rt.right-rt.left)-Adj;
  979. if (x > 32768) x -= 65536;
  980. if (r.right <= r.left) r.right = r.left+1;
  981. if (x < r.left) x = r.left;
  982. if (x > r.right) x = r.right;
  983. x = Scale(TRACKMAX,x-r.left,r.right-r.left);
  984. Percent.Num = x;
  985. Percent.Den = TRACKMAX;
  986. p->Player->Set(p->Player,PLAYER_PERCENT,&Percent,sizeof(Percent));
  987. }
  988. LRESULT CALLBACK TitleProc(HWND WndTitle, UINT Msg, WPARAM wParam, LPARAM lParam)
  989. {
  990. intface* p = (intface*) WinGetObject(WndTitle);
  991. if (p)
  992. {
  993. PAINTSTRUCT Paint;
  994. RECT r;
  995. tchar_t Time[32];
  996. switch (Msg)
  997. {
  998. case WM_ERASEBKGND:
  999. GetClientRect(WndTitle,&r);
  1000. FillRect((HDC)wParam,&r,p->TitleBrush ? p->TitleBrush:GetSysColorBrush(COLOR_BTNFACE));
  1001. break;
  1002. case WM_SIZE:
  1003. p->UpdateScroll = 1;
  1004. break;
  1005. case WM_LBUTTONDOWN:
  1006. break;
  1007. case WM_MOUSEMOVE:
  1008. break;
  1009. case WM_LBUTTONUP:
  1010. break;
  1011. case WM_PAINT:
  1012. BeginPaint(WndTitle,&Paint);
  1013. SelectObject(Paint.hdc,p->TitleFont);
  1014. SetBkColor(Paint.hdc,p->TitleFace);
  1015. SetTextColor(Paint.hdc,p->TitleText);
  1016. #if !defined(TARGET_WINCE)
  1017. SetTextAlign(Paint.hdc,TA_LEFT);
  1018. #endif
  1019. if (!p->TitleTimeWidth)
  1020. {
  1021. SIZE Size;
  1022. tchar_t* s;
  1023. tchar_t Dur[32];
  1024. tick_t Duration;
  1025. tchar_t TitleName[256];
  1026. node* Format;
  1027. if (p->Player->Get(p->Player,PLAYER_FORMAT,&Format,sizeof(Format)) == ERR_NONE && !Format)
  1028. p->TitleTime = -1;
  1029. p->Player->Get(p->Player,PLAYER_TITLE,TitleName,sizeof(TitleName));
  1030. if (tcscmp(p->TitleName,TitleName)!=0)
  1031. {
  1032. tcscpy_s(p->TitleName,TSIZEOF(p->TitleName),TitleName);
  1033. GetTextExtentPoint(Paint.hdc,p->TitleName,tcslen(p->TitleName),&Size);
  1034. p->TitleNameWidth = Size.cx;
  1035. p->TitleNameOffset = 0;
  1036. p->ScrollMode = 0;
  1037. p->UpdateScroll = 1;
  1038. }
  1039. s = Dur;
  1040. Dur[0] = 0;
  1041. if (p->Player->Get(p->Player,PLAYER_DURATION,&Duration,sizeof(Duration)) == ERR_NONE && Duration>=0)
  1042. {
  1043. TickToString(Dur,TSIZEOF(Dur),Duration,0,0,1);
  1044. if (p->TitleTime<0)
  1045. p->TitleTime = 0;
  1046. }
  1047. else
  1048. s = T("0:00:00");
  1049. GetTextExtentPoint(Paint.hdc,s,tcslen(s),&Size);
  1050. p->TitleTimeWidth = Size.cx;
  1051. p->TitleDurWidth = 0;
  1052. p->TitleDur[0] = 0;
  1053. if (Dur[0])
  1054. {
  1055. stprintf_s(p->TitleDur,TSIZEOF(p->TitleDur),T("/%s"),Dur);
  1056. GetTextExtentPoint(Paint.hdc,p->TitleDur,tcslen(p->TitleDur),&Size);
  1057. p->TitleDurWidth = Size.cx;
  1058. p->UpdateScroll = 1;
  1059. }
  1060. }
  1061. if (p->TitleTime>=0)
  1062. TickToString(Time,TSIZEOF(Time),p->TitleTime,0,0,1);
  1063. else
  1064. Time[0] = 0;
  1065. r.top = p->TitleTop;
  1066. r.bottom = p->TitleHeight - p->TitleTop;
  1067. r.left = p->TitleBorder;
  1068. r.right = p->TitleWidth - p->TitleTimeWidth - p->TitleDurWidth - p->TitleBorder * 2;
  1069. p->TitleNameSize  = r.right - r.left;
  1070. if (p->UpdateScroll)
  1071. {
  1072. p->UpdateScroll = 0;
  1073. UpdateTitleScroll(p);
  1074. }
  1075. ExtTextOut(Paint.hdc,r.left-p->TitleNameOffset,r.top,ETO_CLIPPED,&r,p->TitleName,tcslen(p->TitleName),NULL);
  1076. r.left = r.right + p->TitleBorder;
  1077. r.right = r.left + p->TitleTimeWidth;
  1078. //SetBkColor(Paint.hdc,0xFFFFFF);
  1079. ExtTextOut(Paint.hdc,r.left,r.top,ETO_CLIPPED|ETO_OPAQUE,&r,Time,tcslen(Time),NULL);
  1080. //SetBkColor(Paint.hdc,0x00FF00);
  1081. if (p->TitleDurWidth)
  1082. {
  1083. r.left = r.right;
  1084. r.right = r.left + p->TitleDurWidth;
  1085. ExtTextOut(Paint.hdc,r.left,r.top,ETO_CLIPPED,&r,p->TitleDur,tcslen(p->TitleDur),NULL);
  1086. }
  1087. EndPaint(WndTitle,&Paint);
  1088. break;
  1089. }
  1090. }
  1091. return DefWindowProc(WndTitle,Msg,wParam,lParam);
  1092. }
  1093. static void SetKeyInSeek(intface* p)
  1094. {
  1095. bool_t First = !p->InSeek;
  1096. p->InSeek = 1;
  1097. p->Player->Set(p->Player,PLAYER_INSEEK,&p->InSeek,sizeof(p->InSeek));
  1098. SetTimer(p->Win.Wnd,TIMER_KEYINSEEK,First?KEYINSEEK_START:KEYINSEEK_REPEAT,NULL);
  1099. }
  1100. static void StopSeek(intface* p)
  1101. {
  1102. p->InSeek = 0;
  1103. p->Player->Set(p->Player,PLAYER_INSEEK,&p->InSeek,sizeof(p->InSeek));
  1104. KillTimer(p->Win.Wnd,TIMER_KEYINSEEK);
  1105. if (p->Capture)
  1106. {
  1107. ReleaseCapture();
  1108. p->Capture = 0;
  1109. KillTimer(p->Win.Wnd,TIMER_SLIDERINSEEK);
  1110. }
  1111. }
  1112. LRESULT CALLBACK TrackProc(HWND WndTrack, UINT Msg, WPARAM wParam, LPARAM lParam)
  1113. {
  1114. intface* p = (intface*) WinGetObject(WndTrack);
  1115. if (Msg == WM_LBUTTONDOWN)
  1116. {
  1117. p->InSeek = 1;
  1118. p->Capture = 1;
  1119. p->TrackSetPos = -1;
  1120. p->Player->Set(p->Player,PLAYER_INSEEK,&p->InSeek,sizeof(p->InSeek));
  1121. SetTrackPos(p,LOWORD(lParam));
  1122. SetCapture(WndTrack);
  1123. SetTimer(p->Win.Wnd,TIMER_SLIDERINSEEK,SLIDERINSEEK_CYCLE,NULL);
  1124. return 0;
  1125. }
  1126. if (Msg == WM_MOUSEMOVE)
  1127. {
  1128. if (p->InSeek && (wParam & MK_LBUTTON))
  1129. SetTrackPos(p,LOWORD(lParam));
  1130. return 0;
  1131. }
  1132. if (Msg == WM_LBUTTONUP)
  1133. {
  1134. if (p->InSeek)
  1135. {
  1136. SetTrackPos(p,LOWORD(lParam));
  1137. StopSeek(p);
  1138. }
  1139. return 0;
  1140. }
  1141. return CallWindowProc(p->DefTrackProc,WndTrack,Msg,wParam,lParam);
  1142. }
  1143. void UpdateVol(intface* p)
  1144. {
  1145. if (p->Vol >= 0)
  1146. {
  1147. SendMessage(p->WndVol,TBM_SETPOS,1,p->Vol);
  1148. p->Player->Set(p->Player,PLAYER_VOLUME,&p->Vol,sizeof(p->Vol));
  1149. p->Vol = -1;
  1150. if (p->Skin[p->SkinNo].Valid)
  1151. SkinUpdate(&p->Skin[p->SkinNo],p->Player,p->Win.Wnd,&p->SkinArea);
  1152. }
  1153. }
  1154. void SetVolPos(intface* p,int x)
  1155. {
  1156. RECT r;
  1157. int Adj;
  1158. SendMessage(p->WndVol,TBM_GETCHANNELRECT,0,(LONG)&r);
  1159. Adj = WinUnitToPixelX(&p->Win,VOLTHUMB)/4;
  1160. r.left += Adj;
  1161. r.right -= Adj;
  1162. if (x > 32768) x -= 65536;
  1163. if (r.right <= r.left) r.right = r.left+1;
  1164. if (x < r.left) x = r.left;
  1165. if (x > r.right) x = r.right;
  1166. p->Vol = (100*(x-r.left))/(r.right-r.left);
  1167. }
  1168. LRESULT CALLBACK VolBackProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  1169. {
  1170. //DEBUG_MSG1(DEBUG_WIN,T("MSG %04x"),Msg);
  1171. switch (Msg)
  1172. {
  1173. #if defined(TARGET_WINCE)
  1174. case WM_CTLCOLORSTATIC:
  1175. return (LRESULT) GetSysColorBrush(COLOR_BTNFACE);
  1176. #endif
  1177. }
  1178. return DefWindowProc(Wnd,Msg,wParam,lParam);
  1179. }
  1180. LRESULT CALLBACK VolProc(HWND WndVol, UINT Msg, WPARAM wParam, LPARAM lParam)
  1181. {
  1182. intface* p = (intface*) WinGetObject(WndVol);
  1183. switch (Msg)
  1184. {
  1185. case WM_MOUSEMOVE:
  1186. if ((wParam & MK_LBUTTON)==0)
  1187. break;
  1188. case WM_LBUTTONDOWN:
  1189. case WM_LBUTTONDBLCLK:
  1190. SetVolPos(p,LOWORD(lParam));
  1191. if (!p->InVol)
  1192. {
  1193. p->InVol = 1;
  1194. SetForegroundWindow(p->Win.Wnd);
  1195. SetCapture(WndVol);
  1196. SetTimer(p->Win.Wnd,TIMER_SLIDERINVOL,SLIDERINVOL_CYCLE,NULL);
  1197. UpdateVol(p);
  1198. }
  1199. return 0;
  1200. case WM_LBUTTONUP:
  1201. if (!p->InVol)
  1202. SetForegroundWindow(p->Win.Wnd);
  1203. else
  1204. {
  1205. p->InVol = 0;
  1206. ReleaseCapture();
  1207. KillTimer(p->Win.Wnd,TIMER_SLIDERINVOL);
  1208. }
  1209. SetVolPos(p,LOWORD(lParam));
  1210. UpdateVol(p);
  1211. return 0;
  1212. }
  1213. return CallWindowProc(p->DefVolProc,WndVol,Msg,wParam,lParam);
  1214. }
  1215. void CreateDeviceMenu(intface* p)
  1216. {
  1217. int No;
  1218. int *i;
  1219. NodeEnumClass(&p->VOutput,VOUT_CLASS);
  1220. NodeEnumClass(&p->AOutput,AOUT_CLASS);
  1221. for (No=0,i=ARRAYBEGIN(p->VOutput,int);i!=ARRAYEND(p->VOutput,int);++i,++No)
  1222. {
  1223. if (VOutIDCT(*i))
  1224. {
  1225. tchar_t s[256];
  1226. stprintf_s(s,TSIZEOF(s),LangStr(INTERFACE_ID,IF_OPTIONS_VIDEO_ACCEL),LangStr(*i,NODE_NAME));
  1227. WinMenuInsert(&p->Win,1,IF_OPTIONS_VIDEO_TURNOFF,IF_VIDEOACCEL+No,s);
  1228. }
  1229. WinMenuInsert(&p->Win,1,IF_OPTIONS_VIDEO_TURNOFF,IF_VIDEO+No,LangStr(*i,NODE_NAME));
  1230. }
  1231. for (No=0,i=ARRAYBEGIN(p->AOutput,int);i!=ARRAYEND(p->AOutput,int);++i,++No)
  1232. WinMenuInsert(&p->Win,1,IF_OPTIONS_AUDIO_TURNOFF,IF_AUDIO+No,LangStr(*i,NODE_NAME));
  1233. }
  1234. static menudef MenuDef[] =
  1235. {
  1236. { 0,INTERFACE_ID, IF_FILE },
  1237. { 1,INTERFACE_ID, IF_FILE_OPENFILE },
  1238. { 1,INTERFACE_ID, IF_FILE_CORETHEQUE },
  1239. { 1,INTERFACE_ID, IF_FILE_PLAYLIST },
  1240. { 1,-1,-1 },
  1241. { 1,INTERFACE_ID, IF_PLAY },
  1242. { 1,INTERFACE_ID, IF_NEXT },
  1243. { 1,INTERFACE_ID, IF_PREV },
  1244. { 1,-1,-1 },
  1245. { 1,INTERFACE_ID, IF_FILE_CHAPTERS },
  1246. { 2,INTERFACE_ID, IF_FILE_CHAPTERS_NONE },
  1247. { 1,INTERFACE_ID, IF_FILE_MEDIAINFO },
  1248. { 1,INTERFACE_ID, IF_FILE_BENCHMARK },
  1249. { 1,INTERFACE_ID, IF_FILE_ABOUT },
  1250. { 1,-1,-1 },
  1251. { 1,INTERFACE_ID, IF_FILE_EXIT },
  1252. { 0,INTERFACE_ID, IF_OPTIONS },
  1253. { 1,INTERFACE_ID, IF_OPTIONS_SPEED },
  1254. { 2,INTERFACE_ID, IF_OPTIONS_SPEED_10 },
  1255. { 2,INTERFACE_ID, IF_OPTIONS_SPEED_25 },
  1256. { 2,INTERFACE_ID, IF_OPTIONS_SPEED_50 }, 
  1257. { 2,INTERFACE_ID, IF_OPTIONS_SPEED_80 },
  1258. { 2,INTERFACE_ID, IF_OPTIONS_SPEED_90 },
  1259. { 2,INTERFACE_ID, IF_OPTIONS_SPEED_100 },
  1260. { 2,INTERFACE_ID, IF_OPTIONS_SPEED_110 },
  1261. { 2,INTERFACE_ID, IF_OPTIONS_SPEED_120 },
  1262. { 2,INTERFACE_ID, IF_OPTIONS_SPEED_150 },
  1263. { 2,INTERFACE_ID, IF_OPTIONS_SPEED_200 },
  1264. { 1,INTERFACE_ID, IF_OPTIONS_VIEW, MENU_SMALL },
  1265. { 2,INTERFACE_ID, IF_OPTIONS_ZOOM },
  1266. #if !defined(SH3)
  1267. { 3,INTERFACE_ID, IF_OPTIONS_ZOOM_FIT_SCREEN },
  1268. { 3,INTERFACE_ID, IF_OPTIONS_ZOOM_FILL_SCREEN },
  1269. { 3,INTERFACE_ID, IF_OPTIONS_ZOOM_STRETCH_SCREEN },
  1270. { 3,INTERFACE_ID, IF_OPTIONS_ZOOM_FIT_110 },
  1271. { 3,INTERFACE_ID, IF_OPTIONS_ZOOM_FIT_120 },
  1272. { 3,INTERFACE_ID, IF_OPTIONS_ZOOM_FIT_130 },
  1273. { 3,INTERFACE_ID, IF_OPTIONS_ZOOM_50 }, 
  1274. #endif
  1275. { 3,INTERFACE_ID, IF_OPTIONS_ZOOM_100 },
  1276. #if !defined(SH3)
  1277. { 3,INTERFACE_ID, IF_OPTIONS_ZOOM_150 },
  1278. #endif
  1279. { 3,INTERFACE_ID, IF_OPTIONS_ZOOM_200 },
  1280. #if !defined(SH3)
  1281. { 2,INTERFACE_ID, IF_OPTIONS_ASPECT },
  1282. { 3,INTERFACE_ID, IF_OPTIONS_ASPECT_AUTO },
  1283. { 3,INTERFACE_ID, IF_OPTIONS_ASPECT_SQUARE },
  1284. { 3,INTERFACE_ID, IF_OPTIONS_ASPECT_4_3_SCREEN },
  1285. { 3,INTERFACE_ID, IF_OPTIONS_ASPECT_4_3_NTSC },
  1286. { 3,INTERFACE_ID, IF_OPTIONS_ASPECT_4_3_PAL },
  1287. { 3,INTERFACE_ID, IF_OPTIONS_ASPECT_16_9_SCREEN },
  1288. { 3,INTERFACE_ID, IF_OPTIONS_ASPECT_16_9_NTSC },
  1289. { 3,INTERFACE_ID, IF_OPTIONS_ASPECT_16_9_PAL },
  1290. #endif
  1291. { 2,INTERFACE_ID, IF_OPTIONS_ORIENTATION },
  1292. { 3,INTERFACE_ID, IF_OPTIONS_ORIENTATION_FULLSCREEN },
  1293. { 3,INTERFACE_ID, IF_OPTIONS_ROTATE_GUI },
  1294. { 3,INTERFACE_ID, IF_OPTIONS_ROTATE_0 },
  1295. { 3,INTERFACE_ID, IF_OPTIONS_ROTATE_90 },
  1296. { 3,INTERFACE_ID, IF_OPTIONS_ROTATE_270 },
  1297. { 3,INTERFACE_ID, IF_OPTIONS_ROTATE_180 },
  1298. { 2,INTERFACE_ID, IF_OPTIONS_VIEW, MENU_NOTSMALL },
  1299. { 3,INTERFACE_ID, IF_OPTIONS_VIEW_TITLEBAR },
  1300. { 3,INTERFACE_ID, IF_OPTIONS_VIEW_TRACKBAR }, 
  1301. { 3,INTERFACE_ID, IF_OPTIONS_VIEW_TASKBAR }, 
  1302. { 1,INTERFACE_ID, IF_OPTIONS_VIDEO },
  1303. #if !defined(SH3) && !defined(MIPS)
  1304. { 2,INTERFACE_ID, IF_OPTIONS_VIDEO_ZOOM_SMOOTH50 },
  1305. { 2,INTERFACE_ID, IF_OPTIONS_VIDEO_ZOOM_SMOOTHALWAYS },
  1306. { 2,INTERFACE_ID, IF_OPTIONS_VIDEO_DITHER },
  1307. #endif
  1308. { 2,INTERFACE_ID, IF_OPTIONS_VIDEO_QUALITY },
  1309. { 3,INTERFACE_ID, IF_OPTIONS_VIDEO_QUALITY_LOWEST },
  1310. { 3,INTERFACE_ID, IF_OPTIONS_VIDEO_QUALITY_LOW },
  1311. { 3,INTERFACE_ID, IF_OPTIONS_VIDEO_QUALITY_NORMAL }, 
  1312. { 2,-1,-1 },
  1313. { 2,INTERFACE_ID, IF_OPTIONS_VIDEO_DEVICE, MENU_SMALL|MENU_GRAYED },
  1314. { 3,INTERFACE_ID, IF_OPTIONS_VIDEO_TURNOFF },
  1315. { 2,-1,-1 },
  1316. { 2,INTERFACE_ID, IF_OPTIONS_VIDEO_STREAM, MENU_SMALL|MENU_GRAYED },
  1317. { 3,INTERFACE_ID, IF_OPTIONS_VIDEO_STREAM_NONE },
  1318. { 1,INTERFACE_ID, IF_OPTIONS_AUDIO },
  1319. { 2,INTERFACE_ID, IF_OPTIONS_AUDIO_CHANNELS, MENU_SMALL },
  1320. { 3,INTERFACE_ID, IF_OPTIONS_AUDIO_STEREO },
  1321. { 3,INTERFACE_ID, IF_OPTIONS_AUDIO_STEREO_SWAPPED },
  1322. { 3,INTERFACE_ID, IF_OPTIONS_AUDIO_STEREO_JOINED },
  1323. { 3,INTERFACE_ID, IF_OPTIONS_AUDIO_STEREO_LEFT },
  1324. { 3,INTERFACE_ID, IF_OPTIONS_AUDIO_STEREO_RIGHT },
  1325. // { 2,-1,-1 },
  1326. // { 2,INTERFACE_ID, IF_OPTIONS_AUDIO_QUALITY },
  1327. // { 3,INTERFACE_ID, IF_OPTIONS_AUDIO_QUALITY_LOW },
  1328. // { 3,INTERFACE_ID, IF_OPTIONS_AUDIO_QUALITY_MEDIUM },
  1329. // { 3,INTERFACE_ID, IF_OPTIONS_AUDIO_QUALITY_HIGH }, 
  1330. { 2,-1,-1 },
  1331. { 2,INTERFACE_ID, IF_OPTIONS_AUDIO_PREAMP_DEC },
  1332. { 2,INTERFACE_ID, IF_OPTIONS_AUDIO_PREAMP },
  1333. { 2,INTERFACE_ID, IF_OPTIONS_AUDIO_PREAMP_INC }, 
  1334. { 2,-1,-1 },
  1335. { 2,INTERFACE_ID, IF_OPTIONS_AUDIO_DEVICE, MENU_SMALL|MENU_GRAYED },
  1336. { 3,INTERFACE_ID, IF_OPTIONS_AUDIO_TURNOFF },
  1337. { 2,-1,-1 },
  1338. { 2,INTERFACE_ID, IF_OPTIONS_AUDIO_STREAM, MENU_SMALL|MENU_GRAYED },
  1339. { 3,INTERFACE_ID, IF_OPTIONS_AUDIO_STREAM_NONE },
  1340. //!SUBTITLE { 1,INTERFACE_ID, IF_OPTIONS_SUBTITLE_STREAM, MENU_GRAYED },
  1341. //!SUBTITLE { 2,INTERFACE_ID, IF_OPTIONS_SUBTITLE_STREAM_NONE },
  1342. { 1,-1,-1 },
  1343. { 1,INTERFACE_ID, IF_OPTIONS_REPEAT },
  1344. { 1,INTERFACE_ID, IF_OPTIONS_SHUFFLE },
  1345. { 1,INTERFACE_ID, IF_OPTIONS_EQUALIZER },
  1346. { 1,INTERFACE_ID, IF_OPTIONS_FULLSCREEN },
  1347. #if defined(CONFIG_SKIN)
  1348. { 1,INTERFACE_ID, IF_OPTIONS_SKIN },
  1349. #endif
  1350. { 1,-1,-1 },
  1351. { 1,INTERFACE_ID, IF_OPTIONS_SETTINGS },
  1352. MENUDEF_END
  1353. };
  1354. void CreateButtons(intface* p)
  1355. {
  1356. if (QueryPlatform(PLATFORM_TYPENO) != TYPE_SMARTPHONE)
  1357. {
  1358. bool_t FullScreenButton = 1;
  1359. RECT r,rv;
  1360. WinBitmap(&p->Win,IDB_TOOLBAR16,IDB_TOOLBAR32,10);
  1361. WinAddButton(&p->Win,-1,-1,NULL,0);
  1362. WinAddButton(&p->Win,IF_PLAY,0,NULL,1);
  1363. WinAddButton(&p->Win,IF_FASTFORWARD,4,NULL,1);
  1364. WinAddButton(&p->Win,IF_STOP,5,NULL,0);
  1365. WinAddButton(&p->Win,-1,-1,NULL,0);
  1366. WinAddButton(&p->Win,IF_OPTIONS_FULLSCREEN,6,NULL,1);
  1367. WinAddButton(&p->Win,IF_OPTIONS_MUTE,7,NULL,1);
  1368. GetClientRect(p->Win.WndTB,&r);
  1369. SendMessage(p->Win.WndTB,TB_GETRECT,IF_OPTIONS_MUTE,(LPARAM)&rv);
  1370. if (r.right-rv.right < VOLMINWIDTH)
  1371. {
  1372. WinDeleteButton(&p->Win,IF_FASTFORWARD);
  1373. SendMessage(p->Win.WndTB,TB_GETRECT,IF_OPTIONS_MUTE,(LPARAM)&rv);
  1374. if (r.right-rv.right < VOLMINWIDTH)
  1375. {
  1376. WinDeleteButton(&p->Win,IF_OPTIONS_FULLSCREEN);
  1377. FullScreenButton = 0;
  1378. }
  1379. }
  1380. WinMenuDelete(&p->Win,0,IF_PLAY);
  1381. if (FullScreenButton)
  1382. WinMenuDelete(&p->Win,1,IF_OPTIONS_FULLSCREEN);
  1383. WinMenuDelete(&p->Win,1,IF_OPTIONS_MUTE);
  1384. }
  1385. }
  1386. static void UpdateVolume(intface* p)
  1387. {
  1388. int x;
  1389. if (p->Skin[p->SkinNo].Valid)
  1390. SkinUpdate(&p->Skin[p->SkinNo],p->Player,p->Win.Wnd,&p->SkinArea);
  1391. if (p->WndVol)
  1392. {
  1393. bool_t Enable = p->Player->Get(p->Player,PLAYER_VOLUME,&x,sizeof(x))==ERR_NONE;
  1394. EnableWindow(p->WndVol,Enable);
  1395. SetTrackThumb(p->WndVol,Enable);
  1396. if (Enable)
  1397. SendMessage(p->WndVol,TBM_SETPOS,1,x);
  1398. }
  1399. RefreshButton(p,PLAYER_MUTE,&p->Mute,IF_OPTIONS_MUTE,7,8);
  1400. }
  1401. static void CreateVolumeTrack(intface* p)
  1402. {
  1403. if (QueryPlatform(PLATFORM_TYPENO) != TYPE_SMARTPHONE)
  1404. {
  1405. WNDCLASS WinClass;
  1406. memset(&WinClass,0,sizeof(WinClass));
  1407. WinClass.style = CS_HREDRAW | CS_VREDRAW;
  1408. WinClass.lpfnWndProc = (WNDPROC) VolBackProc;
  1409. WinClass.cbClsExtra = 0;
  1410. WinClass.cbWndExtra = 0;
  1411. WinClass.hInstance = p->Win.Module;
  1412. WinClass.hCursor = WinCursorArrow();
  1413. WinClass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
  1414. WinClass.lpszMenuName = 0;
  1415. WinClass.lpszClassName = T("VolumeBack");
  1416. RegisterClass(&WinClass);
  1417. p->WndVolBack = CreateWindowEx( 
  1418. WS_EX_TOPMOST,                    
  1419. WinClass.lpszClassName,       
  1420. Context()->ProgramName,   
  1421. (p->Win.ToolBarHeight ? WS_CHILD:WS_POPUP) | WS_VISIBLE | 
  1422. TBS_HORZ|TBS_BOTH|TBS_NOTICKS|TBS_FIXEDLENGTH, 
  1423. 200, 0,    
  1424. 40, 20,   
  1425. (p->Win.ToolBarHeight ? p->Win.WndTB:p->Win.Wnd),
  1426. NULL,
  1427. p->Win.Module,                     
  1428. NULL                      
  1429. ); 
  1430. p->WndVol = CreateWindowEx( 
  1431. 0,                    
  1432. TRACKBAR_CLASS,       
  1433. NULL,   
  1434. WS_CHILD | WS_VISIBLE | 
  1435. TBS_HORZ|TBS_BOTH|TBS_NOTICKS|TBS_FIXEDLENGTH, 
  1436. 0, 0,    
  1437. 40, 20,   
  1438. p->WndVolBack,
  1439. NULL,
  1440. p->Win.Module,                     
  1441. NULL                      
  1442. ); 
  1443. p->DefVolProc = (WNDPROC)GetWindowLong(p->WndVol,GWL_WNDPROC);
  1444. SetWindowLong(p->WndVol,GWL_WNDPROC,(LONG)VolProc);
  1445. WinSetObject(p->WndVol,&p->Win);
  1446. SendMessage(p->WndVol, TBM_SETRANGE, FALSE,MAKELONG(0,100));
  1447. SendMessage(p->WndVol, TBM_SETPAGESIZE,0,10);
  1448. SendMessage(p->WndVol, TBM_SETLINESIZE,0,10);
  1449. ResizeVolume(p);
  1450. UpdateVolume(p);
  1451. }
  1452. }
  1453. static int UpdateTitleBar(intface* p,bool_t DoResize)
  1454. {
  1455. if (p->TitleBar && !p->WndTitle && p->Win.Wnd)
  1456. {
  1457. WNDCLASS WinClass;
  1458. memset(&WinClass,0,sizeof(WinClass));
  1459. WinClass.style = CS_HREDRAW | CS_VREDRAW;
  1460. WinClass.lpfnWndProc = (WNDPROC) TitleProc;
  1461. WinClass.cbClsExtra = 0;
  1462. WinClass.cbWndExtra = 0;
  1463. WinClass.hInstance = p->Win.Module;
  1464. WinClass.hCursor = WinCursorArrow();
  1465. WinClass.hbrBackground = NULL;
  1466. WinClass.lpszMenuName = 0;
  1467. WinClass.lpszClassName = T("TitleBar");
  1468. RegisterClass(&WinClass);
  1469. p->WndTitle = CreateWindowEx( 
  1470. 0,                    
  1471. WinClass.lpszClassName,       
  1472. T("Time"),   
  1473. WS_CHILD | WS_VISIBLE, 
  1474. 0, 0,    
  1475. 200, 20,   
  1476. p->Win.Wnd,
  1477. NULL,
  1478. p->Win.Module,                     
  1479. NULL                      
  1480. ); 
  1481. WinSetObject(p->WndTitle,&p->Win);
  1482. p->ClientRect.right = -1;
  1483. if (DoResize) Resize(p);
  1484. }
  1485. if (!p->TitleBar && p->WndTitle)
  1486. {
  1487. DestroyWindow(p->WndTitle);
  1488. p->WndTitle = NULL;
  1489. p->ClientRect.right = -1;
  1490. if (DoResize) Resize(p);
  1491. }
  1492. return ERR_NONE;
  1493. }
  1494. static NOINLINE void UpdateTrackPos(intface* p)
  1495. {
  1496. if (p->Skin[p->SkinNo].Valid)
  1497. SkinUpdate(p->Skin+p->SkinNo,p->Player,p->Win.Wnd,&p->SkinArea);
  1498. if (p->WndTrack)
  1499. {
  1500. fraction f;
  1501. int TrackPos;
  1502. if (p->Player->Get(p->Player,PLAYER_PERCENT,&f,sizeof(fraction)) == ERR_NONE)
  1503. TrackPos = Scale(TRACKMAX,f.Num,f.Den);
  1504. else
  1505. TrackPos = -1;
  1506. if (TrackPos != p->TrackPos)
  1507. {
  1508. if (TrackPos == -1)
  1509. {
  1510. SetTrackThumb(p->WndTrack,0);
  1511. EnableWindow(p->WndTrack,0);
  1512. }
  1513. if (p->TrackPos == -1)
  1514. {
  1515. SetTrackThumb(p->WndTrack,1);
  1516. EnableWindow(p->WndTrack,1);
  1517. }
  1518. p->TrackPos = TrackPos;
  1519. SendMessage(p->WndTrack,TBM_SETPOS,1,TrackPos);
  1520. }
  1521. }
  1522. }
  1523. static int UpdateTrackBar(intface* p,bool_t DoResize)
  1524. {
  1525. bool_t TrackBar = p->TrackBar && !p->Skin[p->SkinNo].Valid;
  1526. if (TrackBar && !p->WndTrack && p->Win.Wnd)
  1527. {
  1528. p->WndTrack = CreateWindowEx( 
  1529. 0,                    
  1530. TRACKBAR_CLASS,       
  1531. T("Time"),   
  1532. WS_CHILD | WS_VISIBLE | 
  1533. TBS_HORZ|TBS_BOTH|TBS_NOTICKS|TBS_FIXEDLENGTH, 
  1534. 0, 0,    
  1535. 200, 20,   
  1536. p->Win.Wnd,
  1537. NULL,
  1538. p->Win.Module,                     
  1539. NULL                      
  1540. ); 
  1541. p->DefTrackProc = (WNDPROC)GetWindowLong(p->WndTrack,GWL_WNDPROC);
  1542. SetWindowLong(p->WndTrack,GWL_WNDPROC,(LONG)TrackProc);
  1543. WinSetObject(p->WndTrack,&p->Win);
  1544. SendMessage(p->WndTrack, TBM_SETRANGE, FALSE,MAKELONG(0,TRACKMAX));
  1545. SendMessage(p->WndTrack, TBM_SETPAGESIZE,0,TRACKMAX/20);
  1546. SendMessage(p->WndTrack, TBM_SETLINESIZE,0,TRACKMAX/100);
  1547. p->TrackPos = 0;
  1548. UpdateTrackPos(p);
  1549. p->ClientRect.right = -1;
  1550. if (DoResize) Resize(p);
  1551. }
  1552. if (!TrackBar && p->WndTrack)
  1553. {
  1554. DestroyWindow(p->WndTrack);
  1555. p->WndTrack = NULL;
  1556. p->ClientRect.right = -1;
  1557. if (DoResize) Resize(p);
  1558. }
  1559. p->TrackThumb = -1;
  1560. return ERR_NONE;
  1561. }
  1562. static void BeforeExit(intface* p)
  1563. {
  1564. if (Context()->Wnd)
  1565. {
  1566. NodeRegSaveValue(0,REG_INITING,NULL,0,TYPE_INT);
  1567. NodeRegSave((node*)p);
  1568. UpdateHotKey(p,0,1);
  1569. if (p->WndVolBack)
  1570. {
  1571. DestroyWindow(p->WndVolBack);
  1572. p->WndVolBack = NULL;
  1573. }
  1574. Context_Wnd(NULL);
  1575. }
  1576. }
  1577. static void ShowError2(intface* p, const tchar_t* s)
  1578. {
  1579. win* Win;
  1580. if (p->Player)
  1581. {
  1582. p->Player->Set(p->Player,PLAYER_STOP,NULL,1); // full stop (no filling buffers)
  1583. ToggleFullScreen(p,0,0); //ATI tweaks would have problem
  1584. }
  1585. UpdateClipping(p,1,1); // force clipping mode
  1586. // find application foreground window
  1587. Win = &p->Win;
  1588. while (Win->Child) Win = Win->Child;
  1589. MessageBox(Win->Wnd,s,LangStr(PLATFORM_ID,PLATFORM_ERROR),MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
  1590. }
  1591. static void ToggleStream(intface* p,int Id,int Type,bool_t UseNone)
  1592. {
  1593. packetformat Format;
  1594. int No,Current,First=-1;
  1595. p->Player->Get(p->Player,Id,&Current,sizeof(int));
  1596. if (Current == MAXSTREAM)
  1597. Current = -1;
  1598. for (No=0;PlayerGetStream(p->Player,No,&Format,NULL,0,NULL);++No)
  1599. if (Format.Type == Type)
  1600. {
  1601. if (First < 0)
  1602. First = No;
  1603. if (Current == No)
  1604. Current = -1;
  1605. else
  1606. if (Current == -1)
  1607. Current = No;
  1608. }
  1609. if (Current == -1)
  1610. Current = UseNone ? MAXSTREAM:First;
  1611. if (Current >= 0)
  1612. {
  1613. p->Player->Set(p->Player,Id,&Current,sizeof(int));
  1614. p->Player->Set(p->Player,PLAYER_RESYNC,NULL,0);
  1615. }
  1616. }
  1617. static int UpdateTaskBar(intface* p)
  1618. {
  1619. if (!p->Win.FullScreen)
  1620. DIASet(p->TaskBar?DIA_TASKBAR:0,DIA_TASKBAR);
  1621. return ERR_NONE;
  1622. }
  1623. static int UpdateSkin(intface* p,bool_t Others);
  1624. static int UpdateSkinFile(intface* p)
  1625. {
  1626. if (p->Player)
  1627. {
  1628. SkinFree(p->Skin,NULL);
  1629. SkinLoad(p->Skin,p->Win.Wnd,p->SkinPath);
  1630. UpdateSkin(p,1);
  1631. }
  1632. return ERR_NONE;
  1633. }
  1634. static int Command(intface* p,int Cmd)
  1635. {
  1636. node* Node;
  1637. bool_t b;
  1638. int i;
  1639. fraction f;
  1640. tick_t t;
  1641. int Zero = 0;
  1642. switch (Cmd)
  1643. {
  1644. case IF_SKIN0:
  1645. p->SkinNo = 0;
  1646. UpdateSkin(p,1);
  1647. break;
  1648. case IF_SKIN1:
  1649. p->SkinNo = 1;
  1650. UpdateSkin(p,1);
  1651. break;
  1652. case IF_OPTIONS_VOLUME_UP:
  1653. Delta(p,(node*)p->Player,PLAYER_VOLUME,10,0,100);
  1654. break;
  1655. case IF_OPTIONS_VOLUME_DOWN:
  1656. Delta(p,(node*)p->Player,PLAYER_VOLUME,-10,0,100);
  1657. break;
  1658. case IF_OPTIONS_VOLUME_UP_FINE:
  1659. Delta(p,(node*)p->Player,PLAYER_VOLUME,3,0,100);
  1660. break;
  1661. case IF_OPTIONS_VOLUME_DOWN_FINE:
  1662. Delta(p,(node*)p->Player,PLAYER_VOLUME,-3,0,100);
  1663. break;
  1664. case IF_OPTIONS_BRIGHTNESS_UP:
  1665. Delta(p,p->Color,COLOR_BRIGHTNESS,6,-128,127);
  1666. break;
  1667. case IF_OPTIONS_BRIGHTNESS_DOWN:
  1668. Delta(p,p->Color,COLOR_BRIGHTNESS,-6,-128,127);
  1669. break;
  1670. case IF_OPTIONS_CONTRAST_UP:
  1671. Delta(p,p->Color,COLOR_CONTRAST,6,-128,127);
  1672. break;
  1673. case IF_OPTIONS_CONTRAST_DOWN:
  1674. Delta(p,p->Color,COLOR_CONTRAST,-6,-128,127);
  1675. break;
  1676. case IF_OPTIONS_SATURATION_UP:
  1677. Delta(p,p->Color,COLOR_SATURATION,6,-128,127);
  1678. break;
  1679. case IF_OPTIONS_SATURATION_DOWN:
  1680. Delta(p,p->Color,COLOR_SATURATION,-6,-128,127);
  1681. break;
  1682. case IF_OPTIONS_SCREEN:
  1683. SetDisplayPower(!GetDisplayPower(),1);
  1684. break;
  1685. case IF_OPTIONS_AUDIO_STEREO_TOGGLE:
  1686. p->Player->Get(p->Player,PLAYER_STEREO,&i,sizeof(i));
  1687. i = i==STEREO_LEFT?STEREO_RIGHT:STEREO_LEFT;
  1688. p->Player->Set(p->Player,PLAYER_STEREO,&i,sizeof(i));
  1689. break;
  1690. case IF_OPTIONS_TOGGLE_VIDEO:
  1691. ToggleStream(p,PLAYER_VSTREAM,PACKET_VIDEO,0);
  1692. break;
  1693. case IF_OPTIONS_TOGGLE_SUBTITLE:
  1694. ToggleStream(p,PLAYER_SUBSTREAM,PACKET_SUBTITLE,1);
  1695. break;
  1696. case IF_OPTIONS_TOGGLE_AUDIO:
  1697. ToggleStream(p,PLAYER_ASTREAM,PACKET_AUDIO,0);
  1698. break;
  1699. case IF_OPTIONS_ZOOM_IN:
  1700. p->Player->Get(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  1701. if (f.Num <= 0) f.Num = f.Den = 1;
  1702. if (f.Den != 100)
  1703. {
  1704. f.Num = f.Num * 100 / f.Den;
  1705. f.Den = 100;
  1706. }
  1707. f.Num+=5;
  1708. p->Player->Set(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  1709. p->Player->Set(p->Player,PLAYER_SKIN_ZOOM,&f,sizeof(f));
  1710. break;
  1711. case IF_OPTIONS_ZOOM_OUT:
  1712. p->Player->Get(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  1713. if (f.Num <= 0) f.Num = f.Den = 1;
  1714. if (f.Den != 100)
  1715. {
  1716. f.Num = f.Num * 100 / f.Den;
  1717. f.Den = 100;
  1718. }
  1719. if (f.Num>5) f.Num-=5;
  1720. p->Player->Set(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  1721. p->Player->Set(p->Player,PLAYER_SKIN_ZOOM,&f,sizeof(f));
  1722. break;
  1723. case IF_OPTIONS_ZOOM_FIT:
  1724. p->Player->Get(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  1725. f.Num = f.Num == -1 ? -2:-1;
  1726. f.Den = 1;
  1727. p->Player->Set(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  1728. p->Player->Set(p->Player,PLAYER_SKIN_ZOOM,&f,sizeof(f));
  1729. break;
  1730. case IF_PLAY_FULLSCREEN:
  1731. if (p->Player->Get(p->Player,PLAYER_STREAMING,&b,sizeof(b))==ERR_NONE && b)
  1732. ToggleFullScreen(p,-1,0);
  1733. else
  1734. if (!(p->Player->Get(p->Player,PLAYER_FULLSCREEN,&b,sizeof(b))==ERR_NONE && b) &&
  1735. !(p->Player->Get(p->Player,PLAYER_PLAY,&b,sizeof(b))==ERR_NONE && b))
  1736. {
  1737. ToggleFullScreen(p,1,0);
  1738. Toggle(p,PLAYER_PLAY,1);
  1739. }
  1740. else
  1741. {
  1742. Toggle(p,PLAYER_PLAY,0);
  1743. ToggleFullScreen(p,0,0);
  1744. }
  1745. break;
  1746. case IF_MOVE_FFWD:
  1747. SetKeyInSeek(p);
  1748. p->Player->Set(p->Player,PLAYER_MOVEFFWD,NULL,0);
  1749. break;
  1750. case IF_MOVE_BACK:
  1751. SetKeyInSeek(p);
  1752. p->Player->Set(p->Player,PLAYER_MOVEBACK,NULL,0);
  1753. break;
  1754. case IF_NEXT2:
  1755. case IF_NEXT:
  1756. p->Player->Set(p->Player,PLAYER_NEXT,NULL,0);
  1757. break;
  1758. case IF_PREV_SMART:
  1759. case IF_PREV_SMART2:
  1760. p->Player->Set(p->Player,PLAYER_PREV,NULL,1);
  1761. break;
  1762. case IF_PREV:
  1763. p->Player->Set(p->Player,PLAYER_PREV,NULL,0);
  1764. break;
  1765. case IF_PLAYPAUSE:
  1766. case IF_PLAY:
  1767. p->Play = -1; // force button refresh
  1768. Toggle(p,PLAYER_PLAY,-1);
  1769. break;
  1770. case IF_FASTFORWARD:
  1771. p->FFwd = -1; // force button refresh
  1772. Toggle(p,PLAYER_FFWD,-1);
  1773. break;
  1774. case IF_FILE_BENCHMARK:
  1775. if (!ToggleFullScreen(p,1,0))
  1776. {
  1777. if (p->WndTrack)
  1778. SetTrackThumb(p->WndTrack,0);
  1779. WaitBegin();
  1780. }
  1781. UpdateWindow(p->Win.Wnd);
  1782. t = 0;
  1783. p->Player->Set(p->Player,PLAYER_BENCHMARK,&t,sizeof(t));
  1784. p->Bench = 1;
  1785. break;
  1786. case IF_STOP:
  1787. p->Player->Set(p->Player,PLAYER_STOP,NULL,0);
  1788. f.Num = 0;
  1789. f.Den = 1;
  1790. p->Player->Set(p->Player,PLAYER_PERCENT,&f,sizeof(f));
  1791. break;
  1792. case IF_FILE_OPENFILE:
  1793. p->CmdLineMode = 0;
  1794. Node = NodeCreate(OPENFILE_ID);
  1795. i = 0;
  1796. Node->Set(Node,OPENFILE_FLAGS,&i,sizeof(i));
  1797. i = MEDIA_CLASS;
  1798. Node->Set(Node,OPENFILE_CLASS,&i,sizeof(i));
  1799. UpdateHotKey(p,0,1);
  1800. i = ((win*)Node)->Popup((win*)Node,&p->Win);
  1801. NodeDelete(Node);
  1802. if (i==2)
  1803. {
  1804. UpdateWindow(p->Win.Wnd);
  1805. i=0;
  1806. p->Player->Set(p->Player,PLAYER_LIST_CURRIDX,&i,sizeof(i));
  1807. }
  1808. break;
  1809. case IF_FILE_CORETHEQUE:
  1810. WinPopupClass(CORETHEQUE_UI_ID,&p->Win);
  1811. p->Player->Set(p->Player,PLAYER_UPDATEVIDEO,NULL,0); 
  1812. break;
  1813. case IF_FILE_ABOUT:
  1814. WinPopupClass(ABOUT_ID,&p->Win);
  1815. break;
  1816. case IF_OPTIONS_SETTINGS:
  1817. UpdateHotKey(p,0,1);
  1818. p->AllKeysWarning = 1;
  1819. WinPopupClass(SETTINGS_ID,&p->Win);
  1820. p->AllKeysWarning = 0;
  1821. p->Player->Set(p->Player,PLAYER_UPDATEVIDEO,NULL,0); 
  1822. break;
  1823. case IF_FILE_PLAYLIST:
  1824. WinPopupClass(PLAYLIST_ID,&p->Win);
  1825. break;
  1826. case IF_FILE_MEDIAINFO:
  1827. WinPopupClass(MEDIAINFO_ID,&p->Win);
  1828. break;
  1829. case IF_FILE_EXIT:
  1830. // just to be sure to stop overlay update (WM_DESTROY comes after window is hidden)
  1831. BeforeExit(p);
  1832. DestroyWindow(p->Win.Wnd);
  1833. break;
  1834. case IF_OPTIONS_REPEAT:
  1835. Toggle(p,PLAYER_REPEAT,-1);
  1836. break;
  1837. case IF_OPTIONS_SHUFFLE:
  1838. Toggle(p,PLAYER_SHUFFLE,-1);
  1839. break;
  1840. case IF_OPTIONS_EQUALIZER:
  1841. p->Equalizer->Get(p->Equalizer,EQUALIZER_ENABLED,&b,sizeof(b));
  1842. b = !b;
  1843. p->Equalizer->Set(p->Equalizer,EQUALIZER_ENABLED,&b,sizeof(b));
  1844. //p->Player->Set(p->Player,PLAYER_RESYNC,NULL,0);
  1845. break;
  1846. case IF_OPTIONS_SKIN:
  1847. Node = NodeCreate(OPENFILE_ID);
  1848. if (Node)
  1849. {
  1850. i = OPENFLAG_SINGLE;
  1851. Node->Set(Node,OPENFILE_FLAGS,&i,sizeof(i));
  1852. i = SKIN_CLASS;
  1853. Node->Set(Node,OPENFILE_CLASS,&i,sizeof(i));
  1854. i = ((win*)Node)->Popup((win*)Node,&p->Win);
  1855. NodeDelete(Node);
  1856. if (i==1)
  1857. {
  1858. p->SkinPath[0] = 0;
  1859. UpdateSkinFile(p);
  1860. }
  1861. }
  1862. break;
  1863. case IF_OPTIONS_FULLSCREEN:
  1864. p->FullScreen = -1; // force button refresh
  1865. ToggleFullScreen(p,-1,1);
  1866. break;
  1867. case IF_OPTIONS_MUTE:
  1868. p->Mute = -1; // force button refresh
  1869. if (p->Player->Get(p->Player,PLAYER_VOLUME,&i,sizeof(i))==ERR_NONE && i==0)
  1870. {
  1871. i = 1;
  1872. p->Player->Set(p->Player,PLAYER_VOLUME,&i,sizeof(i));
  1873. }
  1874. Toggle(p,PLAYER_MUTE,-1);
  1875. UpdateVolume(p);
  1876. break;
  1877. case IF_OPTIONS_VIDEO_DITHER:
  1878. p->Color->Get(p->Color,COLOR_DITHER,&b,sizeof(b));
  1879. b = !b;
  1880. p->Color->Set(p->Color,COLOR_DITHER,&b,sizeof(b));
  1881. break;
  1882. case IF_OPTIONS_ROTATE:
  1883. p->Player->Get(p->Player,PLAYER_FULL_DIR,&i,sizeof(i));
  1884. switch (i)
  1885. {
  1886. case 0: i = DIR_SWAPXY | DIR_MIRRORLEFTRIGHT; break;
  1887. case DIR_SWAPXY | DIR_MIRRORLEFTRIGHT: i = DIR_MIRRORUPDOWN | DIR_MIRRORLEFTRIGHT; break;
  1888. case DIR_MIRRORUPDOWN | DIR_MIRRORLEFTRIGHT: i = DIR_SWAPXY | DIR_MIRRORUPDOWN; break;
  1889. case DIR_SWAPXY | DIR_MIRRORUPDOWN: i = 0; break;
  1890. default: i = 0; break;
  1891. }
  1892. p->Player->Set(p->Player,PLAYER_FULL_DIR,&i,sizeof(i));
  1893. p->Player->Get(p->Player,PLAYER_SKIN_DIR,&i,sizeof(i));
  1894. switch (i)
  1895. {
  1896. case 0: i = DIR_SWAPXY | DIR_MIRRORLEFTRIGHT; break;
  1897. case DIR_SWAPXY | DIR_MIRRORLEFTRIGHT: i = DIR_MIRRORUPDOWN | DIR_MIRRORLEFTRIGHT; break;
  1898. case DIR_MIRRORUPDOWN | DIR_MIRRORLEFTRIGHT: i = DIR_SWAPXY | DIR_MIRRORUPDOWN; break;
  1899. case DIR_SWAPXY | DIR_MIRRORUPDOWN: i = 0; break;
  1900. default: i = 0; break;
  1901. }
  1902. p->Player->Set(p->Player,PLAYER_SKIN_DIR,&i,sizeof(i));
  1903. break;
  1904. case IF_OPTIONS_ROTATE_GUI:
  1905. i = -1;
  1906. p->Player->Set(p->Player,PLAYER_FULL_DIR,&i,sizeof(i));
  1907. break;
  1908. case IF_OPTIONS_ROTATE_0:
  1909. i = 0;
  1910. p->Player->Set(p->Player,PLAYER_FULL_DIR,&i,sizeof(i));
  1911. break;
  1912. case IF_OPTIONS_ROTATE_270:
  1913. i = DIR_SWAPXY | DIR_MIRRORUPDOWN;
  1914. p->Player->Set(p->Player,PLAYER_FULL_DIR,&i,sizeof(i));
  1915. break;
  1916. case IF_OPTIONS_ROTATE_180:
  1917. i = DIR_MIRRORUPDOWN | DIR_MIRRORLEFTRIGHT;
  1918. p->Player->Set(p->Player,PLAYER_FULL_DIR,&i,sizeof(i));
  1919. break;
  1920. case IF_OPTIONS_ROTATE_90:
  1921. i = DIR_SWAPXY | DIR_MIRRORLEFTRIGHT;
  1922. p->Player->Set(p->Player,PLAYER_FULL_DIR,&i,sizeof(i));
  1923. break;
  1924. case IF_OPTIONS_ASPECT_AUTO:
  1925. f.Num = 0;
  1926. f.Den = 1;
  1927. p->Player->Set(p->Player,PLAYER_ASPECT,&f,sizeof(f));
  1928. break;
  1929. case IF_OPTIONS_ASPECT_SQUARE:
  1930. f.Num = 1;
  1931. f.Den = 1;
  1932. p->Player->Set(p->Player,PLAYER_ASPECT,&f,sizeof(f));
  1933. break;
  1934. case IF_OPTIONS_ASPECT_4_3_SCREEN:
  1935. f.Num = -4;
  1936. f.Den = 3;
  1937. p->Player->Set(p->Player,PLAYER_ASPECT,&f,sizeof(f));
  1938. break;
  1939. case IF_OPTIONS_ASPECT_4_3_NTSC:
  1940. f.Num = 10;
  1941. f.Den = 11;
  1942. p->Player->Set(p->Player,PLAYER_ASPECT,&f,sizeof(f));
  1943. break;
  1944. case IF_OPTIONS_ASPECT_4_3_PAL:
  1945. f.Num = 12;
  1946. f.Den = 11;
  1947. p->Player->Set(p->Player,PLAYER_ASPECT,&f,sizeof(f));
  1948. break;
  1949. case IF_OPTIONS_ASPECT_16_9_SCREEN:
  1950. f.Num = -16;
  1951. f.Den = 9;
  1952. p->Player->Set(p->Player,PLAYER_ASPECT,&f,sizeof(f));
  1953. break;
  1954. case IF_OPTIONS_ASPECT_16_9_NTSC:
  1955. f.Num = 40;
  1956. f.Den = 33;
  1957. p->Player->Set(p->Player,PLAYER_ASPECT,&f,sizeof(f));
  1958. break;
  1959. case IF_OPTIONS_ASPECT_16_9_PAL:
  1960. f.Num = 16;
  1961. f.Den = 11;
  1962. p->Player->Set(p->Player,PLAYER_ASPECT,&f,sizeof(f));
  1963. break;
  1964. case IF_OPTIONS_ZOOM_FIT_SCREEN:
  1965. f.Num = 0;
  1966. f.Den = 1;
  1967. p->Player->Set(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  1968. p->Player->Set(p->Player,PLAYER_SKIN_ZOOM,&f,sizeof(f));
  1969. break;
  1970. case IF_OPTIONS_ZOOM_STRETCH_SCREEN:
  1971. f.Num = -3;
  1972. f.Den = SCALE_ONE;
  1973. p->Player->Set(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  1974. p->Player->Set(p->Player,PLAYER_SKIN_ZOOM,&f,sizeof(f));
  1975. break;
  1976. case IF_OPTIONS_ZOOM_FILL_SCREEN:
  1977. f.Num = -4;
  1978. f.Den = SCALE_ONE;
  1979. p->Player->Set(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  1980. p->Player->Set(p->Player,PLAYER_SKIN_ZOOM,&f,sizeof(f));
  1981. break;
  1982. case IF_OPTIONS_VIEW_TITLEBAR:
  1983. p->TitleBar = !p->TitleBar;
  1984. UpdateTitleBar(p,1);
  1985. break;
  1986. case IF_OPTIONS_VIEW_TASKBAR:
  1987. p->TaskBar = !p->TaskBar;
  1988. UpdateTaskBar(p);
  1989. break;
  1990. case IF_OPTIONS_VIEW_TRACKBAR:
  1991. p->TrackBar = !p->TrackBar;
  1992. UpdateTrackBar(p,1);
  1993. break;
  1994. case IF_OPTIONS_ZOOM_50:
  1995. f.Num = 1;
  1996. f.Den = 2;
  1997. p->Player->Set(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  1998. p->Player->Set(p->Player,PLAYER_SKIN_ZOOM,&f,sizeof(f));
  1999. break;
  2000. case IF_OPTIONS_ZOOM_100:
  2001. f.Num = 1;
  2002. f.Den = 1;
  2003. p->Player->Set(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  2004. p->Player->Set(p->Player,PLAYER_SKIN_ZOOM,&f,sizeof(f));
  2005. break;
  2006. case IF_OPTIONS_ZOOM_FIT_110:
  2007. f.Num = -11;
  2008. f.Den = 10;
  2009. p->Player->Set(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  2010. p->Player->Set(p->Player,PLAYER_SKIN_ZOOM,&f,sizeof(f));
  2011. break;
  2012. case IF_OPTIONS_ZOOM_FIT_120:
  2013. f.Num = -12;
  2014. f.Den = 10;
  2015. p->Player->Set(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  2016. p->Player->Set(p->Player,PLAYER_SKIN_ZOOM,&f,sizeof(f));
  2017. break;
  2018. case IF_OPTIONS_ZOOM_FIT_130:
  2019. f.Num = -13;
  2020. f.Den = 10;
  2021. p->Player->Set(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  2022. p->Player->Set(p->Player,PLAYER_SKIN_ZOOM,&f,sizeof(f));
  2023. break;
  2024. case IF_OPTIONS_ZOOM_150:
  2025. f.Num = 3;
  2026. f.Den = 2;
  2027. p->Player->Set(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  2028. p->Player->Set(p->Player,PLAYER_SKIN_ZOOM,&f,sizeof(f));
  2029. break;
  2030. case IF_OPTIONS_ZOOM_200:
  2031. f.Num = 2;
  2032. f.Den = 1;
  2033. p->Player->Set(p->Player,PLAYER_FULL_ZOOM,&f,sizeof(f));
  2034. p->Player->Set(p->Player,PLAYER_SKIN_ZOOM,&f,sizeof(f));
  2035. break;
  2036. case IF_OPTIONS_VIDEO_ZOOM_SMOOTH50:
  2037. Toggle(p,PLAYER_SMOOTH50,-1);
  2038. Toggle(p,PLAYER_SMOOTHALWAYS,0);
  2039. break;
  2040. case IF_OPTIONS_VIDEO_ZOOM_SMOOTHALWAYS:
  2041. Toggle(p,PLAYER_SMOOTHALWAYS,-1);
  2042. Toggle(p,PLAYER_SMOOTH50,0);
  2043. break;
  2044. case IF_OPTIONS_AUDIO_STEREO:
  2045. i = STEREO_NORMAL;
  2046. p->Player->Set(p->Player,PLAYER_STEREO,&i,sizeof(i));
  2047. break;
  2048. case IF_OPTIONS_AUDIO_STEREO_SWAPPED:
  2049. i = STEREO_SWAPPED;
  2050. p->Player->Set(p->Player,PLAYER_STEREO,&i,sizeof(i));
  2051. break;
  2052. case IF_OPTIONS_AUDIO_STEREO_JOINED:
  2053. i = STEREO_JOINED;
  2054. p->Player->Set(p->Player,PLAYER_STEREO,&i,sizeof(i));
  2055. break;
  2056. case IF_OPTIONS_AUDIO_STEREO_LEFT:
  2057. i = STEREO_LEFT;
  2058. p->Player->Set(p->Player,PLAYER_STEREO,&i,sizeof(i));
  2059. break;
  2060. case IF_OPTIONS_AUDIO_STEREO_RIGHT:
  2061. i = STEREO_RIGHT;
  2062. p->Player->Set(p->Player,PLAYER_STEREO,&i,sizeof(i));
  2063. break;
  2064. case IF_OPTIONS_AUDIO_PREAMP_INC:
  2065. p->Player->Get(p->Player,PLAYER_PREAMP,&i,sizeof(i));
  2066. i += 25;
  2067. if (i>200) i=200;
  2068. p->Player->Set(p->Player,PLAYER_PREAMP,&i,sizeof(i));
  2069. break;
  2070. case IF_OPTIONS_AUDIO_PREAMP_DEC:
  2071. p->Player->Get(p->Player,PLAYER_PREAMP,&i,sizeof(i));
  2072. i -= 25;
  2073. if (i<-200) i=-200;
  2074. p->Player->Set(p->Player,PLAYER_PREAMP,&i,sizeof(i));
  2075. break;
  2076. case IF_OPTIONS_AUDIO_PREAMP:
  2077. i = 0;
  2078. p->Player->Set(p->Player,PLAYER_PREAMP,&i,sizeof(i));
  2079. break;
  2080. case IF_OPTIONS_AUDIO_QUALITY_LOW:
  2081. i = 0;
  2082. p->Player->Set(p->Player,PLAYER_AUDIO_QUALITY,&i,sizeof(i));
  2083. break;
  2084. case IF_OPTIONS_AUDIO_QUALITY_MEDIUM:
  2085. i = 1;
  2086. p->Player->Set(p->Player,PLAYER_AUDIO_QUALITY,&i,sizeof(i));
  2087. break;
  2088. case IF_OPTIONS_AUDIO_QUALITY_HIGH:
  2089. i = 2;
  2090. p->Player->Set(p->Player,PLAYER_AUDIO_QUALITY,&i,sizeof(i));
  2091. break;
  2092. case IF_OPTIONS_VIDEO_QUALITY_LOWEST:
  2093. i = 0;
  2094. p->Player->Set(p->Player,PLAYER_VIDEO_QUALITY,&i,sizeof(i));
  2095. p->Player->Set(p->Player,PLAYER_RESYNC,NULL,0);
  2096. break;
  2097. case IF_OPTIONS_VIDEO_QUALITY_LOW:
  2098. i = 1;
  2099. p->Player->Set(p->Player,PLAYER_VIDEO_QUALITY,&i,sizeof(i));
  2100. p->Player->Set(p->Player,PLAYER_RESYNC,NULL,0);
  2101. break;
  2102. case IF_OPTIONS_VIDEO_QUALITY_NORMAL:
  2103. i = 2;
  2104. p->Player->Set(p->Player,PLAYER_VIDEO_QUALITY,&i,sizeof(i));
  2105. p->Player->Set(p->Player,PLAYER_RESYNC,NULL,0);
  2106. break;
  2107. case IF_OPTIONS_SPEED_10:
  2108. f.Num = 1;
  2109. f.Den = 10;
  2110. p->Player->Set(p->Player,PLAYER_PLAY_SPEED,&f,sizeof(f));
  2111. break;
  2112. case IF_OPTIONS_SPEED_25:
  2113. f.Num = 1;
  2114. f.Den = 4;
  2115. p->Player->Set(p->Player,PLAYER_PLAY_SPEED,&f,sizeof(f));
  2116. break;
  2117. case IF_OPTIONS_SPEED_50:
  2118. f.Num = 1;
  2119. f.Den = 2;
  2120. p->Player->Set(p->Player,PLAYER_PLAY_SPEED,&f,sizeof(f));
  2121. break;
  2122. case IF_OPTIONS_SPEED_100:
  2123. f.Num = 1;
  2124. f.Den = 1;
  2125. p->Player->Set(p->Player,PLAYER_PLAY_SPEED,&f,sizeof(f));
  2126. break;
  2127. case IF_OPTIONS_SPEED_150:
  2128. f.Num = 3;
  2129. f.Den = 2;
  2130. p->Player->Set(p->Player,PLAYER_PLAY_SPEED,&f,sizeof(f));
  2131. break;
  2132. case IF_OPTIONS_SPEED_200:
  2133. f.Num = 2;
  2134. f.Den = 1;
  2135. p->Player->Set(p->Player,PLAYER_PLAY_SPEED,&f,sizeof(f));
  2136. break;
  2137. case IF_OPTIONS_SPEED_80:
  2138. f.Num = 8;
  2139. f.Den = 10;
  2140. p->Player->Set(p->Player,PLAYER_PLAY_SPEED,&f,sizeof(f));
  2141. break;
  2142. case IF_OPTIONS_SPEED_90:
  2143. f.Num = 9;
  2144. f.Den = 10;
  2145. p->Player->Set(p->Player,PLAYER_PLAY_SPEED,&f,sizeof(f));
  2146. break;
  2147. case IF_OPTIONS_SPEED_110:
  2148. f.Num = 11;
  2149. f.Den = 10;
  2150. p->Player->Set(p->Player,PLAYER_PLAY_SPEED,&f,sizeof(f));
  2151. break;
  2152. case IF_OPTIONS_SPEED_120:
  2153. f.Num = 12;
  2154. f.Den = 10;
  2155. p->Player->Set(p->Player,PLAYER_PLAY_SPEED,&f,sizeof(f));
  2156. break;
  2157. case IF_OPTIONS_SPEED_BENCHMARK:
  2158. f.Num = 0;
  2159. f.Den = 1;
  2160. p->Player->Set(p->Player,PLAYER_PLAY_SPEED,&f,sizeof(f));
  2161. break;
  2162. case IF_OPTIONS_VIDEO_TURNOFF:
  2163. p->Player->Set(p->Player,PLAYER_VOUTPUTID,&Zero,sizeof(Zero));
  2164. break;
  2165. case IF_OPTIONS_AUDIO_TURNOFF:
  2166. p->Player->Set(p->Player,PLAYER_AOUTPUTID,&Zero,sizeof(Zero));
  2167. UpdateVolume(p);
  2168. break;
  2169. case IF_OPTIONS_SUBTITLE_STREAM_NONE:
  2170. i = MAXSTREAM;
  2171. p->Player->Set(p->Player,PLAYER_SUBSTREAM,&i,sizeof(i));
  2172. break;
  2173. }
  2174. if (Cmd >= IF_CHAPTER && Cmd < IF_CHAPTER+100)
  2175. {
  2176. tick_t Time = PlayerGetChapter(p->Player,Cmd-IF_CHAPTER,NULL,0);
  2177. if (Time>=0)
  2178. p->Player->Set(p->Player,PLAYER_POSITION,&Time,sizeof(tick_t));
  2179. }
  2180. if (Cmd >= IF_STREAM_AUDIO && Cmd < IF_STREAM_AUDIO+MAXSTREAM)
  2181. {
  2182. i = Cmd-IF_STREAM_AUDIO;
  2183. p->Player->Set(p->Player,PLAYER_ASTREAM,&i,sizeof(i));
  2184. p->Player->Set(p->Player,PLAYER_RESYNC,NULL,0);
  2185. }
  2186. if (Cmd >= IF_STREAM_VIDEO && Cmd < IF_STREAM_VIDEO+MAXSTREAM)
  2187. {
  2188. i = Cmd-IF_STREAM_VIDEO;
  2189. p->Player->Set(p->Player,PLAYER_VSTREAM,&i,sizeof(i));
  2190. p->Player->Set(p->Player,PLAYER_RESYNC,NULL,0);
  2191. }
  2192. if (Cmd >= IF_STREAM_SUBTITLE && Cmd < IF_STREAM_SUBTITLE+MAXSTREAM)
  2193. {
  2194. i = Cmd-IF_STREAM_SUBTITLE;
  2195. p->Player->Set(p->Player,PLAYER_SUBSTREAM,&i,sizeof(i));
  2196. p->Player->Set(p->Player,PLAYER_RESYNC,NULL,0);
  2197. }
  2198. if (Cmd >= IF_VIDEO && Cmd < IF_VIDEO+ARRAYCOUNT(p->VOutput,int))
  2199. {
  2200. b = 0;
  2201. p->Player->Set(p->Player,PLAYER_VIDEO_ACCEL,&b,sizeof(b));
  2202. p->Player->Set(p->Player,PLAYER_VOUTPUTID,ARRAYBEGIN(p->VOutput,int)+(Cmd-IF_VIDEO),sizeof(int));
  2203. }
  2204. if (Cmd >= IF_VIDEOACCEL && Cmd < IF_VIDEOACCEL+ARRAYCOUNT(p->VOutput,int))
  2205. {
  2206. b = 1;
  2207. p->Player->Set(p->Player,PLAYER_VIDEO_ACCEL,&b,sizeof(b));
  2208. p->Player->Set(p->Player,PLAYER_VOUTPUTID,ARRAYBEGIN(p->VOutput,int)+(Cmd-IF_VIDEOACCEL),sizeof(int));
  2209. }
  2210. if (Cmd >= IF_AUDIO && Cmd < IF_AUDIO+ARRAYCOUNT(p->AOutput,int))
  2211. {
  2212. p->Player->Set(p->Player,PLAYER_AOUTPUTID,ARRAYBEGIN(p->AOutput,int)+(Cmd-IF_AUDIO),sizeof(int));
  2213. UpdateVolume(p);
  2214. }
  2215. if (p->Focus && p->Clipping)
  2216. UpdateClipping(p,0,1); // maybe overlapping window is gone
  2217. return ERR_INVALID_PARAM;
  2218. }
  2219. static int PlayerNotify(intface* p,int Id,int Value)
  2220. {
  2221. if (Id == PLAYER_TITLE)
  2222. {
  2223. p->TitleTimeWidth = 0;
  2224. if (Value)
  2225. p->TitleTime = -1;
  2226. if (p->WndTitle && !p->FullScreen)
  2227. InvalidateRect(p->WndTitle,NULL,1); // redraws timer too!
  2228. if (!p->Win.FullScreen && !p->Bench && p->InSeek && p->Capture)
  2229. PostMessage(p->Win.Wnd,MSG_PLAYER,PLAYER_PERCENT,Value);
  2230. }
  2231. else
  2232. if (Id == PLAYER_PERCENT)
  2233. {
  2234. if (!p->Win.FullScreen && !p->Bench && (!p->InSeek || !p->Capture))
  2235. PostMessage(p->Win.Wnd,MSG_PLAYER,PLAYER_PERCENT,Value);
  2236. }
  2237. else
  2238. PostMessage(p->Win.Wnd,MSG_PLAYER,Id,Value);
  2239. return ERR_NONE;
  2240. }
  2241. static int ErrorNotify(intface* p,int Param,int Param2)
  2242. {
  2243. const tchar_t* Msg = (const tchar_t*)Param2;
  2244. if (GetCurrentThreadId() != p->ThreadId)
  2245. PostMessage(p->Win.Wnd,MSG_ERROR,0,(LPARAM)tcsdup(Msg));
  2246. else
  2247. ShowError2(p,Msg);
  2248. return ERR_NONE;
  2249. }
  2250. static int KeyRotate(intface* p,int Code)
  2251. {
  2252. int i;
  2253. int Dir;
  2254. if (!QueryAdvanced(ADVANCED_KEYFOLLOWDIR))
  2255. return Code;
  2256. switch (Code)
  2257. {
  2258. case VK_UP: i=1; break;
  2259. case VK_RIGHT: i=2; break;
  2260. case VK_DOWN: i=3; break;
  2261. case VK_LEFT: i=4; break;
  2262. default: return Code;
  2263. }
  2264. p->Player->Get(p->Player,PLAYER_REL_DIR,&Dir,sizeof(Dir));
  2265. if (Dir & DIR_SWAPXY)
  2266. i += (Dir & DIR_MIRRORUPDOWN) ? 1:3;
  2267. else
  2268. i += (Dir & DIR_MIRRORUPDOWN) ? 2:0;
  2269. if (i>4) i-=4;
  2270. switch (i)
  2271. {
  2272. case 1: Code = VK_UP; break;
  2273. case 2: Code = VK_RIGHT; break;
  2274. case 3: Code = VK_DOWN; break;
  2275. case 4: Code = VK_LEFT; break;
  2276. }
  2277. return Code;
  2278. }
  2279. static void DefaultSkin(intface* p);
  2280. static NOINLINE void UpdatePosition(intface* p)
  2281. {
  2282. UpdateTrackPos(p);
  2283. UpdateTitleTime(p);
  2284. }
  2285. static const int SkinCmd[MAX_SKINITEM] =
  2286. {
  2287. 0,
  2288. 0,
  2289. 0,
  2290. 0,
  2291. 0,
  2292. IF_PLAY,
  2293. IF_STOP,
  2294. IF_NEXT,
  2295. IF_PREV,
  2296. IF_OPTIONS_FULLSCREEN,
  2297. IF_FASTFORWARD,
  2298. IF_FILE_PLAYLIST,
  2299. IF_FILE_OPENFILE,
  2300. IF_OPTIONS_MUTE,
  2301. IF_OPTIONS_REPEAT,
  2302. IF_SKIN0,
  2303. IF_SKIN1,
  2304. IF_OPTIONS_ROTATE,
  2305. 0,
  2306. IF_PLAY_FULLSCREEN,
  2307. IF_FILE_EXIT,
  2308. };
  2309. static bool_t Proc(intface* p, int Msg, uint32_t wParam, uint32_t lParam, int* Result)
  2310. {
  2311. tick_t t;
  2312. bool_t b;
  2313. int i,Key;
  2314. PAINTSTRUCT Paint;
  2315. notify Notify;
  2316. switch (Msg) 
  2317. {
  2318. case WM_CANCELMODE:
  2319. if (p->InSkin>0)
  2320. {
  2321. p->InSkin = 0;
  2322. ReleaseCapture();
  2323. }
  2324. if (p->InVol)
  2325. {
  2326. p->InVol = 0;
  2327. ReleaseCapture();
  2328. }
  2329. if (p->InSeek)
  2330. StopSeek(p);
  2331. if (IsOverlay(p))
  2332. {
  2333. //delayed clipping (don't want to turn off overlay, just because a toolbar button was pressed)
  2334. SetTimer(p->Win.Wnd,TIMER_CLIPPING2,CLIPPING2_CYCLE,NULL);
  2335. break;
  2336. }
  2337. // no break
  2338. #if !defined(TARGET_WINCE)
  2339. case WM_INITMENU:
  2340. #endif
  2341. UpdateClipping(p,1,1); // force clipping mode
  2342. break;
  2343. case WM_PAINT:
  2344. BeginPaint(p->Win.Wnd,&Paint);
  2345. if (p->Skin[p->SkinNo].Valid)
  2346. SkinDraw(&p->Skin[p->SkinNo],Paint.hdc,&p->SkinArea);
  2347. p->Player->Paint(p->Player,Paint.hdc,p->Offset.x,p->Offset.y);
  2348. EndPaint(p->Win.Wnd,&Paint);
  2349. break;
  2350. #if defined(TARGET_WINCE)
  2351. case WM_CTLCOLORSTATIC:
  2352. *Result = (LRESULT) GetSysColorBrush(COLOR_BTNFACE);
  2353. return 1;
  2354. #endif
  2355. case WM_SYSCHAR:
  2356. if (wParam == 13) //Alt+Enter
  2357. PostMessage(p->Win.Wnd,WM_COMMAND,IF_OPTIONS_FULLSCREEN,0);
  2358. break;
  2359. case WM_TIMER:
  2360. if (wParam == TIMER_TITLESCROLL)
  2361. TitleScroll(p);
  2362. if (wParam == TIMER_SLIDERINVOL)
  2363. UpdateVol(p);
  2364. if (wParam == TIMER_SLIDERINSEEK && !p->Win.FullScreen)
  2365. UpdatePosition(p);
  2366. if (wParam == TIMER_KEYINSEEK)
  2367. StopSeek(p);
  2368. if (wParam == TIMER_CLIPPING2 && ShowVideo(p) && !p->Clipping && IsOverlapped(p))
  2369. UpdateClipping(p,1,1);
  2370. if (wParam == TIMER_CLIPPING && ShowVideo(p) && p->Clipping)
  2371. UpdateClipping(p,0,1);
  2372. if (wParam == TIMER_INITING)
  2373. {
  2374. NodeRegSaveValue(0,REG_INITING,NULL,0,TYPE_INT);
  2375. KillTimer(p->Win.Wnd,TIMER_INITING);
  2376. }
  2377. if (wParam == TIMER_SLEEP && (p->Play>0 || p->FFwd>0))
  2378. SleepTimerReset();
  2379. break;
  2380. case WM_INITMENUPOPUP:
  2381. UpdateClipping(p,1,1); // force clipping mode
  2382. UpdateMenu(p);
  2383. break;
  2384. case WM_KEYUP:
  2385. #if defined(TARGET_WINCE)
  2386. if (!GetDisplayPower())
  2387. SetDisplayPower(0,1);
  2388. #endif
  2389. Key = WinKeyState(KeyRotate(p,wParam));
  2390. for (i=0;i<HOTKEYCOUNT;++i)
  2391. if (p->HotKey[i] && (p->HotKey[i] & ~HOTKEY_KEEP) == Key)
  2392. return 0;
  2393. if (p->AllKeys)
  2394. ForwardMenuButtons(&p->Win,Msg,wParam,lParam);
  2395. break;
  2396. case WM_KEYDOWN:
  2397. Key = WinKeyState(KeyRotate(p,wParam));
  2398. for (i=0;i<HOTKEYCOUNT;++i)
  2399. if (p->HotKey[i] && (p->HotKey[i] & ~HOTKEY_KEEP) == Key)
  2400. {
  2401. PostMessage(p->Win.Wnd,WM_COMMAND,HotKey[i],0);
  2402. return 0;
  2403. }
  2404. if (p->AllKeys)
  2405. ForwardMenuButtons(&p->Win,Msg,wParam,lParam);
  2406. break;
  2407. case WM_HOTKEY:
  2408. #if defined(TARGET_WINCE)
  2409. if ((LOWORD(lParam) & MOD_KEYUP))
  2410. {
  2411. if (!GetDisplayPower())
  2412. SetDisplayPower(0,1);
  2413. }
  2414. else
  2415. #endif
  2416. PostMessage(p->Win.Wnd,WM_COMMAND,wParam,0);
  2417. *Result = 0;
  2418. return 1;
  2419. case WM_MOUSEMOVE:
  2420. if (p->InSkin>0 && (wParam & MK_LBUTTON))
  2421. SkinMouse(&p->Skin[p->SkinNo],p->InSkin,(int16_t)LOWORD(lParam)-p->SkinArea.x,(int16_t)HIWORD(lParam)-p->SkinArea.y,p->Player,NULL,p->Win.Wnd,&p->SkinArea);
  2422. return 0;
  2423. case WM_LBUTTONUP:
  2424. if (p->InSkin>0)
  2425. {
  2426. int Cmd = 0;
  2427. SkinMouse(&p->Skin[p->SkinNo],p->InSkin,(int16_t)LOWORD(lParam)-p->SkinArea.x,(int16_t)HIWORD(lParam)-p->SkinArea.y,p->Player,&Cmd,p->Win.Wnd,&p->SkinArea);
  2428. if (p->InSeek)
  2429. StopSeek(p);
  2430. p->InSkin = 0;
  2431. if (p->Capture)
  2432. {
  2433. ReleaseCapture();
  2434. p->Capture = 0;
  2435. }
  2436. if (Cmd==SKIN_VOLUME)
  2437. UpdateVolume(p);
  2438. if (Cmd>0 && SkinCmd[Cmd]>0)
  2439. Command(p,SkinCmd[Cmd]);
  2440. }
  2441. *Result = 0;
  2442. return 1;
  2443. case WM_LBUTTONDBLCLK:
  2444. case WM_LBUTTONDOWN:
  2445. DEBUG_MSG(DEBUG_WIN,T("LBUTTON"));
  2446. if ((wParam & MK_LBUTTON) && p->Focus)
  2447. {
  2448. tchar_t URL[MAXPATH];
  2449. SetDisplayPower(1,0);
  2450. if (p->Skin[p->SkinNo].Valid && !p->FullScreen)
  2451. p->InSkin = SkinMouse(&p->Skin[p->SkinNo],0,(int16_t)LOWORD(lParam)-p->SkinArea.x,(int16_t)HIWORD(lParam)-p->SkinArea.y,p->Player,NULL,p->Win.Wnd,&p->SkinArea);
  2452. else
  2453. p->InSkin = -1;
  2454. if (p->InSkin>0)
  2455. {
  2456. SetCapture(p->Win.Wnd);
  2457. p->Capture = 1;
  2458. if (p->InSkin == SKIN_SEEK)
  2459. p->InSeek = 1;
  2460. }
  2461. else if (p->InSkin<0)
  2462. {
  2463. if (!p->FullScreen && p->Player->CommentByName(p->Player,-1,T("URL"),URL,TSIZEOF(URL)))
  2464. WinShowHTML(URL);
  2465. else
  2466. if (p->Player->Get(p->Player,PLAYER_SINGLECLICKFULLSCREEN,&b,sizeof(b))==ERR_NONE && !b)
  2467. {
  2468. if (Msg == WM_LBUTTONDBLCLK)
  2469. PostMessage(p->Win.Wnd,WM_COMMAND,IF_OPTIONS_FULLSCREEN,0);
  2470. PostMessage(p->Win.Wnd,WM_COMMAND,IF_PLAY,0);
  2471. }
  2472. else
  2473. PostMessage(p->Win.Wnd,WM_COMMAND,IF_PLAY_FULLSCREEN,0);
  2474. }
  2475. }
  2476. SetForegroundWindow(p->Win.Wnd); //sometimes wince suck (triple click in opendialog)
  2477. *Result = 0;
  2478. return 1;
  2479. case WM_MOVE:
  2480. Resize(p);
  2481. break;
  2482. case WM_SETTINGCHANGE:
  2483. if (wParam == SETTINGCHANGE_RESET) 
  2484. {
  2485. p->Player->Set(p->Player,PLAYER_RESETVIDEO,NULL,0);
  2486. if (p->VolResizeNeeded2)
  2487. {
  2488. ResizeVolume(p);
  2489. if (p->VolResizeNeeded2>1)
  2490. ShowVol(p,1);
  2491. p->VolResizeNeeded2 = 0;
  2492. }
  2493. }
  2494. break;
  2495. case WM_SIZE:
  2496. #ifdef MAXIMIZE_FULLSCREEN
  2497. if (wParam == SIZE_MAXIMIZED)
  2498. {
  2499. ShowWindow(p->Win.Wnd,SW_SHOWNORMAL);
  2500. ToggleFullScreen(p,1,1);
  2501. }
  2502. else
  2503. #endif
  2504. Resize(p);
  2505. break;
  2506. case WM_SETFOCUS:
  2507. if (!p->Focus || !p->WndVolBack || (HWND)wParam != p->WndVolBack)
  2508. {
  2509. DEBUG_MSG(DEBUG_WIN,T("SETFOCUS"));
  2510. p->Focus = 1;
  2511. DIASet(0,DIA_SIP);
  2512. if (p->Wait)
  2513. {
  2514. WaitBegin();
  2515. UpdateHotKey(p,1,0);
  2516. // clipping still needed
  2517. }
  2518. else
  2519. UpdateClipping(p,0,1); // turn off clipping when no overlapping windows
  2520. UpdateClippingTimer(p);
  2521. UpdateTitleScroll(p);
  2522. }
  2523. break;
  2524. case WM_KILLFOCUS:
  2525. if (!p->WndVolBack || (HWND)wParam != p->WndVolBack)
  2526. {
  2527. DEBUG_MSG(DEBUG_WIN,T("KILLFOCUS"));
  2528. p->Focus = 0;
  2529. if (!ShowVideo(p))
  2530. UpdateClipping(p,1,1); // force clipping mode
  2531. if (p->Wait)
  2532. WaitEnd();
  2533. }
  2534. break;
  2535. case WM_ACTIVATE:
  2536. if (!p->WndVolBack || (HWND)lParam != p->WndVolBack)
  2537. {
  2538. if (LOWORD(wParam)==WA_INACTIVE) 
  2539. {
  2540. #ifdef NDEBUG
  2541. Toggle(p,PLAYER_FOREGROUND,0);
  2542. ToggleFullScreen(p,0,0); // example ATI tweaks have problem
  2543. #endif
  2544. ShowVol(p,0);
  2545. if (p->InSeek) StopSeek(p);
  2546. SetDisplayPower(1,0);
  2547. }
  2548. else
  2549. {
  2550. ShowVol(p,1);
  2551. UpdateVolume(p);
  2552. Toggle(p,PLAYER_FOREGROUND,1);
  2553. if (p->ForceFullScreen)
  2554. PostMessage(p->Win.Wnd,MSG_PLAYER,PLAYER_FULLSCREEN,1);
  2555. }
  2556. }
  2557. break;
  2558. case WM_DESTROY:
  2559. BeforeExit(p);
  2560. PostQuitMessage(0);
  2561. SkinFree(p->Skin,NULL);
  2562. Context()->Error.Func = NULL;
  2563. ArrayClear(&p->VOutput);
  2564. ArrayClear(&p->AOutput);
  2565. break;
  2566. case MSG_ERROR:
  2567. ShowError2(p,(const tchar_t*)lParam);
  2568. free((tchar_t*)lParam);
  2569. return 1;
  2570. case MSG_PLAYER:
  2571. switch (wParam)
  2572. {
  2573. case PLAYER_EXIT_AT_END:
  2574. if (p->CmdLineMode)
  2575. PostMessage(p->Win.Wnd,WM_COMMAND,IF_FILE_EXIT,0);
  2576. break;
  2577. case PLAYER_PERCENT:
  2578. UpdatePosition(p);
  2579. break;
  2580. case PLAYER_LOADMODE:
  2581. if (p->Wait != (bool_t)lParam)
  2582. {
  2583. p->Wait = lParam;
  2584. if (p->Wait)
  2585. {
  2586. if (WaitBegin())
  2587. UpdateClipping(p,1,0);
  2588. }
  2589. else
  2590. WaitEnd();
  2591. }
  2592. break;
  2593. case PLAYER_FULLSCREEN:
  2594. p->ForceFullScreen = lParam;
  2595. if (GetForegroundWindow() == p->Win.Wnd || !lParam)
  2596. {
  2597. ToggleFullScreen(p,lParam,1);
  2598. p->ForceFullScreen = 0;
  2599. }
  2600. break;
  2601. case PLAYER_PLAY:
  2602. RefreshButton(p,PLAYER_PLAY,&p->Play,IF_PLAY,0,1);
  2603. RefreshButton(p,PLAYER_FFWD,&p->FFwd,IF_FASTFORWARD,4,1);
  2604. UpdateSleepTimer(p);
  2605. break;
  2606. case PLAYER_BENCHMARK:
  2607. if (p->Bench && p->Player->Get(p->Player,PLAYER_BENCHMARK,&t,sizeof(tick_t))==ERR_NONE)
  2608. {
  2609. p->Bench = 0;
  2610. ToggleFullScreen(p,0,0);
  2611. WaitEnd();
  2612. if (p->WndTrack)
  2613. SetTrackThumb(p->WndTrack,1);
  2614. UpdateWindow(p->Win.Wnd);
  2615. WinPopupClass(BENCHRESULT_ID,&p->Win);
  2616. }
  2617. break;
  2618. }
  2619. return 1;
  2620. case WM_COPYDATA:
  2621. ProcessCmdLine(p,(const tchar_t*)((COPYDATASTRUCT*)lParam)->lpData);
  2622. return 1;
  2623. case MSG_INIT:
  2624. SetForegroundWindow(p->Win.Wnd);
  2625. if (Context()->CmdLine[0] || NodeRegLoadValue(0,REG_INITING,&i,sizeof(i),TYPE_INT))
  2626. {
  2627. b = 1; // last time crashed -> discard saved playlist
  2628. p->Player->Set(p->Player,PLAYER_DISCARDLIST,&b,sizeof(b));
  2629. }
  2630. #ifdef NDEBUG
  2631. i = 1;
  2632. NodeRegSaveValue(0,REG_INITING,&i,sizeof(int),TYPE_INT);
  2633. SetTimer(p->Win.Wnd,TIMER_INITING,INITING_CYCLE,NULL);
  2634. #endif
  2635. Context_Wnd(p->Win.Wnd);
  2636. if (Context()->CmdLine[0])
  2637. {
  2638. p->Player->Get(p->Player,PLAYER_PLAYATOPEN_FULL,&b,sizeof(b));
  2639. if (!b)
  2640. {
  2641. UpdateWindow(p->Win.Wnd); //http connection may take a while
  2642. if (p->Win.WndTB)
  2643. UpdateWindow(p->Win.WndTB);
  2644. }
  2645. ProcessCmdLine(p,Context()->CmdLine);
  2646. }
  2647. if (LangStr(LANG_ID,LANG_DEFAULT)[0]==0 &&
  2648. LangStr(LANG_ID,Context()->Lang)[0]==0)
  2649. ShowMessage(NULL,T("Language files (*.txt,*.tgz) are missing!"));
  2650. return 1;
  2651. case WM_CREATE:
  2652. WinTitle(&p->Win,Context()->ProgramName);
  2653. p->ThreadId = GetCurrentThreadId();
  2654. p->Player = (player*)Context()->Player;
  2655. p->Color = NodeEnumObject(NULL,COLOR_ID);
  2656. p->Equalizer = NodeEnumObject(NULL,EQUALIZER_ID);
  2657. p->Focus = 0;
  2658. p->Clipping = 0;
  2659. Notify.This = p;
  2660. Notify.Func = (notifyfunc)PlayerNotify;
  2661. if (p->Player)
  2662. p->Player->Set(p->Player,PLAYER_NOTIFY,&Notify,sizeof(Notify));
  2663. Context()->Error.This = p;
  2664. Context()->Error.Func = ErrorNotify;
  2665. WinMenuEnable(&p->Win,1,IF_OPTIONS_VIDEO_STREAM,0);
  2666. WinMenuEnable(&p->Win,1,IF_OPTIONS_VIDEO_STREAM,0);
  2667. WinMenuEnable(&p->Win,1,IF_OPTIONS_AUDIO_STREAM,0);
  2668. WinMenuEnable(&p->Win,1,IF_OPTIONS_VIDEO_DEVICE,0);
  2669. WinMenuEnable(&p->Win,1,IF_OPTIONS_AUDIO_DEVICE,0);
  2670. WinMenuEnable(&p->Win,1,IF_OPTIONS_ORIENTATION_FULLSCREEN,0);
  2671. WinMenuEnable(&p->Win,1,IF_OPTIONS_AUDIO_QUALITY,0);
  2672. if (!NodeEnumClass(NULL,CORETHEQUE_UI_ID))
  2673. WinMenuDelete(&p->Win,0,IF_FILE_CORETHEQUE);
  2674. if (IsAutoRun(p,Context()->CmdLine))
  2675. DefaultSkin(p);
  2676. SkinLoad(p->Skin,p->Win.Wnd,p->SkinPath);
  2677. if (!p->Skin[0].Valid)
  2678. CreateButtons(p);
  2679. UpdateSkin(p,0);
  2680. UpdateTrackBar(p,0);
  2681. UpdateTitleBar(p,0);
  2682. CreateVolumeTrack(p);
  2683. CreateDeviceMenu(p);
  2684. Resize(p);
  2685. // first finish window creation and postpone loading playlist and etc... 
  2686. PostMessage(p->Win.Wnd,MSG_INIT,0,0);
  2687. UpdateHotKey(p,1,0);
  2688. break;
  2689. }
  2690. return 0;
  2691. }
  2692. static const datatable Params[] =
  2693. {
  2694. { IF_TITLEBAR, TYPE_BOOL, DF_SETUP|DF_HIDDEN },
  2695. { IF_TRACKBAR, TYPE_BOOL, DF_SETUP|DF_HIDDEN },
  2696. { IF_TASKBAR, TYPE_BOOL, DF_SETUP|DF_HIDDEN },
  2697. { IF_SKINNO, TYPE_INT,  DF_SETUP|DF_HIDDEN },
  2698. { IF_SKINPATH, TYPE_STRING,DF_SETUP|DF_HIDDEN },
  2699. #if defined(TARGET_WINCE)
  2700. { IF_ALLKEYS, TYPE_BOOL, DF_SETUP|DF_CHECKLIST },
  2701. #endif
  2702. DATATABLE_END(INTERFACE_ID)
  2703. };
  2704. static int Enum( intface* p, int* No, datadef* Param )
  2705. {
  2706. if (NodeEnumTable(No,Param,Params)==ERR_NONE)
  2707. return ERR_NONE;
  2708. if (*No>=0 && *No<HOTKEYCOUNT)
  2709. {
  2710. memset(Param,0,sizeof(datadef));
  2711. Param->No = HotKey[*No];
  2712. Param->Type = TYPE_HOTKEY;
  2713. Param->Size = sizeof(int);
  2714. Param->Flags = DF_SETUP;
  2715. #if defined(TARGET_WINCE)
  2716. if (*No==0) Param->Flags |= DF_GAP;
  2717. #endif
  2718. Param->Class = INTERFACE_ID;
  2719. Param->Name = LangStr(INTERFACE_ID,Param->No);
  2720. return ERR_NONE;
  2721. }
  2722. return ERR_INVALID_PARAM;
  2723. }
  2724. static int Get(intface* p,int No,void* Data,int Size)
  2725. {
  2726. int Result = ERR_INVALID_PARAM;
  2727. int i;
  2728. for (i=0;i<HOTKEYCOUNT;++i)
  2729. if (HotKey[i]==No)
  2730. {
  2731. GETVALUE(p->HotKey[i],int); 
  2732. break;
  2733. }
  2734. switch (No)
  2735. {
  2736. case IF_TRACKBAR: GETVALUE(p->TrackBar,bool_t); break;
  2737. case IF_TITLEBAR: GETVALUE(p->TitleBar,bool_t); break;
  2738. case IF_TASKBAR: GETVALUE(p->TaskBar,bool_t); break;
  2739. case IF_SKINNO: GETVALUE(p->SkinNo,int); break;
  2740. case IF_SKINPATH: GETSTRING(p->SkinPath); break;
  2741. case IF_ALLKEYS: GETVALUE(p->AllKeys,bool_t); break;
  2742. }
  2743. return Result;
  2744. }
  2745. static int UpdateSkin(intface* p,bool_t Others)
  2746. {
  2747. if (!p->Player)
  2748. return ERR_NONE;
  2749. if (p->SkinNo>0 && !p->Skin[p->SkinNo].Valid)
  2750. p->SkinNo=0;
  2751. if (Others)
  2752. {
  2753. if (p->Skin[p->SkinNo].Valid)
  2754. SkinUpdate(&p->Skin[p->SkinNo],p->Player,p->Win.Wnd,&p->SkinArea);
  2755. ShowVol(p,1);
  2756. UpdateTrackBar(p,1);
  2757. InvalidateRect(p->Win.Wnd,NULL,0);
  2758. p->ClientRect.right = -1;
  2759. Resize(p);
  2760. }
  2761. RefreshButton(p,PLAYER_REPEAT,NULL,0,0,0);
  2762. RefreshButton(p,PLAYER_PLAY,NULL,0,0,0);
  2763. RefreshButton(p,PLAYER_FFWD,NULL,0,0,0);
  2764. RefreshButton(p,PLAYER_MUTE,NULL,0,0,0);
  2765. RefreshButton(p,PLAYER_FULLSCREEN,NULL,0,0,0);
  2766. if (p->TitleBrush)
  2767. {
  2768. DeleteObject(p->TitleBrush);
  2769. p->TitleBrush = NULL;
  2770. }
  2771. if (p->Skin[p->SkinNo].Valid)
  2772. {
  2773. p->TitleBrush = CreateSolidBrush(p->Skin[p->SkinNo].Item[SKIN_TITLE].ColorFace);
  2774. p->TitleFace = p->Skin[p->SkinNo].Item[SKIN_TITLE].ColorFace;
  2775. p->TitleText = p->Skin[p->SkinNo].Item[SKIN_TITLE].ColorText;
  2776. }
  2777. else
  2778. {
  2779. p->TitleBrush = NULL;
  2780. p->TitleFace = GetSysColor(COLOR_BTNFACE);
  2781. p->TitleText = GetSysColor(COLOR_BTNTEXT);
  2782. }
  2783. return ERR_NONE;
  2784. }
  2785. static int UpdateAllKeys(intface* p)
  2786. {
  2787. if (!p->AllKeys && p->AllKeysWarning)
  2788. {
  2789. int i;
  2790. for (i=0;i<HOTKEYCOUNT;++i)
  2791. if (p->HotKey[i] && WinNoHotKey(p->HotKey[i]))
  2792. {
  2793. ShowMessage(LangStr(p->Win.Node.Class,NODE_NAME),LangStr(INTERFACE_ID,IF_ALLKEYS_WARNING2));
  2794. break;
  2795. }
  2796. }
  2797. return ERR_NONE;
  2798. }
  2799. static void SetHotKey(intface* p,int i,int Key)
  2800. {
  2801. if (p->Focus && p->HotKey[i] && !p->AllKeys)
  2802. WinUnRegisterHotKey(&p->Win,HotKey[i]);
  2803. if (!p->AllKeys && p->AllKeysWarning && WinNoHotKey(Key))
  2804. ShowMessage(LangStr(p->Win.Node.Class,NODE_NAME),LangStr(INTERFACE_ID,IF_ALLKEYS_WARNING));
  2805. p->HotKey[i] = Key;
  2806. if (p->Focus && p->HotKey[i] && !p->AllKeys && !WinEssentialKey(p->HotKey[i]))
  2807. WinRegisterHotKey(&p->Win,HotKey[i],p->HotKey[i]);
  2808. }
  2809. static int Set(intface* p,int No,const void* Data,int Size)
  2810. {
  2811. int Result = ERR_INVALID_PARAM;
  2812. int i,j;
  2813. for (i=0;i<HOTKEYCOUNT;++i)
  2814. if (HotKey[i]==No)
  2815. {
  2816. int Key = *(int*)Data;
  2817. SetHotKey(p,i,0);
  2818. if (Key)
  2819. {
  2820. for (j=0;j<HOTKEYCOUNT;++j)
  2821. if ((p->HotKey[j] & ~HOTKEY_KEEP) == (Key & ~HOTKEY_KEEP))
  2822. SetHotKey(p,j,0);
  2823. SetHotKey(p,i,Key);
  2824. }
  2825. Result = ERR_NONE;
  2826. break;
  2827. }
  2828. switch (No)
  2829. {
  2830. case IF_TRACKBAR: SETVALUE(p->TrackBar,bool_t,UpdateTrackBar(p,1)); break;
  2831. case IF_TITLEBAR: SETVALUE(p->TitleBar,bool_t,UpdateTitleBar(p,1)); break;
  2832. case IF_TASKBAR: SETVALUE(p->TaskBar,bool_t,UpdateTaskBar(p)); break;
  2833. case IF_SKINNO: SETVALUE(p->SkinNo,int,UpdateSkin(p,1)); break;
  2834. case IF_SKINPATH: SETSTRING(p->SkinPath); Result = UpdateSkinFile(p); break;
  2835. case IF_ALLKEYS: SETVALUECMP(p->AllKeys,bool_t,UpdateAllKeys(p),EqBool); break;
  2836. }
  2837. return Result;
  2838. }
  2839. static void DefaultSkin(intface* p)
  2840. {
  2841. tchar_t* s;
  2842. GetModuleFileName(GetModuleHandle(NULL),p->SkinPath,MAXPATH);
  2843. s = tcsrchr(p->SkinPath,'\');
  2844. if (s) s[1]=0;
  2845. tcscat_s(p->SkinPath,TSIZEOF(p->SkinPath),T("skin.xml"));
  2846. p->SkinNo = 0;
  2847. }
  2848. static int Create(intface* p)
  2849. {
  2850. int Key;
  2851. DefaultSkin(p);
  2852. p->Win.WinWidth = 360;
  2853. p->Win.WinHeight = 240;
  2854. p->Win.Proc = Proc;
  2855. p->Win.Command = (wincommand)Command;
  2856. p->Win.MenuDef = MenuDef;
  2857. p->Win.Node.Enum = Enum;
  2858. p->Win.Node.Get = Get;
  2859. p->Win.Node.Set = Set;
  2860. p->Vol = -1;
  2861. p->TaskBar = 1;
  2862. p->TitleBar = 1;
  2863. p->TrackBar = 1;
  2864. p->MenuPreAmp = -1;
  2865. p->MenuStreams = 0;
  2866. p->MenuAStream = -1;
  2867. p->MenuVStream = -1;
  2868. p->MenuSubStream = -1;
  2869. Key = VK_RIGHT;
  2870. Set(p,IF_MOVE_FFWD,&Key,sizeof(Key));
  2871. Key = VK_LEFT;
  2872. Set(p,IF_MOVE_BACK,&Key,sizeof(Key));
  2873. Key = VK_UP;
  2874. Set(p,IF_OPTIONS_VOLUME_UP,&Key,sizeof(Key));
  2875. Key = VK_DOWN;
  2876. Set(p,IF_OPTIONS_VOLUME_DOWN,&Key,sizeof(Key));
  2877. Key = VK_RETURN;
  2878. Set(p,QueryPlatform(PLATFORM_TYPENO) == TYPE_SMARTPHONE?IF_PLAY_FULLSCREEN:IF_PLAY,&Key,sizeof(Key));
  2879. Key = 0xB0; //VK_MEDIA_NEXT_TRACK;
  2880. Set(p,IF_NEXT2,&Key,sizeof(Key));
  2881. Key = 0xB1; //VK_MEDIA_PREV_TRACK;
  2882. Set(p,IF_PREV_SMART2,&Key,sizeof(Key));
  2883. Key = 0xB2; //VK_MEDIA_STOP;
  2884. Set(p,IF_STOP,&Key,sizeof(Key));
  2885. Key = 0xB3; //VK_MEDIA_PLAY_PAUSE;
  2886. Set(p,IF_PLAYPAUSE,&Key,sizeof(Key));
  2887. #if defined(TARGET_WIN32)
  2888. Key = VK_SPACE;
  2889. Set(p,IF_PLAY,&Key,sizeof(Key));
  2890. #endif
  2891. return ERR_NONE;
  2892. }
  2893. static const nodedef IntFace =
  2894. {
  2895. sizeof(intface)|CF_GLOBAL|CF_SETTINGS,
  2896. INTERFACE_ID,
  2897. WIN_CLASS,
  2898. PRI_MAXIMUM+570,
  2899. (nodecreate)Create,
  2900. };
  2901. static const nodedef Skin =
  2902. {
  2903. 0,
  2904. SKIN_CLASS,
  2905. NODE_CLASS,
  2906. PRI_MAXIMUM,
  2907. };
  2908. void Interface_Init()
  2909. {
  2910. NodeRegisterClass(&IntFace);
  2911. NodeRegisterClass(&Skin);
  2912. }
  2913. void Interface_Done()
  2914. {
  2915. NodeUnRegisterClass(INTERFACE_ID);
  2916. NodeUnRegisterClass(SKIN_CLASS);
  2917. }
  2918. #endif