Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2017
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.62 KB | None | 0 0
  1. /* RetroArch - A frontend for libretro.
  2. * Copyright (C) 2011-2017 - Daniel De Matteis
  3. *
  4. * RetroArch is free software: you can redistribute it and/or modify it under the terms
  5. * of the GNU General Public License as published by the Free Software Found-
  6. * ation, either version 3 of the License, or (at your option) any later version.
  7. *
  8. * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  9. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  10. * PURPOSE. See the GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with RetroArch.
  13. * If not, see <http://www.gnu.org/licenses/>.
  14. */
  15.  
  16. #include <stdint.h>
  17. #include <stddef.h>
  18. #include <string.h>
  19.  
  20. #include <retro_miscellaneous.h>
  21. #include <windows.h>
  22.  
  23. #include <boolean.h>
  24. #include <compat/strl.h>
  25. #include <dynamic/dylib.h>
  26. #include <lists/file_list.h>
  27. #include <file/file_path.h>
  28.  
  29. #ifdef HAVE_CONFIG_H
  30. #include "../../config.h"
  31. #endif
  32.  
  33. #ifdef HAVE_MENU
  34. #include "../../menu/menu_driver.h"
  35. #endif
  36.  
  37. #include "../frontend_driver.h"
  38. #include "../../configuration.h"
  39. #include "../../defaults.h"
  40. #include "../../runloop.h"
  41. #include "../../verbosity.h"
  42.  
  43. /* We only load this library once, so we let it be
  44. * unloaded at application shutdown, since unloading
  45. * it early seems to cause issues on some systems.
  46. */
  47.  
  48. static dylib_t dwmlib;
  49.  
  50. static bool dwm_composition_disabled;
  51.  
  52. static bool is_console_attached;
  53. static bool is_console_created;
  54. static HANDLE hDefaultConsoleOut;
  55. static HANDLE hDefaultConsoleErr;
  56.  
  57. static void gfx_dwm_shutdown(void)
  58. {
  59. if (dwmlib)
  60. dylib_close(dwmlib);
  61. dwmlib = NULL;
  62. }
  63.  
  64. static bool gfx_init_dwm(void)
  65. {
  66. static bool inited = false;
  67.  
  68. if (inited)
  69. return true;
  70.  
  71. dwmlib = dylib_load("dwmapi.dll");
  72. if (!dwmlib)
  73. {
  74. RARCH_LOG("Did not find dwmapi.dll.\n");
  75. return false;
  76. }
  77. atexit(gfx_dwm_shutdown);
  78.  
  79. HRESULT (WINAPI *mmcss)(BOOL) =
  80. (HRESULT (WINAPI*)(BOOL))dylib_proc(dwmlib, "DwmEnableMMCSS");
  81. if (mmcss)
  82. {
  83. RARCH_LOG("Setting multimedia scheduling for DWM.\n");
  84. mmcss(TRUE);
  85. }
  86.  
  87. inited = true;
  88. return true;
  89. }
  90.  
  91. static void gfx_set_dwm(void)
  92. {
  93. HRESULT ret;
  94. settings_t *settings = config_get_ptr();
  95.  
  96. if (!gfx_init_dwm())
  97. return;
  98.  
  99. if (settings->video.disable_composition == dwm_composition_disabled)
  100. return;
  101.  
  102. HRESULT (WINAPI *composition_enable)(UINT) =
  103. (HRESULT (WINAPI*)(UINT))dylib_proc(dwmlib, "DwmEnableComposition");
  104. if (!composition_enable)
  105. {
  106. RARCH_ERR("Did not find DwmEnableComposition ...\n");
  107. return;
  108. }
  109.  
  110. ret = composition_enable(!settings->video.disable_composition);
  111. if (FAILED(ret))
  112. RARCH_ERR("Failed to set composition state ...\n");
  113. dwm_composition_disabled = settings->video.disable_composition;
  114. }
  115.  
  116. static void frontend_win32_get_os(char *s, size_t len, int *major, int *minor)
  117. {
  118. uint32_t version = GetVersion();
  119.  
  120. *major = (DWORD)(LOBYTE(LOWORD(version)));
  121. *minor = (DWORD)(HIBYTE(LOWORD(version)));
  122.  
  123. switch (*major)
  124. {
  125. case 10:
  126. strlcpy(s, "Windows 10", len);
  127. break;
  128. case 6:
  129. switch (*minor)
  130. {
  131. case 3:
  132. strlcpy(s, "Windows 8.1", len);
  133. break;
  134. case 2:
  135. strlcpy(s, "Windows 8", len);
  136. break;
  137. case 1:
  138. strlcpy(s, "Windows 7/2008 R2", len);
  139. break;
  140. case 0:
  141. strlcpy(s, "Windows Vista/2008", len);
  142. break;
  143. default:
  144. break;
  145. }
  146. break;
  147. case 5:
  148. switch (*minor)
  149. {
  150. case 2:
  151. strlcpy(s, "Windows 2003", len);
  152. break;
  153. case 1:
  154. strlcpy(s, "Windows XP", len);
  155. break;
  156. case 0:
  157. strlcpy(s, "Windows 2000", len);
  158. break;
  159. }
  160. break;
  161. case 4:
  162. switch (*minor)
  163. {
  164. case 0:
  165. strlcpy(s, "Windows NT 4.0", len);
  166. break;
  167. case 90:
  168. strlcpy(s, "Windows ME", len);
  169. break;
  170. case 10:
  171. strlcpy(s, "Windows 98", len);
  172. break;
  173. }
  174. break;
  175. default:
  176. sprintf(s, "Windows %i.%i", *major, *minor);
  177. break;
  178. }
  179. }
  180.  
  181. static void frontend_win32_init(void *data)
  182. {
  183. typedef BOOL (WINAPI *isProcessDPIAwareProc)();
  184. typedef BOOL (WINAPI *setProcessDPIAwareProc)();
  185. HMODULE handle = GetModuleHandle("User32.dll");
  186. isProcessDPIAwareProc isDPIAwareProc = (isProcessDPIAwareProc)dylib_proc(handle, "IsProcessDPIAware");
  187. setProcessDPIAwareProc setDPIAwareProc = (setProcessDPIAwareProc)dylib_proc(handle, "SetProcessDPIAware");
  188.  
  189. if (isDPIAwareProc)
  190. {
  191. if (!isDPIAwareProc())
  192. {
  193. if (setDPIAwareProc)
  194. setDPIAwareProc();
  195. }
  196. }
  197.  
  198. }
  199.  
  200. enum frontend_powerstate frontend_win32_get_powerstate(int *seconds, int *percent)
  201. {
  202. SYSTEM_POWER_STATUS status;
  203. enum frontend_powerstate ret = FRONTEND_POWERSTATE_NONE;
  204.  
  205. if (!GetSystemPowerStatus(&status))
  206. return ret;
  207.  
  208. if (status.BatteryFlag == 0xFF)
  209. ret = FRONTEND_POWERSTATE_NONE;
  210. if (status.BatteryFlag & (1 << 7))
  211. ret = FRONTEND_POWERSTATE_NO_SOURCE;
  212. else if (status.BatteryFlag & (1 << 3))
  213. ret = FRONTEND_POWERSTATE_CHARGING;
  214. else if (status.ACLineStatus == 1)
  215. ret = FRONTEND_POWERSTATE_CHARGED;
  216. else
  217. ret = FRONTEND_POWERSTATE_ON_POWER_SOURCE;
  218.  
  219. *percent = (int)status.BatteryLifePercent;
  220. *seconds = (int)status.BatteryLifeTime;
  221.  
  222. #ifdef _WIN32
  223. if (*percent == 255)
  224. *percent = 0;
  225. #endif
  226. return ret;
  227. }
  228.  
  229. enum frontend_architecture frontend_win32_get_architecture(void)
  230. {
  231. /* stub */
  232. return FRONTEND_ARCH_NONE;
  233. }
  234.  
  235. static int frontend_win32_parse_drive_list(void *data)
  236. {
  237. #ifdef HAVE_MENU
  238. size_t i = 0;
  239. unsigned drives = GetLogicalDrives();
  240. char drive[] = " :\\";
  241. file_list_t *list = (file_list_t*)data;
  242.  
  243. for (i = 0; i < 32; i++)
  244. {
  245. drive[0] = 'A' + i;
  246. if (drives & (1 << i))
  247. menu_entries_append_enum(list,
  248. drive,
  249. msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR),
  250. MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR,
  251. MENU_SETTING_ACTION, 0, 0);
  252. }
  253. #endif
  254.  
  255. return 0;
  256. }
  257.  
  258. static void frontend_win32_environment_get(int *argc, char *argv[],
  259. void *args, void *params_data)
  260. {
  261. gfx_set_dwm();
  262.  
  263. fill_pathname_expand_special(g_defaults.dir.assets,
  264. ":\\assets", sizeof(g_defaults.dir.assets));
  265. fill_pathname_expand_special(g_defaults.dir.audio_filter,
  266. ":\\filters\\audio", sizeof(g_defaults.dir.audio_filter));
  267. fill_pathname_expand_special(g_defaults.dir.video_filter,
  268. ":\\filters\\video", sizeof(g_defaults.dir.video_filter));
  269. fill_pathname_expand_special(g_defaults.dir.cheats,
  270. ":\\cheats", sizeof(g_defaults.dir.cheats));
  271. fill_pathname_expand_special(g_defaults.dir.database,
  272. ":\\database\\rdb", sizeof(g_defaults.dir.database));
  273. fill_pathname_expand_special(g_defaults.dir.cursor,
  274. ":\\database\\cursors", sizeof(g_defaults.dir.cursor));
  275. fill_pathname_expand_special(g_defaults.dir.playlist,
  276. ":\\playlists", sizeof(g_defaults.dir.assets));
  277. fill_pathname_expand_special(g_defaults.dir.menu_config,
  278. ":\\config", sizeof(g_defaults.dir.menu_config));
  279. fill_pathname_expand_special(g_defaults.dir.remap,
  280. ":\\config\\remaps", sizeof(g_defaults.dir.remap));
  281. fill_pathname_expand_special(g_defaults.dir.wallpapers,
  282. ":\\assets\\wallpapers", sizeof(g_defaults.dir.wallpapers));
  283. fill_pathname_expand_special(g_defaults.dir.thumbnails,
  284. ":\\thumbnails", sizeof(g_defaults.dir.thumbnails));
  285. fill_pathname_expand_special(g_defaults.dir.overlay,
  286. ":\\overlays", sizeof(g_defaults.dir.overlay));
  287. fill_pathname_expand_special(g_defaults.dir.core,
  288. ":\\cores", sizeof(g_defaults.dir.core));
  289. fill_pathname_expand_special(g_defaults.dir.core_info,
  290. ":\\info", sizeof(g_defaults.dir.core_info));
  291. fill_pathname_expand_special(g_defaults.dir.autoconfig,
  292. ":\\autoconfig", sizeof(g_defaults.dir.autoconfig));
  293. fill_pathname_expand_special(g_defaults.dir.shader,
  294. ":\\shaders", sizeof(g_defaults.dir.shader));
  295. fill_pathname_expand_special(g_defaults.dir.core_assets,
  296. ":\\downloads", sizeof(g_defaults.dir.core_assets));
  297. fill_pathname_expand_special(g_defaults.dir.screenshot,
  298. ":\\screenshots", sizeof(g_defaults.dir.screenshot));
  299.  
  300. /* don't force this in the driver anymore, these will be handled by
  301. a dummy config file so they can be reset to content dir
  302.  
  303. fill_pathname_expand_special(g_defaults.dir.sram,
  304. ":\\saves", sizeof(g_defaults.dir.sram));
  305. fill_pathname_expand_special(g_defaults.dir.savestate,
  306. ":\\states", sizeof(g_defaults.dir.savestate));
  307. fill_pathname_expand_special(g_defaults.dir.system,
  308. ":\\system", sizeof(g_defaults.dir.system));
  309. */
  310. #ifdef HAVE_MENU
  311. #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
  312. snprintf(g_defaults.settings.menu, sizeof(g_defaults.settings.menu), "xmb");
  313. #endif
  314. #endif
  315. }
  316.  
  317. static uint64_t frontend_win32_get_mem_total(void)
  318. {
  319. /* OSes below 2000 don't have the Ex version, and non-Ex cannot work with >4GB RAM */
  320. #if _WIN32_WINNT > 0x0400
  321. MEMORYSTATUSEX mem_info;
  322. mem_info.dwLength = sizeof(MEMORYSTATUSEX);
  323. GlobalMemoryStatusEx(&mem_info);
  324. return mem_info.ullTotalPhys;
  325. #else
  326. MEMORYSTATUS mem_info;
  327. mem_info.dwLength = sizeof(MEMORYSTATUS);
  328. GlobalMemoryStatus(&mem_info);
  329. return mem_info.dwTotalPhys;
  330. #endif
  331. }
  332.  
  333. static uint64_t frontend_win32_get_mem_used(void)
  334. {
  335. /* OSes below 2000 don't have the Ex version, and non-Ex cannot work with >4GB RAM */
  336. #if _WIN32_WINNT > 0x0400
  337. MEMORYSTATUSEX mem_info;
  338. mem_info.dwLength = sizeof(MEMORYSTATUSEX);
  339. GlobalMemoryStatusEx(&mem_info);
  340. return ((frontend_win32_get_mem_total() - mem_info.ullAvailPhys));
  341. #else
  342. MEMORYSTATUS mem_info;
  343. mem_info.dwLength = sizeof(MEMORYSTATUS);
  344. GlobalMemoryStatus(&mem_info);
  345. return ((frontend_win32_get_mem_total() - mem_info.dwAvailPhys));
  346. #endif
  347. }
  348.  
  349. static void frontend_win32_attach_console(void)
  350. {
  351. #ifdef _WIN32
  352. #ifdef _WIN32_WINNT_WINXP
  353. if(is_console_attached || is_console_created)
  354. return;
  355.  
  356. if(AttachConsole(ATTACH_PARENT_PROCESS))
  357. {
  358. is_console_attached = true;
  359. }
  360. else
  361. {
  362. AllocConsole();
  363. AttachConsole( GetCurrentProcessId()) ;
  364. is_console_created = true;
  365. }
  366.  
  367. hDefaultConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
  368. hDefaultConsoleErr = GetStdHandle(STD_ERROR_HANDLE);
  369.  
  370. freopen( "CONOUT$", "w", stdout );
  371. freopen( "CONOUT$", "w", stderr );
  372.  
  373. #endif
  374. #endif
  375. }
  376.  
  377. static void frontend_win32_detach_console(void)
  378. {
  379. #if defined(_WIN32) && !defined(_XBOX)
  380. #ifdef _WIN32_WINNT_WINXP
  381. if(is_console_attached)
  382. {
  383. /* there's nothing we can do here. we can't attach it to nothing. */
  384. is_console_attached = false;
  385. }
  386. if(is_console_created)
  387. {
  388. FreeConsole();
  389. is_console_created = false;
  390. }
  391.  
  392. /* restore the original attachments */
  393. SetStdHandle(STD_OUTPUT_HANDLE, hDefaultConsoleOut);
  394. SetStdHandle(STD_ERROR_HANDLE, hDefaultConsoleErr);
  395. hDefaultConsoleOut = hDefaultConsoleErr = 0;
  396. #endif
  397. #endif
  398. }
  399.  
  400. frontend_ctx_driver_t frontend_ctx_win32 = {
  401. frontend_win32_environment_get,
  402. frontend_win32_init,
  403. NULL, /* deinit */
  404. NULL, /* exitspawn */
  405. NULL, /* process_args */
  406. NULL, /* exec */
  407. NULL, /* set_fork */
  408. NULL, /* shutdown */
  409. NULL, /* get_name */
  410. frontend_win32_get_os,
  411. NULL, /* get_rating */
  412. NULL, /* load_content */
  413. frontend_win32_get_architecture,
  414. frontend_win32_get_powerstate,
  415. frontend_win32_parse_drive_list,
  416. frontend_win32_get_mem_total,
  417. frontend_win32_get_mem_used,
  418. NULL, /* install_signal_handler */
  419. NULL, /* get_sighandler_state */
  420. NULL, /* set_sighandler_state */
  421. NULL, /* destroy_sighandler_state */
  422. frontend_win32_attach_console, /* attach_console */
  423. frontend_win32_detach_console, /* detach_console */
  424. "win32"
  425. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement