- added instructions how to update the online documentation
[bochs-mirror.git] / gui / win32dialog.cc
blob849513109cb1416d986e2f60d01862d616aaed4e
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: win32dialog.cc,v 1.63 2008/10/21 13:45:03 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 #include "win32dialog.h"
7 #if BX_USE_TEXTCONFIG && defined(WIN32)
9 #include "bochs.h"
10 #include "win32res.h"
12 const char log_choices[5][16] = {"ignore", "log", "ask user", "end simulation", "no change"};
13 static int retcode = 0;
14 static bxevent_handler old_callback = NULL;
15 static void *old_callback_arg = NULL;
16 #if BX_DEBUGGER
17 HWND hDebugDialog = NULL;
18 char *debug_cmd = NULL;
19 BOOL debug_cmd_ready = FALSE;
20 #endif
22 int AskFilename(HWND hwnd, bx_param_filename_c *param, const char *ext);
24 char *backslashes(char *s)
26 if (s != NULL) {
27 while (*s != 0) {
28 if (*s == '/') *s = '\\';
29 s++;
32 return s;
35 HWND GetBochsWindow()
37 HWND hwnd;
39 hwnd = FindWindow("Bochs for Windows", NULL);
40 if (hwnd == NULL) {
41 hwnd = GetForegroundWindow();
43 return hwnd;
46 BOOL CreateImage(HWND hDlg, int sectors, const char *filename)
48 if (sectors < 1) {
49 MessageBox(hDlg, "The disk size is invalid.", "Invalid size", MB_ICONERROR);
50 return FALSE;
52 if (lstrlen(filename) < 1) {
53 MessageBox(hDlg, "You must type a file name for the new disk image.", "Bad filename", MB_ICONERROR);
54 return FALSE;
56 int ret = SIM->create_disk_image (filename, sectors, 0);
57 if (ret == -1) { // already exists
58 int answer = MessageBox(hDlg, "File exists. Do you want to overwrite it?",
59 "File exists", MB_YESNO);
60 if (answer == IDYES)
61 ret = SIM->create_disk_image (filename, sectors, 1);
62 else
63 return FALSE;
65 if (ret == -2) {
66 MessageBox(hDlg, "I could not create the disk image. Check for permission problems or available disk space.", "Failed", MB_ICONERROR);
67 return FALSE;
69 return TRUE;
72 int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
74 char path[MAX_PATH];
76 if (uMsg == BFFM_INITIALIZED) {
77 GetCurrentDirectory(MAX_PATH, path);
78 SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)path);
80 return 0;
83 #ifndef BIF_NEWDIALOGSTYLE
84 #define BIF_NEWDIALOGSTYLE 0
85 #endif
87 int BrowseDir(const char *Title, char *result)
89 BROWSEINFO browseInfo;
90 LPITEMIDLIST ItemIDList;
91 int r = -1;
93 memset(&browseInfo,0,sizeof(BROWSEINFO));
94 browseInfo.hwndOwner = GetActiveWindow();
95 browseInfo.pszDisplayName = result;
96 browseInfo.lpszTitle = (LPCSTR)Title;
97 browseInfo.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS;
98 browseInfo.lpfn = BrowseCallbackProc;
99 ItemIDList = SHBrowseForFolder(&browseInfo);
100 if (ItemIDList != NULL) {
101 *result = 0;
102 if (SHGetPathFromIDList(ItemIDList, result)) {
103 if (result[0]) r = 0;
105 // free memory used
106 IMalloc * imalloc = 0;
107 if (SUCCEEDED(SHGetMalloc(&imalloc))) {
108 imalloc->Free(ItemIDList);
109 imalloc->Release();
112 return r;
115 static BOOL CALLBACK LogAskProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
117 BxEvent *event;
118 int level;
120 switch (msg) {
121 case WM_INITDIALOG:
122 event = (BxEvent*)lParam;
123 level = event->u.logmsg.level;
124 SetWindowText(hDlg, SIM->get_log_level_name(level));
125 SetWindowText(GetDlgItem(hDlg, IDASKDEV), event->u.logmsg.prefix);
126 SetWindowText(GetDlgItem(hDlg, IDASKMSG), event->u.logmsg.msg);
127 SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue");
128 SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and don't ask again");
129 SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation");
130 SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)");
131 #if BX_DEBUGGER
132 SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger");
133 #endif
134 SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0);
135 SetFocus(GetDlgItem(hDlg, IDASKLIST));
136 return FALSE;
137 case WM_CLOSE:
138 EndDialog(hDlg, BX_LOG_ASK_CHOICE_DIE);
139 break;
140 case WM_COMMAND:
141 switch (LOWORD(wParam)) {
142 case IDOK:
143 EndDialog(hDlg, SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_GETCURSEL, 0, 0));
144 break;
145 case IDCANCEL:
146 EndDialog(hDlg, BX_LOG_ASK_CHOICE_DIE);
147 break;
150 return FALSE;
153 static BOOL CALLBACK StringParamProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
155 static bx_param_string_c *param;
156 char buffer[512];
157 const char *title;
159 switch (msg) {
160 case WM_INITDIALOG:
161 param = (bx_param_string_c *)lParam;
162 title = param->get_label();
163 if ((title == NULL) || (strlen(title) == 0)) {
164 title = param->get_name();
166 SetWindowText(hDlg, title);
167 SetWindowText(GetDlgItem(hDlg, IDSTRING), param->getptr());
168 SendMessage(GetDlgItem(hDlg, IDSTRING), EM_SETLIMITTEXT, param->get_maxsize(), 0);
169 return TRUE;
170 break;
171 case WM_CLOSE:
172 EndDialog(hDlg, -1);
173 break;
174 case WM_COMMAND:
175 switch (LOWORD(wParam)) {
176 case IDOK:
177 GetDlgItemText(hDlg, IDSTRING, buffer, param->get_maxsize() + 1);
178 param->set(buffer);
179 EndDialog(hDlg, 1);
180 break;
181 case IDCANCEL:
182 EndDialog(hDlg, -1);
183 break;
186 return FALSE;
189 static BOOL CALLBACK FloppyDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
191 static bx_param_filename_c *param;
192 static bx_param_enum_c *status;
193 static bx_param_enum_c *devtype;
194 static bx_param_enum_c *mediatype;
195 static char origpath[MAX_PATH];
196 char mesg[MAX_PATH];
197 char path[MAX_PATH];
198 char pname[80];
199 const char *title;
200 int i, cap;
202 switch (msg) {
203 case WM_INITDIALOG:
204 param = (bx_param_filename_c *)lParam;
205 param->get_param_path(pname, 80);
206 if (!strcmp(pname, BXPN_FLOPPYA_PATH)) {
207 status = SIM->get_param_enum(BXPN_FLOPPYA_STATUS);
208 devtype = SIM->get_param_enum(BXPN_FLOPPYA_DEVTYPE);
209 mediatype = SIM->get_param_enum(BXPN_FLOPPYA_TYPE);
210 } else {
211 status = SIM->get_param_enum(BXPN_FLOPPYB_STATUS);
212 devtype = SIM->get_param_enum(BXPN_FLOPPYB_DEVTYPE);
213 mediatype = SIM->get_param_enum(BXPN_FLOPPYB_TYPE);
215 cap = devtype->get() - (int)devtype->get_min();
216 SetWindowText(GetDlgItem(hDlg, IDDEVTYPE), floppy_type_names[cap]);
217 i = 0;
218 while (floppy_type_names[i] != NULL) {
219 SendMessage(GetDlgItem(hDlg, IDMEDIATYPE), CB_ADDSTRING, 0, (LPARAM)floppy_type_names[i]);
220 SendMessage(GetDlgItem(hDlg, IDMEDIATYPE), CB_SETITEMDATA, i, (LPARAM)(mediatype->get_min() + i));
221 i++;
223 cap = mediatype->get() - (int)mediatype->get_min();
224 SendMessage(GetDlgItem(hDlg, IDMEDIATYPE), CB_SETCURSEL, cap, 0);
225 if (status->get() == BX_INSERTED) {
226 SendMessage(GetDlgItem(hDlg, IDSTATUS), BM_SETCHECK, BST_CHECKED, 0);
228 lstrcpy(origpath, param->getptr());
229 title = param->get_label();
230 if (!title) title = param->get_name();
231 SetWindowText(hDlg, title);
232 if (lstrlen(origpath) && lstrcmp(origpath, "none")) {
233 SetWindowText(GetDlgItem(hDlg, IDPATH), origpath);
235 return TRUE;
236 break;
237 case WM_CLOSE:
238 GetDlgItemText(hDlg, IDPATH, path, MAX_PATH);
239 if (lstrcmp(path, origpath)) {
240 param->set(origpath);
242 EndDialog(hDlg, -1);
243 return TRUE;
244 break;
245 case WM_COMMAND:
246 switch (LOWORD(wParam)) {
247 case IDBROWSE:
248 GetDlgItemText(hDlg, IDPATH, path, MAX_PATH);
249 param->set(backslashes(path));
250 if (AskFilename(hDlg, param, "img") > 0) {
251 SetWindowText(GetDlgItem(hDlg, IDPATH), param->getptr());
252 SendMessage(GetDlgItem(hDlg, IDSTATUS), BM_SETCHECK, BST_CHECKED, 0);
253 SendMessage(GetDlgItem(hDlg, IDMEDIATYPE), CB_SELECTSTRING, (WPARAM)-1, (LPARAM)"auto");
254 EnableWindow(GetDlgItem(hDlg, IDCREATE), FALSE);
256 return TRUE;
257 break;
258 case IDOK:
259 status->set(BX_EJECTED);
260 if (SendMessage(GetDlgItem(hDlg, IDSTATUS), BM_GETCHECK, 0, 0) == BST_CHECKED) {
261 GetDlgItemText(hDlg, IDPATH, path, MAX_PATH);
262 if (lstrlen(path) == 0) {
263 lstrcpy(path, "none");
265 } else {
266 lstrcpy(path, "none");
268 param->set(path);
269 i = SendMessage(GetDlgItem(hDlg, IDMEDIATYPE), CB_GETCURSEL, 0, 0);
270 cap = SendMessage(GetDlgItem(hDlg, IDMEDIATYPE), CB_GETITEMDATA, i, 0);
271 mediatype->set(cap);
272 if (lstrcmp(path, "none")) {
273 status->set(BX_INSERTED);
275 EndDialog(hDlg, 1);
276 return TRUE;
277 break;
278 case IDCANCEL:
279 GetDlgItemText(hDlg, IDPATH, path, MAX_PATH);
280 if (lstrcmp(path, origpath)) {
281 param->set(origpath);
283 EndDialog(hDlg, -1);
284 return TRUE;
285 break;
286 case IDMEDIATYPE:
287 if (HIWORD(wParam) == CBN_SELCHANGE) {
288 i = SendMessage(GetDlgItem(hDlg, IDMEDIATYPE), CB_GETCURSEL, 0, 0);
289 EnableWindow(GetDlgItem(hDlg, IDCREATE), (floppy_type_n_sectors[i] > 0));
291 break;
292 case IDCREATE:
293 GetDlgItemText(hDlg, IDPATH, path, MAX_PATH);
294 backslashes(path);
295 i = SendMessage(GetDlgItem(hDlg, IDMEDIATYPE), CB_GETCURSEL, 0, 0);
296 if (CreateImage(hDlg, floppy_type_n_sectors[i], path)) {
297 wsprintf(mesg, "Created a %s disk image called %s", floppy_type_names[i], path);
298 MessageBox(hDlg, mesg, "Image created", MB_OK);
300 return TRUE;
301 break;
304 return FALSE;
307 static BOOL CALLBACK Cdrom1DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
309 static bx_list_c *cdromop;
310 int device;
311 static char origpath[MAX_PATH];
312 char path[MAX_PATH];
314 switch (msg) {
315 case WM_INITDIALOG:
316 SIM->get_cdrom_options(0, &cdromop, &device);
317 lstrcpy(origpath, SIM->get_param_string("path", cdromop)->getptr());
318 if (lstrlen(origpath) && lstrcmp(origpath, "none")) {
319 SetWindowText(GetDlgItem(hDlg, IDCDROM1), origpath);
321 if (SIM->get_param_enum("status", cdromop)->get() == BX_INSERTED) {
322 SendMessage(GetDlgItem(hDlg, IDSTATUS1), BM_SETCHECK, BST_CHECKED, 0);
324 return TRUE;
325 break;
326 case WM_CLOSE:
327 if (lstrcmp(SIM->get_param_string("path", cdromop)->getptr(), origpath)) {
328 SIM->get_param_string("path", cdromop)->set(origpath);
330 EndDialog(hDlg, -1);
331 break;
332 case WM_COMMAND:
333 switch (LOWORD(wParam)) {
334 case IDBROWSE1:
335 GetDlgItemText(hDlg, IDCDROM1, path, MAX_PATH);
336 SIM->get_param_string("path", cdromop)->set(backslashes(path));
337 if (AskFilename(hDlg, (bx_param_filename_c *)SIM->get_param_string("path", cdromop), "iso") > 0) {
338 SetWindowText(GetDlgItem(hDlg, IDCDROM1), SIM->get_param_string("path", cdromop)->getptr());
339 SendMessage(GetDlgItem(hDlg, IDSTATUS1), BM_SETCHECK, BST_CHECKED, 0);
341 break;
342 case IDOK:
343 if (SendMessage(GetDlgItem(hDlg, IDSTATUS1), BM_GETCHECK, 0, 0) == BST_CHECKED) {
344 GetDlgItemText(hDlg, IDCDROM1, path, MAX_PATH);
345 if (lstrlen(path)) {
346 SIM->get_param_enum("status", cdromop)->set(BX_INSERTED);
347 if (lstrcmp(path, SIM->get_param_string("path", cdromop)->getptr())) {
348 SIM->get_param_string("path", cdromop)->set(path);
350 } else {
351 SIM->get_param_enum("status", cdromop)->set(BX_EJECTED);
353 } else {
354 SIM->get_param_enum("status", cdromop)->set(BX_EJECTED);
356 EndDialog(hDlg, 1);
357 break;
358 case IDCANCEL:
359 if (lstrcmp(SIM->get_param_string("path", cdromop)->getptr(), origpath)) {
360 SIM->get_param_string("path", cdromop)->set(origpath);
362 EndDialog(hDlg, -1);
363 break;
366 return FALSE;
369 void RuntimeDlgSetStdLogOpt(HWND hDlg)
371 int level, idx;
372 int defchoice[5];
374 for (level=0; level<5; level++) {
375 int mod = 0;
376 int first = SIM->get_log_action (mod, level);
377 BOOL consensus = true;
378 // now compare all others to first. If all match, then use "first" as
379 // the initial value.
380 for (mod=1; mod<SIM->get_n_log_modules(); mod++) {
381 if (first != SIM->get_log_action (mod, level)) {
382 consensus = false;
383 break;
386 if (consensus)
387 defchoice[level] = first;
388 else
389 defchoice[level] = 4;
391 for (level=0; level<5; level++) {
392 idx = 0;
393 SendMessage(GetDlgItem(hDlg, IDLOGEVT1+level), CB_RESETCONTENT, 0, 0);
394 for (int action=0; action<5; action++) {
395 if (((level > 1) && (action > 0)) || ((level < 2) && ((action < 2) || (action > 3)))) {
396 SendMessage(GetDlgItem(hDlg, IDLOGEVT1+level), CB_ADDSTRING, 0, (LPARAM)log_choices[action]);
397 SendMessage(GetDlgItem(hDlg, IDLOGEVT1+level), CB_SETITEMDATA, idx, action);
398 if (action == defchoice[level]) {
399 SendMessage(GetDlgItem(hDlg, IDLOGEVT1+level), CB_SETCURSEL, idx, 0);
401 idx++;
405 EnableWindow(GetDlgItem(hDlg, IDDEVLIST), FALSE);
408 void RuntimeDlgSetAdvLogOpt(HWND hDlg)
410 int idx, level, mod;
412 idx = SendMessage(GetDlgItem(hDlg, IDDEVLIST), LB_GETCURSEL, 0, 0);
413 mod = SendMessage(GetDlgItem(hDlg, IDDEVLIST), LB_GETITEMDATA, idx, 0);
414 for (level=0; level<5; level++) {
415 idx = 0;
416 SendMessage(GetDlgItem(hDlg, IDLOGEVT1+level), CB_RESETCONTENT, 0, 0);
417 for (int action=0; action<4; action++) {
418 if (((level > 1) && (action > 0)) || ((level < 2) && (action < 2))) {
419 SendMessage(GetDlgItem(hDlg, IDLOGEVT1+level), CB_ADDSTRING, 0, (LPARAM)log_choices[action]);
420 SendMessage(GetDlgItem(hDlg, IDLOGEVT1+level), CB_SETITEMDATA, idx, action);
421 if (action == SIM->get_log_action (mod, level)) {
422 SendMessage(GetDlgItem(hDlg, IDLOGEVT1+level), CB_SETCURSEL, idx, 0);
424 idx++;
430 static BOOL CALLBACK RTCdromDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
432 static int devcount;
433 static bx_list_c *cdromop[4];
434 static char origpath[4][MAX_PATH];
435 static BOOL changed;
436 int device;
437 long noticode;
438 Bit8u cdrom;
439 char path[MAX_PATH];
440 PSHNOTIFY *psn;
442 switch (msg) {
443 case WM_INITDIALOG:
444 SetForegroundWindow(GetParent(hDlg));
445 SetDlgItemText(GetParent(hDlg), IDOK, "Continue");
446 SetDlgItemText(GetParent(hDlg), IDCANCEL, "Quit");
447 // 4 cdroms supported at run time
448 devcount = 1;
449 for (cdrom=1; cdrom<4; cdrom++) {
450 if (!SIM->get_cdrom_options(cdrom, &cdromop[cdrom], &device) ||
451 !SIM->get_param_bool("present", cdromop[cdrom])->get()) {
452 EnableWindow(GetDlgItem(hDlg, IDLABEL1+cdrom), FALSE);
453 EnableWindow(GetDlgItem(hDlg, IDCDROM1+cdrom), FALSE);
454 EnableWindow(GetDlgItem(hDlg, IDBROWSE1+cdrom), FALSE);
455 EnableWindow(GetDlgItem(hDlg, IDSTATUS1+cdrom), FALSE);
456 } else {
457 lstrcpy(origpath[cdrom], SIM->get_param_string("path", cdromop[cdrom])->getptr());
458 if (lstrlen(origpath[cdrom]) && lstrcmp(origpath[cdrom], "none")) {
459 SetWindowText(GetDlgItem(hDlg, IDCDROM1+cdrom), origpath[cdrom]);
461 if (SIM->get_param_enum("status", cdromop[cdrom])->get() == BX_INSERTED) {
462 SendMessage(GetDlgItem(hDlg, IDSTATUS1+cdrom), BM_SETCHECK, BST_CHECKED, 0);
464 devcount++;
467 changed = FALSE;
468 return TRUE;
469 case WM_NOTIFY:
470 psn = (PSHNOTIFY *)lParam;
471 switch(psn->hdr.code) {
472 case PSN_APPLY:
473 if ((psn->lParam == FALSE) && changed) { // Apply pressed & change in this dialog
474 for (device=1; device<devcount; device++) {
475 if (SendMessage(GetDlgItem(hDlg, IDSTATUS1+device), BM_GETCHECK, 0, 0) == BST_CHECKED) {
476 GetDlgItemText(hDlg, IDCDROM1+device, path, MAX_PATH);
477 if (lstrlen(path)) {
478 SIM->get_param_enum("status", cdromop[device])->set(BX_INSERTED);
479 if (lstrcmp(path, SIM->get_param_string("path", cdromop[device])->getptr())) {
480 SIM->get_param_string("path", cdromop[device])->set(path);
482 } else {
483 SIM->get_param_enum("status", cdromop[device])->set(BX_EJECTED);
485 } else {
486 SIM->get_param_enum("status", cdromop[device])->set(BX_EJECTED);
489 changed = FALSE;
490 } else {
491 if (changed) {
492 for (device=1; device<devcount; device++) {
493 if (lstrcmp(SIM->get_param_string("path", cdromop[device])->getptr(), origpath[device])) {
494 SIM->get_param_string("path", cdromop[device])->set(origpath[device]);
498 retcode = BX_CI_RT_CONT;
500 return PSNRET_NOERROR;
501 case PSN_QUERYCANCEL:
502 retcode = BX_CI_RT_QUIT;
503 return TRUE;
505 break;
506 case WM_COMMAND:
507 noticode = HIWORD(wParam);
508 switch(noticode) {
509 case EN_CHANGE:
510 switch (LOWORD(wParam)) {
511 case IDCDROM2:
512 case IDCDROM3:
513 case IDCDROM4:
514 changed = TRUE;
515 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
516 break;
518 break;
519 default:
520 switch (LOWORD(wParam)) {
521 case IDBROWSE2:
522 case IDBROWSE3:
523 case IDBROWSE4:
524 device = LOWORD(wParam) - IDBROWSE1;
525 GetDlgItemText(hDlg, IDCDROM1+device, path, MAX_PATH);
526 SIM->get_param_string("path", cdromop[device])->set(backslashes(path));
527 if (AskFilename(hDlg, (bx_param_filename_c *)SIM->get_param_string("path", cdromop[device]), "iso") > 0) {
528 SetWindowText(GetDlgItem(hDlg, IDCDROM1+device), SIM->get_param_string("path", cdromop[device])->getptr());
529 SendMessage(GetDlgItem(hDlg, IDSTATUS1+device), BM_SETCHECK, BST_CHECKED, 0);
531 break;
532 case IDSTATUS2:
533 case IDSTATUS3:
534 case IDSTATUS4:
535 changed = TRUE;
536 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
537 break;
540 break;
542 return FALSE;
545 static BOOL CALLBACK RTUSBdevDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
547 static BOOL changed;
548 long noticode;
549 char buffer[MAX_PATH];
550 PSHNOTIFY *psn;
552 switch (msg) {
553 case WM_INITDIALOG:
554 if (SIM->get_param_string(BXPN_USB1_PORT1)->get_enabled()) {
555 SetDlgItemText(hDlg, IDUSBDEV1, SIM->get_param_string(BXPN_USB1_PORT1)->getptr());
556 SetDlgItemText(hDlg, IDUSBDEV2, SIM->get_param_string(BXPN_USB1_PORT2)->getptr());
557 } else {
558 EnableWindow(GetDlgItem(hDlg, IDUSBLBL1), FALSE);
559 EnableWindow(GetDlgItem(hDlg, IDUSBLBL2), FALSE);
560 EnableWindow(GetDlgItem(hDlg, IDUSBDEV1), FALSE);
561 EnableWindow(GetDlgItem(hDlg, IDUSBDEV2), FALSE);
563 changed = FALSE;
564 return TRUE;
565 case WM_NOTIFY:
566 psn = (PSHNOTIFY *)lParam;
567 switch(psn->hdr.code) {
568 case PSN_APPLY:
569 if ((psn->lParam == FALSE) && changed) { // Apply pressed & change in this dialog
570 GetDlgItemText(hDlg, IDUSBDEV1, buffer, sizeof(buffer));
571 SIM->get_param_string(BXPN_USB1_PORT1)->set(buffer);
572 GetDlgItemText(hDlg, IDUSBDEV2, buffer, sizeof(buffer));
573 SIM->get_param_string(BXPN_USB1_PORT2)->set(buffer);
575 return PSNRET_NOERROR;
576 case PSN_QUERYCANCEL:
577 retcode = BX_CI_RT_QUIT;
578 return TRUE;
580 break;
581 case WM_COMMAND:
582 noticode = HIWORD(wParam);
583 switch(noticode) {
584 case EN_CHANGE:
585 switch (LOWORD(wParam)) {
586 case IDUSBDEV1:
587 case IDUSBDEV2:
588 changed = TRUE;
589 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
590 break;
592 break;
594 break;
596 return FALSE;
599 static BOOL CALLBACK RTLogOptDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
601 static BOOL advanced;
602 static BOOL changed;
603 int idx, level, mod, value;
604 long noticode;
605 char prefix[8];
606 PSHNOTIFY *psn;
608 switch (msg) {
609 case WM_INITDIALOG:
610 idx = 0;
611 for (mod=0; mod<SIM->get_n_log_modules(); mod++) {
612 if (strcmp(SIM->get_prefix(mod), "[ ]")) {
613 lstrcpyn(prefix, SIM->get_prefix(mod), sizeof(prefix));
614 lstrcpy(prefix, prefix+1);
615 prefix[5] = 0;
616 SendMessage(GetDlgItem(hDlg, IDDEVLIST), LB_ADDSTRING, 0, (LPARAM)prefix);
617 SendMessage(GetDlgItem(hDlg, IDDEVLIST), LB_SETITEMDATA, idx, mod);
618 idx++;
621 RuntimeDlgSetStdLogOpt(hDlg);
622 advanced = FALSE;
623 changed = FALSE;
624 return TRUE;
625 case WM_NOTIFY:
626 psn = (PSHNOTIFY *)lParam;
627 switch(psn->hdr.code) {
628 case PSN_APPLY:
629 if ((psn->lParam == FALSE) && changed) { // Apply pressed & change in this dialog
630 if (advanced) {
631 idx = SendMessage(GetDlgItem(hDlg, IDDEVLIST), LB_GETCURSEL, 0, 0);
632 mod = SendMessage(GetDlgItem(hDlg, IDDEVLIST), LB_GETITEMDATA, idx, 0);
633 for (level=0; level<5; level++) {
634 idx = SendMessage(GetDlgItem(hDlg, IDLOGEVT1+level), CB_GETCURSEL, 0, 0);
635 value = SendMessage(GetDlgItem(hDlg, IDLOGEVT1+level), CB_GETITEMDATA, idx, 0);
636 SIM->set_log_action (mod, level, value);
638 EnableWindow(GetDlgItem(hDlg, IDDEVLIST), TRUE);
639 } else {
640 for (level=0; level<5; level++) {
641 idx = SendMessage(GetDlgItem(hDlg, IDLOGEVT1+level), CB_GETCURSEL, 0, 0);
642 value = SendMessage(GetDlgItem(hDlg, IDLOGEVT1+level), CB_GETITEMDATA, idx, 0);
643 if (value < 4) {
644 // set new default
645 SIM->set_default_log_action (level, value);
646 // apply that action to all modules (devices)
647 SIM->set_log_action (-1, level, value);
651 EnableWindow(GetDlgItem(hDlg, IDADVLOGOPT), TRUE);
652 changed = FALSE;
654 return PSNRET_NOERROR;
655 case PSN_QUERYCANCEL:
656 retcode = BX_CI_RT_QUIT;
657 return TRUE;
659 break;
660 case WM_COMMAND:
661 noticode = HIWORD(wParam);
662 switch(noticode) {
663 case CBN_SELCHANGE: /* LBN_SELCHANGE is the same value */
664 switch (LOWORD(wParam)) {
665 case IDDEVLIST:
666 RuntimeDlgSetAdvLogOpt(hDlg);
667 break;
668 case IDLOGEVT1:
669 case IDLOGEVT2:
670 case IDLOGEVT3:
671 case IDLOGEVT4:
672 case IDLOGEVT5:
673 if (!changed) {
674 EnableWindow(GetDlgItem(hDlg, IDADVLOGOPT), FALSE);
675 if (advanced) {
676 EnableWindow(GetDlgItem(hDlg, IDDEVLIST), FALSE);
678 changed = TRUE;
679 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
681 break;
683 break;
684 default:
685 switch (LOWORD(wParam)) {
686 case IDADVLOGOPT:
687 if (SendMessage(GetDlgItem(hDlg, IDADVLOGOPT), BM_GETCHECK, 0, 0) == BST_CHECKED) {
688 EnableWindow(GetDlgItem(hDlg, IDDEVLIST), TRUE);
689 SendMessage(GetDlgItem(hDlg, IDDEVLIST), LB_SETCURSEL, 0, 0);
690 RuntimeDlgSetAdvLogOpt(hDlg);
691 advanced = TRUE;
692 } else {
693 SendMessage(GetDlgItem(hDlg, IDDEVLIST), LB_SETCURSEL, (WPARAM)-1, 0);
694 RuntimeDlgSetStdLogOpt(hDlg);
695 advanced = FALSE;
697 break;
700 break;
702 return FALSE;
705 static BOOL CALLBACK RTMiscDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
707 static BOOL changed;
708 int value;
709 long noticode;
710 char buffer[32];
711 PSHNOTIFY *psn;
713 switch (msg) {
714 case WM_INITDIALOG:
715 SetDlgItemInt(hDlg, IDVGAUPDATE, SIM->get_param_num(BXPN_VGA_UPDATE_INTERVAL)->get(), FALSE);
716 SetDlgItemInt(hDlg, IDKBDPASTE, SIM->get_param_num(BXPN_KBD_PASTE_DELAY)->get(), FALSE);
717 if (SIM->get_param_num(BXPN_MOUSE_ENABLED)->get()) {
718 SendMessage(GetDlgItem(hDlg, IDMOUSE), BM_SETCHECK, BST_CHECKED, 0);
720 SetDlgItemText(hDlg, IDUSERBTN, SIM->get_param_string(BXPN_USER_SHORTCUT)->getptr());
721 SetDlgItemInt(hDlg, IDSB16TIMER, SIM->get_param_num(BXPN_SB16_DMATIMER)->get(), FALSE);
722 SetDlgItemInt(hDlg, IDSBLOGLEV, SIM->get_param_num(BXPN_SB16_LOGLEVEL)->get(), FALSE);
723 changed = FALSE;
724 return TRUE;
725 case WM_NOTIFY:
726 psn = (PSHNOTIFY *)lParam;
727 switch(psn->hdr.code) {
728 case PSN_APPLY:
729 if ((psn->lParam == FALSE) && changed) { // Apply pressed & change in this dialog
730 value = GetDlgItemInt(hDlg, IDVGAUPDATE, NULL, FALSE);
731 SIM->get_param_num(BXPN_VGA_UPDATE_INTERVAL)->set(value);
732 value = GetDlgItemInt(hDlg, IDKBDPASTE, NULL, FALSE);
733 SIM->get_param_num(BXPN_KBD_PASTE_DELAY)->set(value);
734 value = SendMessage(GetDlgItem(hDlg, IDMOUSE), BM_GETCHECK, 0, 0);
735 SIM->get_param_num(BXPN_MOUSE_ENABLED)->set(value==BST_CHECKED);
736 GetDlgItemText(hDlg, IDUSERBTN, buffer, sizeof(buffer));
737 SIM->get_param_string(BXPN_USER_SHORTCUT)->set(buffer);
738 value = GetDlgItemInt(hDlg, IDSB16TIMER, NULL, FALSE);
739 SIM->get_param_num(BXPN_SB16_DMATIMER)->set(value);
740 value = GetDlgItemInt(hDlg, IDSBLOGLEV, NULL, FALSE);
741 SIM->get_param_num(BXPN_SB16_LOGLEVEL)->set(value);
742 changed = FALSE;
744 return PSNRET_NOERROR;
745 case PSN_QUERYCANCEL:
746 retcode = BX_CI_RT_QUIT;
747 return TRUE;
749 break;
750 case WM_COMMAND:
751 noticode = HIWORD(wParam);
752 switch(noticode) {
753 case EN_CHANGE:
754 switch (LOWORD(wParam)) {
755 case IDVGAUPDATE:
756 case IDKBDPASTE:
757 case IDUSERBTN:
758 case IDSB16TIMER:
759 case IDSBLOGLEV:
760 changed = TRUE;
761 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
762 break;
764 break;
765 default:
766 switch (LOWORD(wParam)) {
767 case IDMOUSE:
768 changed = TRUE;
769 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
770 break;
773 break;
775 return FALSE;
778 void LogAskDialog(BxEvent *event)
780 event->retcode = DialogBoxParam(NULL, MAKEINTRESOURCE(ASK_DLG), GetBochsWindow(),
781 (DLGPROC)LogAskProc, (LPARAM)event);
784 int AskFilename(HWND hwnd, bx_param_filename_c *param, const char *ext)
786 OPENFILENAME ofn;
787 int ret;
788 DWORD errcode;
789 char filename[MAX_PATH];
790 const char *title;
791 char errtext[80];
793 param->get(filename, MAX_PATH);
794 // common file dialogs don't accept raw device names
795 if ((isalpha(filename[0])) && (filename[1] == ':') && (strlen(filename) == 2)) {
796 filename[0] = 0;
798 title = param->get_label();
799 if (!title) title = param->get_name();
800 memset(&ofn, 0, sizeof(OPENFILENAME));
801 ofn.lStructSize = sizeof(OPENFILENAME);
802 ofn.hwndOwner = hwnd;
803 ofn.lpstrFile = filename;
804 ofn.nMaxFile = MAX_PATH;
805 ofn.lpstrInitialDir = bx_startup_flags.initial_dir;
806 ofn.lpstrTitle = title;
807 ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
808 ofn.lpstrDefExt = ext;
809 if (!lstrcmp(ext, "img")) {
810 ofn.lpstrFilter = "Floppy image files (*.img)\0*.img\0All files (*.*)\0*.*\0";
811 } else if (!lstrcmp(ext, "iso")) {
812 ofn.lpstrFilter = "CD-ROM image files (*.iso)\0*.iso\0All files (*.*)\0*.*\0";
813 } else if (!lstrcmp(ext, "txt")) {
814 ofn.lpstrFilter = "Text files (*.txt)\0*.txt\0All files (*.*)\0*.*\0";
815 } else {
816 ofn.lpstrFilter = "All files (*.*)\0*.*\0";
818 if (param->get_options()->get() & bx_param_filename_c::SAVE_FILE_DIALOG) {
819 ofn.Flags |= OFN_OVERWRITEPROMPT;
820 ret = GetSaveFileName(&ofn);
821 } else {
822 ofn.Flags |= OFN_FILEMUSTEXIST;
823 ret = GetOpenFileName(&ofn);
825 param->set(filename);
826 if (ret == 0) {
827 errcode = CommDlgExtendedError();
828 if (errcode == 0) {
829 ret = -1;
830 } else {
831 if (errcode == 0x3002) {
832 wsprintf(errtext, "CommDlgExtendedError: invalid filename");
833 } else {
834 wsprintf(errtext, "CommDlgExtendedError returns 0x%04x", errcode);
836 MessageBox(hwnd, errtext, "Error", MB_ICONERROR);
839 return ret;
842 int AskString(bx_param_string_c *param)
844 return DialogBoxParam(NULL, MAKEINTRESOURCE(STRING_DLG), GetBochsWindow(),
845 (DLGPROC)StringParamProc, (LPARAM)param);
848 int FloppyDialog(bx_param_filename_c *param)
850 return DialogBoxParam(NULL, MAKEINTRESOURCE(FLOPPY_DLG), GetBochsWindow(),
851 (DLGPROC)FloppyDlgProc, (LPARAM)param);
854 int Cdrom1Dialog()
856 return DialogBox(NULL, MAKEINTRESOURCE(CDROM1_DLG), GetBochsWindow(),
857 (DLGPROC)Cdrom1DlgProc);
860 int RuntimeOptionsDialog()
862 PROPSHEETPAGE psp[4];
863 PROPSHEETHEADER psh;
864 int i;
866 memset(psp,0,sizeof(psp));
867 for (i = 0; i < 4; i++) {
868 psp[i].dwSize = sizeof(PROPSHEETPAGE);
869 psp[i].dwFlags = PSP_DEFAULT;
870 psp[i].hInstance = NULL;
872 psp[0].pszTemplate = MAKEINTRESOURCE(RT_CDROM_DLG);
873 psp[0].pfnDlgProc = RTCdromDlgProc;
874 psp[1].pszTemplate = MAKEINTRESOURCE(RT_USBDEV_DLG);
875 psp[1].pfnDlgProc = RTUSBdevDlgProc;
876 psp[2].pszTemplate = MAKEINTRESOURCE(RT_LOGOPT_DLG);
877 psp[2].pfnDlgProc = RTLogOptDlgProc;
878 psp[3].pszTemplate = MAKEINTRESOURCE(RT_MISC_DLG);
879 psp[3].pfnDlgProc = RTMiscDlgProc;
881 memset(&psh,0,sizeof(PROPSHEETHEADER));
882 psh.dwSize = sizeof(PROPSHEETHEADER);
883 psh.dwFlags = PSH_PROPSHEETPAGE;
884 psh.hwndParent = GetBochsWindow();
885 psh.hInstance = NULL;
886 psh.pszCaption = "Runtime Options";
887 psh.nPages = 4;
888 psh.ppsp = (LPCPROPSHEETPAGE)&psp;
890 PropertySheet(&psh);
891 PostMessage(GetBochsWindow(), WM_SETFOCUS, 0, 0);
892 return retcode;
895 BxEvent* win32_notify_callback(void *unused, BxEvent *event)
897 int opts;
898 bx_param_c *param;
899 bx_param_string_c *sparam;
900 #if BX_DEBUGGER
901 char debug_msg[1024];
902 int i, j;
903 #endif
905 event->retcode = -1;
906 switch (event->type)
908 case BX_SYNC_EVT_LOG_ASK:
909 LogAskDialog(event);
910 return event;
911 #if BX_DEBUGGER
912 case BX_SYNC_EVT_GET_DBG_COMMAND:
914 debug_cmd = new char[512];
915 SendMessage(hDebugDialog, WM_USER, 0x1234, 1);
916 debug_cmd_ready = FALSE;
917 SendMessage(hDebugDialog, WM_USER, 0x1234, 2);
918 while (!debug_cmd_ready && (hDebugDialog != NULL)) {
919 Sleep(10);
921 if (hDebugDialog == NULL) {
922 lstrcpy(debug_cmd, "q");
923 } else {
924 SendMessage(hDebugDialog, WM_USER, 0x1234, 0);
926 event->u.debugcmd.command = debug_cmd;
927 event->retcode = 1;
928 return event;
930 case BX_ASYNC_EVT_DBG_MSG:
931 lstrcpy(debug_msg, (char*)event->u.logmsg.msg);
932 for (i = 0; i < lstrlen(debug_msg); i++) {
933 if (debug_msg[i] == 10) {
934 for (j = lstrlen(debug_msg); j >= i; j--) debug_msg[j+1] = debug_msg[j];
935 debug_msg[i] = 13;
936 i++;
939 SendMessage(hDebugDialog, WM_USER, 0x5678, (LPARAM)debug_msg);
940 // free the char* which was allocated in dbg_printf
941 delete [] ((char*)event->u.logmsg.msg);
942 return event;
943 #endif
944 case BX_SYNC_EVT_ASK_PARAM:
945 param = event->u.param.param;
946 if (param->get_type() == BXT_PARAM_STRING) {
947 sparam = (bx_param_string_c *)param;
948 opts = sparam->get_options()->get();
949 if (opts & sparam->IS_FILENAME) {
950 if (opts & sparam->SELECT_FOLDER_DLG) {
951 event->retcode = BrowseDir(sparam->get_label(), sparam->getptr());
952 } else if (param->get_parent() == NULL) {
953 event->retcode = AskFilename(GetBochsWindow(), (bx_param_filename_c *)sparam, "txt");
954 } else {
955 event->retcode = FloppyDialog((bx_param_filename_c *)sparam);
957 return event;
958 } else {
959 event->retcode = AskString(sparam);
960 return event;
962 } else if (param->get_type() == BXT_LIST) {
963 event->retcode = Cdrom1Dialog();
964 return event;
965 } else if (param->get_type() == BXT_PARAM_BOOL) {
966 UINT flag = MB_YESNO | MB_SETFOREGROUND;
967 if (((bx_param_bool_c *)param)->get() == 0) {
968 flag |= MB_DEFBUTTON2;
970 ((bx_param_bool_c *)param)->set(MessageBox(GetActiveWindow(), param->get_description(), param->get_label(), flag) == IDYES);
971 event->retcode = 0;
972 return event;
974 case BX_ASYNC_EVT_REFRESH:
975 #if BX_DEBUGGER
976 RefreshDebugDialog();
977 return event;
978 #endif
979 case BX_SYNC_EVT_TICK: // called periodically by siminterface.
980 // fall into default case
981 default:
982 return (*old_callback)(old_callback_arg, event);
986 void win32_init_notify_callback()
988 SIM->get_notify_callback(&old_callback, &old_callback_arg);
989 assert (old_callback != NULL);
990 SIM->set_notify_callback(win32_notify_callback, NULL);
993 #endif // BX_USE_TEXTCONFIG && defined(WIN32)