1 |
nishi |
1.1 |
/* $Id: gui.c 291 2024-10-09 03:14:51Z nishi $ */ |
2 |
|
|
|
3 |
|
|
#include "../config.h" |
4 |
|
|
|
5 |
|
|
#if defined(BUILD_GUI_VALID) |
6 |
|
|
|
7 |
|
|
#include "gui.h" |
8 |
|
|
#include "tw_server.h" |
9 |
|
|
|
10 |
|
|
#include <cm_log.h> |
11 |
|
|
|
12 |
|
|
#include <stdio.h> |
13 |
|
|
#include <windows.h> |
14 |
|
|
#include <process.h> |
15 |
|
|
#include <commctrl.h> |
16 |
|
|
|
17 |
|
|
HINSTANCE hInst; |
18 |
|
|
HBRUSH pbtewi_brush; |
19 |
|
|
HWND logarea; |
20 |
|
|
HWND button_start; |
21 |
|
|
HWND button_stop; |
22 |
|
|
HWND button_about; |
23 |
|
|
HWND button_reset; |
24 |
|
|
HWND button_exit; |
25 |
|
|
HWND statuswnd; |
26 |
|
|
HFONT monospace; |
27 |
|
|
BOOL tewi_alive; |
28 |
|
|
BOOL was_starting; |
29 |
|
|
BOOL exiting; |
30 |
|
|
BOOL idle; |
31 |
|
|
extern FILE* logfile; |
32 |
|
|
extern int running; |
33 |
|
|
|
34 |
|
|
#define WINWIDTH(rc) (rc.right - rc.left) |
35 |
|
|
#define WINHEIGHT(rc) (rc.bottom - rc.top) |
36 |
|
|
|
37 |
|
|
int startup(int argc, char** argv); |
38 |
|
|
|
39 |
|
|
void ShowBitmapSize(HWND hWnd, HDC hdc, const char* name, int x, int y, int w, int h) { |
40 |
|
|
HBITMAP hBitmap = LoadBitmap(hInst, name); |
41 |
|
|
BITMAP bmp; |
42 |
|
|
HDC hmdc; |
43 |
|
|
GetObject(hBitmap, sizeof(bmp), &bmp); |
44 |
|
|
hmdc = CreateCompatibleDC(hdc); |
45 |
|
|
SelectObject(hmdc, hBitmap); |
46 |
|
|
if(w == 0 && h == 0) { |
47 |
|
|
StretchBlt(hdc, x, y, bmp.bmWidth, bmp.bmHeight, hmdc, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY); |
48 |
|
|
} else { |
49 |
|
|
StretchBlt(hdc, x, y, w, h, hmdc, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY); |
50 |
|
|
} |
51 |
|
|
DeleteDC(hmdc); |
52 |
|
|
DeleteObject(hBitmap); |
53 |
|
|
} |
54 |
|
|
|
55 |
|
|
void ShowBitmap(HWND hWnd, HDC hdc, const char* name, int x, int y) { ShowBitmapSize(hWnd, hdc, name, x, y, 0, 0); } |
56 |
|
|
|
57 |
|
|
int max = 0; |
58 |
|
|
void AddLog(const char* str) { |
59 |
|
|
HDC hdc; |
60 |
|
|
PAINTSTRUCT ps; |
61 |
|
|
SIZE sz; |
62 |
|
|
|
63 |
|
|
SendMessage(logarea, LB_ADDSTRING, 0, (LPARAM)str); |
64 |
|
|
|
65 |
|
|
hdc = CreateCompatibleDC(NULL); |
66 |
|
|
SelectObject(hdc, monospace); |
67 |
|
|
GetTextExtentPoint32(hdc, str, strlen(str), &sz); |
68 |
|
|
DeleteDC(hdc); |
69 |
|
|
|
70 |
|
|
if(max < sz.cx) { |
71 |
|
|
max = sz.cx; |
72 |
|
|
SendMessage(logarea, LB_SETHORIZONTALEXTENT, max, 0); |
73 |
|
|
} |
74 |
|
|
} |
75 |
|
|
|
76 |
|
|
LRESULT CALLBACK VersionDialog(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { |
77 |
|
|
if(msg == WM_COMMAND) { |
78 |
|
|
if(LOWORD(wp) == IDOK) EndDialog(hWnd, IDOK); |
79 |
|
|
} else if(msg == WM_PAINT) { |
80 |
|
|
HDC hdc; |
81 |
|
|
PAINTSTRUCT ps; |
82 |
|
|
RECT size; |
83 |
|
|
|
84 |
|
|
size.left = size.top = 5; |
85 |
|
|
size.right = size.bottom = 32 + 5; |
86 |
|
|
MapDialogRect(hWnd, &size); |
87 |
|
|
|
88 |
|
|
hdc = BeginPaint(hWnd, &ps); |
89 |
|
|
ShowBitmapSize(hWnd, hdc, "TEWILOGO", size.left, size.top, WINWIDTH(size), WINWIDTH(size)); |
90 |
|
|
EndPaint(hWnd, &ps); |
91 |
|
|
} else if(msg == WM_CTLCOLORDLG || msg == WM_CTLCOLORSTATIC) { |
92 |
|
|
HDC dc = (HDC)wp; |
93 |
|
|
SetBkMode(dc, TRANSPARENT); |
94 |
|
|
return (LRESULT)GetSysColorBrush(COLOR_MENU); |
95 |
|
|
} else { |
96 |
|
|
return FALSE; |
97 |
|
|
} |
98 |
|
|
return TRUE; |
99 |
|
|
} |
100 |
|
|
|
101 |
|
|
void tewi_thread(void* ptr) { |
102 |
|
|
int st = startup(0, NULL); |
103 |
|
|
was_starting = TRUE; |
104 |
|
|
if(st == -1) { |
105 |
|
|
tewi_alive = TRUE; |
106 |
|
|
idle = FALSE; |
107 |
|
|
} else { |
108 |
|
|
cm_force_log("Config error"); |
109 |
|
|
idle = FALSE; |
110 |
|
|
_endthread(); |
111 |
|
|
} |
112 |
|
|
running = 1; |
113 |
|
|
tw_server_loop(); |
114 |
|
|
tewi_alive = FALSE; |
115 |
|
|
was_starting = TRUE; |
116 |
|
|
idle = FALSE; |
117 |
|
|
_endthread(); |
118 |
|
|
} |
119 |
|
|
|
120 |
|
|
void StartTewi(void) { |
121 |
|
|
EnableWindow(button_start, FALSE); |
122 |
|
|
EnableWindow(button_stop, FALSE); |
123 |
|
|
_beginthread(tewi_thread, 0, NULL); |
124 |
|
|
} |
125 |
|
|
|
126 |
|
|
void StopTewi(void) { |
127 |
|
|
EnableWindow(button_start, FALSE); |
128 |
|
|
EnableWindow(button_stop, FALSE); |
129 |
|
|
running = 0; |
130 |
|
|
} |
131 |
|
|
|
132 |
|
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { |
133 |
|
|
if(msg == WM_COMMAND) { |
134 |
|
|
int trig = LOWORD(wp); |
135 |
|
|
int ev = HIWORD(wp); |
136 |
|
|
if(trig == GUI_BUTTON_ABOUT) { |
137 |
|
|
if(ev == BN_CLICKED) { |
138 |
|
|
DialogBox(hInst, "VERSIONDLG", hWnd, (DLGPROC)VersionDialog); |
139 |
|
|
} |
140 |
|
|
} else if(trig == GUI_BUTTON_START) { |
141 |
|
|
if(ev == BN_CLICKED) { |
142 |
|
|
SendMessage(statuswnd, SB_SETTEXT, 0, (LPARAM) "Starting Tewi HTTPd"); |
143 |
|
|
StartTewi(); |
144 |
|
|
} |
145 |
|
|
} else if(trig == GUI_BUTTON_STOP) { |
146 |
|
|
if(ev == BN_CLICKED) { |
147 |
|
|
SendMessage(statuswnd, SB_SETTEXT, 0, (LPARAM) "Stopping Tewi HTTPd"); |
148 |
|
|
StopTewi(); |
149 |
|
|
} |
150 |
|
|
} else if(trig == GUI_BUTTON_RESET) { |
151 |
|
|
if(ev == BN_CLICKED) { |
152 |
|
|
SendMessage(logarea, LB_RESETCONTENT, 0, 0); |
153 |
|
|
max = 0; |
154 |
|
|
SendMessage(logarea, LB_SETHORIZONTALEXTENT, max, 0); |
155 |
|
|
} |
156 |
|
|
} else if(trig == GUI_BUTTON_EXIT) { |
157 |
|
|
if(ev == BN_CLICKED) { |
158 |
|
|
if(tewi_alive) { |
159 |
|
|
SendMessage(statuswnd, SB_SETTEXT, 0, (LPARAM) "Stopping Tewi HTTPd"); |
160 |
|
|
StopTewi(); |
161 |
|
|
exiting = TRUE; |
162 |
|
|
} else { |
163 |
|
|
SendMessage(hWnd, WM_CLOSE, 0, 0); |
164 |
|
|
} |
165 |
|
|
} |
166 |
|
|
} else if(trig == GUI_LOG) { |
167 |
|
|
} |
168 |
|
|
} else if(msg == WM_CLOSE) { |
169 |
|
|
DestroyWindow(hWnd); |
170 |
|
|
} else if(msg == WM_DESTROY) { |
171 |
|
|
DeleteObject(pbtewi_brush); |
172 |
|
|
PostQuitMessage(0); |
173 |
|
|
} else if(msg == WM_CREATE) { |
174 |
|
|
RECT rc, src; |
175 |
|
|
GetClientRect(hWnd, &rc); |
176 |
|
|
|
177 |
|
|
InitCommonControls(); |
178 |
|
|
|
179 |
|
|
monospace = (HFONT)GetStockObject(SYSTEM_FIXED_FONT); |
180 |
|
|
|
181 |
|
|
statuswnd = CreateStatusWindow(WS_CHILD | WS_VISIBLE | CCS_BOTTOM, NULL, hWnd, GUI_STATUS); |
182 |
|
|
SendMessage(statuswnd, SB_SIMPLE, 0, 0); |
183 |
|
|
SendMessage(statuswnd, SB_SETTEXT, 0, (LPARAM) "Welcome to Tewi HTTPd"); |
184 |
|
|
SendMessage(statuswnd, SB_GETRECT, 0, (LPARAM)&src); |
185 |
|
|
|
186 |
|
|
pbtewi_brush = CreateSolidBrush(RGB(0xf7, 0xc9, 0xf3)); |
187 |
|
|
button_start = CreateWindow("BUTTON", "&Start", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, WINWIDTH(rc) - 100, 20 * 0, 100, 20, hWnd, (HMENU)GUI_BUTTON_START, hInst, NULL); |
188 |
|
|
button_stop = CreateWindow("BUTTON", "S&top", WS_CHILD | WS_VISIBLE | WS_DISABLED | BS_PUSHBUTTON, WINWIDTH(rc) - 100, 20 * 1, 100, 20, hWnd, (HMENU)GUI_BUTTON_STOP, hInst, NULL); |
189 |
|
|
button_about = CreateWindow("BUTTON", "&About", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, WINWIDTH(rc) - 100, 20 * 2, 100, 20, hWnd, (HMENU)GUI_BUTTON_ABOUT, hInst, NULL); |
190 |
|
|
button_reset = CreateWindow("BUTTON", "&Reset", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, WINWIDTH(rc) - 100, WINHEIGHT(rc) - WINHEIGHT(src) - 20 - 20, 100, 20, hWnd, (HMENU)GUI_BUTTON_RESET, hInst, NULL); |
191 |
|
|
button_exit = CreateWindow("BUTTON", "E&xit", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, WINWIDTH(rc) - 100, WINHEIGHT(rc) - WINHEIGHT(src) - 20, 100, 20, hWnd, (HMENU)GUI_BUTTON_EXIT, hInst, NULL); |
192 |
|
|
logarea = CreateWindow("LISTBOX", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | LBS_NOINTEGRALHEIGHT | LBS_NOSEL, 0, 40, WINWIDTH(rc) - 100, WINHEIGHT(rc) - 40 - WINHEIGHT(src), hWnd, (HMENU)GUI_LOG, hInst, NULL); |
193 |
|
|
|
194 |
|
|
SendMessage(logarea, WM_SETFONT, (WPARAM)monospace, TRUE); |
195 |
|
|
|
196 |
|
|
SetTimer(hWnd, TIMER_WATCH_TEWI, 100, NULL); |
197 |
|
|
} else if(msg == WM_TIMER) { |
198 |
|
|
if(wp == TIMER_WATCH_TEWI) { |
199 |
|
|
if(idle) { |
200 |
|
|
} else if(tewi_alive) { |
201 |
|
|
if(was_starting) { |
202 |
|
|
was_starting = FALSE; |
203 |
|
|
SendMessage(statuswnd, SB_SETTEXT, 0, (LPARAM) "Started Tewi HTTPd"); |
204 |
|
|
} |
205 |
|
|
EnableWindow(button_start, FALSE); |
206 |
|
|
EnableWindow(button_stop, TRUE); |
207 |
|
|
idle = TRUE; |
208 |
|
|
} else { |
209 |
|
|
if(was_starting) { |
210 |
|
|
was_starting = FALSE; |
211 |
|
|
SendMessage(statuswnd, SB_SETTEXT, 0, (LPARAM) "Stopped Tewi HTTPd"); |
212 |
|
|
} |
213 |
|
|
EnableWindow(button_start, TRUE); |
214 |
|
|
EnableWindow(button_stop, FALSE); |
215 |
|
|
if(exiting) { |
216 |
|
|
KillTimer(hWnd, TIMER_WATCH_TEWI); |
217 |
|
|
SendMessage(hWnd, WM_CLOSE, 0, 0); |
218 |
|
|
} |
219 |
|
|
idle = TRUE; |
220 |
|
|
} |
221 |
|
|
} |
222 |
|
|
} else if(msg == WM_PAINT) { |
223 |
|
|
HDC hdc; |
224 |
|
|
PAINTSTRUCT ps; |
225 |
|
|
RECT rc; |
226 |
|
|
RECT fill; |
227 |
|
|
|
228 |
|
|
GetClientRect(hWnd, &rc); |
229 |
|
|
hdc = BeginPaint(hWnd, &ps); |
230 |
|
|
SetRect(&fill, 0, 0, WINWIDTH(rc), 40); |
231 |
|
|
FillRect(hdc, &fill, pbtewi_brush); |
232 |
|
|
ShowBitmap(hWnd, hdc, "PBTEWI", 0, 0); |
233 |
|
|
EndPaint(hWnd, &ps); |
234 |
|
|
} else { |
235 |
|
|
return DefWindowProc(hWnd, msg, wp, lp); |
236 |
|
|
} |
237 |
|
|
return 0; |
238 |
|
|
} |
239 |
|
|
|
240 |
|
|
BOOL InitApp(void) { |
241 |
|
|
WNDCLASSEX wc; |
242 |
|
|
wc.cbSize = sizeof(WNDCLASSEX); |
243 |
|
|
wc.style = CS_HREDRAW | CS_VREDRAW; |
244 |
|
|
wc.lpfnWndProc = WndProc; |
245 |
|
|
wc.cbClsExtra = 0; |
246 |
|
|
wc.cbWndExtra = 0; |
247 |
|
|
wc.hInstance = hInst; |
248 |
|
|
wc.hIcon = LoadIcon(hInst, "TEWI"); |
249 |
|
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW); |
250 |
|
|
wc.hbrBackground = GetSysColorBrush(COLOR_MENU); |
251 |
|
|
wc.lpszMenuName = NULL; |
252 |
|
|
wc.lpszClassName = "tewihttpd"; |
253 |
|
|
wc.hIconSm = LoadIcon(hInst, "TEWI"); |
254 |
|
|
return RegisterClassEx(&wc); |
255 |
|
|
} |
256 |
|
|
|
257 |
|
|
BOOL InitWindow(int nCmdShow) { |
258 |
|
|
HWND hWnd; |
259 |
|
|
RECT deskrc, rc; |
260 |
|
|
HWND hDeskWnd = GetDesktopWindow(); |
261 |
|
|
GetWindowRect(hDeskWnd, &deskrc); |
262 |
|
|
hWnd = CreateWindow("tewihttpd", "Tewi HTTPd", (WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME) ^ WS_MAXIMIZEBOX, 0, 0, 600, 400, NULL, 0, hInst, NULL); |
263 |
|
|
|
264 |
|
|
if(!hWnd) { |
265 |
|
|
return FALSE; |
266 |
|
|
} |
267 |
|
|
GetWindowRect(hWnd, &rc); |
268 |
|
|
SetWindowPos(hWnd, HWND_TOP, (deskrc.right - (rc.right - rc.left)) / 2, (deskrc.bottom - (rc.bottom - rc.top)) / 2, rc.right - rc.left, rc.bottom - rc.top, SWP_SHOWWINDOW); |
269 |
|
|
ShowWindow(hWnd, nCmdShow); |
270 |
|
|
UpdateWindow(hWnd); |
271 |
|
|
return TRUE; |
272 |
|
|
} |
273 |
|
|
|
274 |
|
|
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { |
275 |
|
|
MSG msg; |
276 |
|
|
BOOL bret; |
277 |
|
|
hInst = hCurInst; |
278 |
|
|
tewi_alive = FALSE; |
279 |
|
|
was_starting = FALSE; |
280 |
|
|
exiting = FALSE; |
281 |
|
|
idle = TRUE; |
282 |
|
|
logfile = stderr; |
283 |
|
|
if(!InitApp()) { |
284 |
|
|
return FALSE; |
285 |
|
|
} |
286 |
|
|
if(!InitWindow(nCmdShow)) { |
287 |
|
|
return FALSE; |
288 |
|
|
} |
289 |
|
|
|
290 |
|
|
while((bret = GetMessage(&msg, NULL, 0, 0)) != 0) { |
291 |
|
|
if(bret == -1) { |
292 |
|
|
break; |
293 |
|
|
} else { |
294 |
|
|
TranslateMessage(&msg); |
295 |
|
|
DispatchMessage(&msg); |
296 |
|
|
} |
297 |
|
|
} |
298 |
|
|
return (int)msg.wParam; |
299 |
|
|
} |
300 |
|
|
|
301 |
|
|
#endif |