WinRTUtil.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include "pch.h"
  2. #include <wrl.h>
  3. #include <string>
  4. #include <DXGI.h>
  5. #include <ppltasks.h>
  6. #include "../SDLPal.Common/AsyncHelper.h"
  7. #include "../SDLPal.Common/StringHelper.h"
  8. #include "SDL.h"
  9. #include "SDL_endian.h"
  10. static std::string g_basepath, g_configpath;
  11. extern HANDLE g_eventHandle;
  12. extern "C"
  13. LPCSTR UTIL_BasePath(VOID)
  14. {
  15. if (g_basepath.empty())
  16. {
  17. auto mru_list = Windows::Storage::AccessCache::StorageApplicationPermissions::MostRecentlyUsedList;
  18. if (mru_list->Entries->Size > 0)
  19. {
  20. auto localfolder = mru_list->Entries->First()->Current.Metadata;
  21. if (localfolder->End()[-1] != L'\\') localfolder += "\\";
  22. ConvertString(localfolder, g_basepath);
  23. }
  24. }
  25. return g_basepath.c_str();
  26. }
  27. extern "C"
  28. LPCSTR UTIL_SavePath(VOID)
  29. {
  30. return UTIL_BasePath();
  31. }
  32. extern "C"
  33. LPCSTR UTIL_ConfigPath(VOID)
  34. {
  35. if (g_configpath.empty())
  36. {
  37. auto localfolder = Windows::Storage::ApplicationData::Current->LocalFolder->Path;
  38. if (localfolder->End()[-1] != L'\\') localfolder += "\\";
  39. ConvertString(localfolder, g_configpath);
  40. }
  41. return g_configpath.c_str();
  42. }
  43. extern "C"
  44. LPCSTR UTIL_ScreenShotPath(VOID)
  45. {
  46. return UTIL_BasePath();
  47. }
  48. extern "C"
  49. BOOL UTIL_GetScreenSize(DWORD *pdwScreenWidth, DWORD *pdwScreenHeight)
  50. {
  51. DXGI_OUTPUT_DESC desc;
  52. IDXGIFactory1* pFactory = nullptr;
  53. IDXGIAdapter1* pAdapter = nullptr;
  54. IDXGIOutput* pOutput = nullptr;
  55. DWORD retval = FALSE;
  56. #if _WIN32_WINNT >= 0x0A00
  57. if (Windows::System::Profile::AnalyticsInfo::VersionInfo->DeviceFamily != L"Windows.Mobile") return FALSE;
  58. #endif
  59. if (!pdwScreenWidth || !pdwScreenHeight) return FALSE;
  60. if (FAILED(CreateDXGIFactory1(IID_IDXGIFactory1, (void**)&pFactory))) goto UTIL_WP_GetScreenSize_exit;
  61. if (FAILED(pFactory->EnumAdapters1(0, &pAdapter))) goto UTIL_WP_GetScreenSize_exit;
  62. if (FAILED(pAdapter->EnumOutputs(0, &pOutput))) goto UTIL_WP_GetScreenSize_exit;
  63. if (SUCCEEDED(pOutput->GetDesc(&desc)))
  64. {
  65. #if (_WIN32_WINNT < 0x0A00) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
  66. *pdwScreenWidth = (desc.DesktopCoordinates.right - desc.DesktopCoordinates.left);
  67. *pdwScreenHeight = (desc.DesktopCoordinates.bottom - desc.DesktopCoordinates.top);
  68. #else
  69. *pdwScreenWidth = (desc.DesktopCoordinates.bottom - desc.DesktopCoordinates.top);
  70. *pdwScreenHeight = (desc.DesktopCoordinates.right - desc.DesktopCoordinates.left);
  71. #endif
  72. retval = TRUE;
  73. }
  74. UTIL_WP_GetScreenSize_exit:
  75. if (pOutput) pOutput->Release();
  76. if (pAdapter) pAdapter->Release();
  77. if (pFactory) pFactory->Release();
  78. return retval;
  79. }
  80. extern "C"
  81. BOOL UTIL_IsAbsolutePath(LPCSTR lpszFileName)
  82. {
  83. char szDrive[_MAX_DRIVE], szDir[_MAX_DIR], szFname[_MAX_FNAME], szExt[_MAX_EXT];
  84. if (_splitpath_s(lpszFileName, szDrive, szDir, szFname, szExt) == 0)
  85. return (strlen(szDrive) > 0 && (szDir[0] == '\\' || szDir[0] == '/'));
  86. else
  87. return FALSE;
  88. }
  89. extern "C"
  90. BOOL UTIL_TouchEnabled(VOID)
  91. {
  92. return (ref new Windows::Devices::Input::TouchCapabilities())->TouchPresent;
  93. }
  94. static Windows::Storage::StorageFile^ g_running_file = nullptr;
  95. static void CreateRunningFile()
  96. {
  97. // Create the 'running' file for crash detection.
  98. try { g_running_file = AWait(Windows::Storage::ApplicationData::Current->LocalFolder->CreateFileAsync("running", Windows::Storage::CreationCollisionOption::OpenIfExists), g_eventHandle); }
  99. catch (Platform::Exception^) {}
  100. }
  101. static void DeleteRunningFile()
  102. {
  103. // Delete the 'running' file on normal exit.
  104. try { if (g_running_file) AWait(g_running_file->DeleteAsync()); g_running_file = nullptr; }
  105. catch (Platform::Exception^) {}
  106. }
  107. static int SDLCALL WinRT_EventFilter(void *userdata, SDL_Event * event)
  108. {
  109. switch (event->type)
  110. {
  111. case SDL_APP_DIDENTERFOREGROUND:
  112. CreateRunningFile();
  113. break;
  114. case SDL_APP_DIDENTERBACKGROUND:
  115. case SDL_APP_TERMINATING:
  116. // Enter background or exiting, treat as normal exit
  117. DeleteRunningFile();
  118. break;
  119. }
  120. return 0;
  121. }
  122. extern "C"
  123. INT UTIL_Platform_Init(int argc, char* argv[])
  124. {
  125. CreateRunningFile();
  126. SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeRight");
  127. SDL_SetHint(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, "1");
  128. SDL_AddEventWatch(WinRT_EventFilter, nullptr);
  129. return 0;
  130. }
  131. extern "C"
  132. VOID UTIL_Platform_Quit(VOID)
  133. {
  134. DeleteRunningFile();
  135. }