4 * Copyright 2004 Ferenc Wagner
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 /* Event object to signal successful window creation to main thread.
29 static HANDLE initEvent
;
35 /* Progress data for the text* functions and for scaling.
37 static unsigned int progressMax
, progressCurr
;
38 static double progressScale
;
40 /* Progress group counter for the gui* functions.
42 static int progressGroup
;
44 static WNDPROC DefEditProc
;
49 static const int matrix
[][4] = {{IDOK
, 0, 0, 0},
50 {IDOK
, IDCANCEL
, 0, 0},
51 {IDABORT
, IDRETRY
, IDIGNORE
, 0},
52 {IDYES
, IDNO
, IDCANCEL
, 0},
54 {IDRETRY
, IDCANCEL
, 0, 0}};
55 int type
= uType
& MB_TYPEMASK
;
56 int def
= (uType
& MB_DEFMASK
) / MB_DEFBUTTON2
;
58 return matrix
[type
][def
];
61 /* report (R_STATUS, fmt, ...) */
63 textStatus (va_list ap
)
65 char *str
= vstrmake (NULL
, ap
);
74 guiStatus (va_list ap
)
77 char *str
= vstrmake (&len
, ap
);
79 if (len
> 128) str
[129] = 0;
80 SetDlgItemTextA (dialog
, IDC_SB
, str
);
85 /* report (R_PROGRESS, barnum, steps) */
87 textProgress (va_list ap
)
89 progressGroup
= va_arg (ap
, int);
90 progressMax
= va_arg (ap
, int);
96 guiProgress (va_list ap
)
101 progressGroup
= va_arg (ap
, int);
102 progressMax
= max
= va_arg (ap
, int);
105 progressScale
= (double)0xffff / max
;
108 else progressScale
= 1;
109 pb
= GetDlgItem (dialog
, IDC_PB0
+ progressGroup
* 2);
110 SendMessageA(pb
, PBM_SETRANGE
, 0, MAKELPARAM (0, max
));
111 SendMessageA(pb
, PBM_SETSTEP
, 1, 0);
115 /* report (R_STEP, fmt, ...) */
117 textStep (va_list ap
)
119 char *str
= vstrmake (NULL
, ap
);
123 fprintf (stderr
, " (%d of %d)\n", progressCurr
, progressMax
);
131 const int pgID
= IDC_ST0
+ progressGroup
* 2;
132 char *str
= vstrmake (NULL
, ap
);
135 SetDlgItemTextA (dialog
, pgID
, str
);
136 SendDlgItemMessageA(dialog
, pgID
+1, PBM_SETPOS
,
137 progressScale
* progressCurr
, 0);
142 /* report (R_DELTA, inc, fmt, ...) */
144 textDelta (va_list ap
)
146 const int inc
= va_arg (ap
, int);
147 char *str
= vstrmake (NULL
, ap
);
151 fprintf (stderr
, " (%d of %d)\n", progressCurr
, progressMax
);
157 guiDelta (va_list ap
)
159 const int inc
= va_arg (ap
, int);
160 const int pgID
= IDC_ST0
+ progressGroup
* 2;
161 char *str
= vstrmake (NULL
, ap
);
164 SetDlgItemTextA (dialog
, pgID
, str
);
165 SendDlgItemMessageA(dialog
, pgID
+1, PBM_SETPOS
,
166 progressScale
* progressCurr
, 0);
175 fputs ("Tag: ", stderr
);
177 fputc ('\n', stderr
);
184 SetDlgItemTextA (dialog
, IDC_TAG
, tag
);
188 /* report (R_DIR, fmt, ...) */
192 char *str
= vstrmake (NULL
, ap
);
194 fputs ("Temporary directory: ", stderr
);
196 fputc ('\n', stderr
);
204 char *str
= vstrmake (NULL
, ap
);
206 SetDlgItemTextA (dialog
, IDC_DIR
, str
);
211 /* report (R_OUT, fmt, ...) */
215 char *str
= vstrmake (NULL
, ap
);
217 fputs ("Log file: ", stderr
);
219 fputc ('\n', stderr
);
227 char *str
= vstrmake (NULL
, ap
);
229 SetDlgItemTextA (dialog
, IDC_OUT
, str
);
234 /* report (R_WARNING, fmt, ...) */
236 textWarning (va_list ap
)
238 fputs ("Warning: ", stderr
);
244 guiWarning (va_list ap
)
246 char *str
= vstrmake (NULL
, ap
);
248 MessageBoxA (dialog
, str
, "Warning", MB_ICONWARNING
| MB_OK
);
253 /* report (R_ERROR, fmt, ...) */
255 textError (va_list ap
)
257 fputs ("Error: ", stderr
);
263 guiError (va_list ap
)
265 char *str
= vstrmake (NULL
, ap
);
267 MessageBoxA (dialog
, str
, "Error", MB_ICONERROR
| MB_OK
);
272 /* report (R_FATAL, fmt, ...) */
274 textFatal (va_list ap
)
281 guiFatal (va_list ap
)
287 /* report (R_ASK, type, fmt, ...) */
291 int uType
= va_arg (ap
, int);
292 int ret
= MBdefault (uType
);
293 char *str
= vstrmake (NULL
, ap
);
295 fprintf (stderr
, "Question of type %d: %s\n"
296 "Returning default: %d\n", uType
, str
, ret
);
304 int uType
= va_arg (ap
, int);
305 char *str
= vstrmake (NULL
, ap
);
306 int ret
= MessageBoxA (dialog
, str
, "Question", MB_ICONQUESTION
| uType
);
313 EditTagProc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
317 if (wParam
== 8) break; /* backspace is OK */
318 if (GetWindowTextLengthA (hwnd
) == MAXTAGLEN
||
319 !goodtagchar (wParam
)) return TRUE
;
322 return CallWindowProcA (DefEditProc
, hwnd
, msg
, wParam
, lParam
);
325 static INT_PTR CALLBACK
326 AskTagProc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
332 DefEditProc
= (WNDPROC
)SetWindowLongPtrA
333 (GetDlgItem (hwnd
, IDC_TAG
), GWLP_WNDPROC
, (LONG_PTR
)EditTagProc
);
336 switch (LOWORD (wParam
)) {
338 len
= GetWindowTextLengthA (GetDlgItem (hwnd
, IDC_TAG
));
340 report (R_WARNING
, "You must enter a tag to continue");
343 tag
= heap_alloc (len
+1);
344 GetDlgItemTextA (hwnd
, IDC_TAG
, tag
, len
+1);
345 EndDialog (hwnd
, IDOK
);
348 EndDialog (hwnd
, IDABORT
);
358 return DialogBoxA(GetModuleHandleA(NULL
), MAKEINTRESOURCEA(IDD_TAG
), dialog
, AskTagProc
);
361 static INT_PTR CALLBACK
362 AskEmailProc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
369 switch (LOWORD (wParam
)) {
371 len
= GetWindowTextLengthA (GetDlgItem (hwnd
, IDC_EMAIL
));
373 report (R_WARNING
, "You must enter an email address to continue");
376 email
= heap_alloc (len
+1);
377 GetDlgItemTextA (hwnd
, IDC_EMAIL
, email
, len
+1);
378 EndDialog (hwnd
, IDOK
);
381 EndDialog (hwnd
, IDABORT
);
391 return DialogBoxA(GetModuleHandleA(NULL
), MAKEINTRESOURCEA(IDD_EMAIL
), dialog
, AskEmailProc
);
394 /* Quiet functions */
404 return MBdefault (va_arg (ap
, int));
407 static INT_PTR CALLBACK
408 AboutProc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
412 switch (LOWORD (wParam
)) {
414 EndDialog (hwnd
, IDCANCEL
);
421 static INT_PTR CALLBACK
422 DlgProc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
426 SendMessageA(hwnd
, WM_SETICON
, ICON_SMALL
,
427 (LPARAM
)LoadImageA( GetModuleHandleA(NULL
), MAKEINTRESOURCEA(IDI_WINE
), IMAGE_ICON
,
428 GetSystemMetrics(SM_CXSMICON
), GetSystemMetrics(SM_CYSMICON
),
430 SendMessageA(hwnd
, WM_SETICON
, ICON_BIG
,
431 (LPARAM
)LoadIconA( GetModuleHandleA(NULL
), MAKEINTRESOURCEA(IDI_WINE
)));
433 if (!SetEvent (initEvent
)) {
434 report (R_STATUS
, "Can't signal main thread: %d",
443 switch (LOWORD (wParam
)) {
445 DialogBoxA(GetModuleHandleA(NULL
), MAKEINTRESOURCEA(IDD_ABOUT
), hwnd
, AboutProc
);
448 report (R_STATUS
, "Aborting, please wait...");
457 DlgThreadProc (LPVOID param
)
461 InitCommonControls ();
462 ret
= DialogBoxA(GetModuleHandleA(NULL
), MAKEINTRESOURCEA(IDD_STATUS
), NULL
, DlgProc
);
465 report (R_FATAL
, "Cannot display dialog");
468 report (R_WARNING
, "DialogBox failed: %d",
474 report (R_STATUS
, "Dialog exited: %d", ret
);
480 report (enum report_type t
, ...)
482 typedef int r_fun_t (va_list);
486 static r_fun_t
* const text_funcs
[] =
487 {textStatus
, textProgress
, textStep
, textDelta
,
488 textTag
, textDir
, textOut
,
489 textWarning
, textError
, textFatal
, textAsk
};
490 static r_fun_t
* const GUI_funcs
[] =
491 {guiStatus
, guiProgress
, guiStep
, guiDelta
,
492 guiTag
, guiDir
, guiOut
,
493 guiWarning
, guiError
, guiFatal
, guiAsk
};
494 static r_fun_t
* const quiet_funcs
[] =
495 {qNoOp
, qNoOp
, qNoOp
, qNoOp
,
497 qNoOp
, textError
, textFatal
, qAsk
};
498 static r_fun_t
* const * funcs
= NULL
;
516 initEvent
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
518 report (R_STATUS
, "Can't create event object: %d",
521 DlgThread
= CreateThread (NULL
, 0, DlgThreadProc
,
522 NULL
, 0, &DlgThreadID
);
524 report (R_STATUS
, "Can't create GUI thread: %d",
527 DWORD ret
= WaitForSingleObject (initEvent
, INFINITE
);
528 CloseHandle(DlgThread
);
534 report (R_STATUS
, "GUI creation timed out");
537 report (R_STATUS
, "Wait for GUI failed: %d",
541 report (R_STATUS
, "Wait returned %d",
550 if (t
< sizeof text_funcs
/ sizeof text_funcs
[0]) ret
= funcs
[t
](ap
);
551 else report (R_WARNING
, "unimplemented report type: %d", t
);