23 #include <SDL_syswm.h>
39 static int xemuwingui_init (
void )
42 SDL_VERSION(&info.version);
43 SDL_GetWindowWMInfo(
sdl_win, &info);
44 xemuwinmenu.win_hwnd = info.info.win.window;
46 xemuwinmenu.num_of_hmenus = 0;
47 xemuwinmenu.num_of_items = 0;
53 static int xemuwingui_iteration (
void )
59 static int xemuwingui_file_selector (
int dialog_mode,
const char *dialog_title,
char *default_dir,
char *selected,
int path_max_size )
63 ZeroMemory(&ofn,
sizeof ofn);
64 ofn.lStructSize =
sizeof ofn;
65 ofn.hwndOwner = xemuwinmenu.win_hwnd;
66 ofn.lpstrFile = selected;
68 ofn.nMaxFile = path_max_size;
69 ofn.lpstrFilter = NULL;
71 ofn.lpstrFileTitle = NULL;
72 ofn.nMaxFileTitle = 0;
73 ofn.lpstrInitialDir = default_dir ? default_dir : NULL;
74 ofn.lpstrTitle = dialog_title;
75 switch (dialog_mode & 3) {
77 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
78 res = !GetOpenFileName(&ofn);
81 ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
82 res = !GetSaveFileName(&ofn);
85 FATAL(
"Bad dialog_mode in file selector");
88 int err = CommDlgExtendedError();
90 DEBUGGUI(
"GUI: file selector (Windows) error code: %04Xh for HWND owner %p" NL, err, ofn.hwndOwner);
92 ERROR_WINDOW(
"Windows CommDlgExtendedError: %04Xh for HWND owner %p", err, ofn.hwndOwner);
94 store_dir_from_file_selection(default_dir, selected, dialog_mode);
103 static HMENU _wingui_recursive_menu_builder (
const struct menu_st desc[],
const char *parent_name )
105 HMENU menu = CreatePopupMenu();
107 ERROR_WINDOW(
"CreatePopupMenu() failed in menu builder!");
111 FATAL(
"GUI: too many submenus!");
112 xemuwinmenu.hmenus[xemuwinmenu.num_of_hmenus++] = menu;
113 int radio_begin = xemuwinmenu.num_of_items;
114 int radio_active = xemuwinmenu.num_of_items;
115 for (
int a = 0; desc[a].
name; a++) {
122 DEBUGPRINT(
"GUI: invalid menu entry found, skipping it (item #%d of menu \"%s\")" NL, a, parent_name);
126 FATAL(
"GUI: too many items in menu builder!");
128 switch (
type & 0xFF) {
131 HMENU submenu = _wingui_recursive_menu_builder(desc[a].
user_data, desc[a].
name);
134 ret = AppendMenu(menu, MF_POPUP, (UINT_PTR)submenu, desc[a].
name);
144 xemuwinmenu.items[xemuwinmenu.num_of_items] = &desc[a];
148 ret = AppendMenu(menu, MF_STRING, ++xemuwinmenu.num_of_items, desc[a].name);
151 DEBUGPRINT(
"GUI: invalid menu item type: %d (item #%d of menu \"%s\")" NL,
type & 0xFF, a, parent_name);
159 CheckMenuItem(menu, xemuwinmenu.num_of_items, MF_CHECKED);
161 AppendMenu(menu, MF_SEPARATOR, 0, NULL);
163 radio_begin = xemuwinmenu.num_of_items;
164 radio_active = xemuwinmenu.num_of_items;
167 radio_active = xemuwinmenu.num_of_items;
169 CheckMenuRadioItem(menu, radio_begin, xemuwinmenu.num_of_items, radio_active, MF_BYCOMMAND);
170 radio_begin = xemuwinmenu.num_of_items;
171 radio_active = xemuwinmenu.num_of_items;
176 xemuwinmenu.problem = 1;
181 static void _wingui_destroy_menu (
void )
183 while (xemuwinmenu.num_of_hmenus > 0) {
184 int ret = DestroyMenu(xemuwinmenu.hmenus[--xemuwinmenu.num_of_hmenus]);
185 DEBUGGUI(
"GUI: destroyed menu at %p, retval = %d" NL, xemuwinmenu.hmenus[xemuwinmenu.num_of_hmenus], ret);
187 xemuwinmenu.num_of_hmenus = 0;
188 xemuwinmenu.num_of_items = 0;
192 static HMENU _wingui_create_popup_menu (
const struct menu_st desc[] )
194 _wingui_destroy_menu();
195 xemuwinmenu.problem = 0;
197 if (!menu || xemuwinmenu.problem) {
198 _wingui_destroy_menu();
205 static inline void _wingui_getmousecoords ( POINT *point )
208 SDL_GetMouseState(&
x, &
y);
214 static void _wingui_callback (
const struct menu_st *item )
223 static int xemuwingui_popup (
const struct menu_st desc[] )
226 HMENU menu = _wingui_create_popup_menu(desc);
231 _wingui_getmousecoords(&point);
232 if (!ClientToScreen(xemuwinmenu.win_hwnd, &point)) {
234 _wingui_destroy_menu();
238 int n = TrackPopupMenu(menu, TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, point.x, point.y, 0, xemuwinmenu.win_hwnd, NULL);
243 const struct menu_st *item = xemuwinmenu.items[n - 1];
244 _wingui_destroy_menu();
245 _wingui_callback(item);
247 _wingui_destroy_menu();
257 .description =
"Windows API based Xemu UI implementation",
258 .init = xemuwingui_init,
261 .file_selector = xemuwingui_file_selector,
262 .popup = xemuwingui_popup,