Subversion Repositories Tewi

Rev

Rev 289 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
244 nishi 1
/* $Id: gui.c 291 2024-10-09 03:14:51Z nishi $ */
2
 
3
#include "../config.h"
4
 
291 nishi 5
#if defined(BUILD_GUI_VALID)
6
 
244 nishi 7
#include "gui.h"
253 nishi 8
#include "tw_server.h"
244 nishi 9
 
253 nishi 10
#include <cm_log.h>
11
 
12
#include <stdio.h>
244 nishi 13
#include <windows.h>
253 nishi 14
#include <process.h>
244 nishi 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;
255 nishi 23
HWND button_reset;
24
HWND button_exit;
289 nishi 25
HWND statuswnd;
253 nishi 26
HFONT monospace;
244 nishi 27
BOOL tewi_alive;
28
BOOL was_starting;
29
BOOL exiting;
253 nishi 30
BOOL idle;
31
extern FILE* logfile;
32
extern int running;
244 nishi 33
 
34
#define WINWIDTH(rc) (rc.right - rc.left)
35
#define WINHEIGHT(rc) (rc.bottom - rc.top)
36
 
253 nishi 37
int startup(int argc, char** argv);
244 nishi 38
 
255 nishi 39
void ShowBitmapSize(HWND hWnd, HDC hdc, const char* name, int x, int y, int w, int h) {
244 nishi 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);
255 nishi 46
	if(w == 0 && h == 0) {
244 nishi 47
		StretchBlt(hdc, x, y, bmp.bmWidth, bmp.bmHeight, hmdc, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
255 nishi 48
	} else {
244 nishi 49
		StretchBlt(hdc, x, y, w, h, hmdc, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
50
	}
51
	DeleteDC(hmdc);
52
	DeleteObject(hBitmap);
53
}
54
 
255 nishi 55
void ShowBitmap(HWND hWnd, HDC hdc, const char* name, int x, int y) { ShowBitmapSize(hWnd, hdc, name, x, y, 0, 0); }
244 nishi 56
 
253 nishi 57
int max = 0;
255 nishi 58
void AddLog(const char* str) {
253 nishi 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);
255 nishi 69
 
70
	if(max < sz.cx) {
253 nishi 71
		max = sz.cx;
72
		SendMessage(logarea, LB_SETHORIZONTALEXTENT, max, 0);
73
	}
74
}
75
 
255 nishi 76
LRESULT CALLBACK VersionDialog(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
77
	if(msg == WM_COMMAND) {
244 nishi 78
		if(LOWORD(wp) == IDOK) EndDialog(hWnd, IDOK);
255 nishi 79
	} else if(msg == WM_PAINT) {
244 nishi 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);
255 nishi 91
	} else if(msg == WM_CTLCOLORDLG || msg == WM_CTLCOLORSTATIC) {
249 nishi 92
		HDC dc = (HDC)wp;
93
		SetBkMode(dc, TRANSPARENT);
253 nishi 94
		return (LRESULT)GetSysColorBrush(COLOR_MENU);
255 nishi 95
	} else {
244 nishi 96
		return FALSE;
97
	}
98
	return TRUE;
99
}
100
 
255 nishi 101
void tewi_thread(void* ptr) {
253 nishi 102
	int st = startup(0, NULL);
244 nishi 103
	was_starting = TRUE;
255 nishi 104
	if(st == -1) {
253 nishi 105
		tewi_alive = TRUE;
106
		idle = FALSE;
255 nishi 107
	} else {
253 nishi 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();
244 nishi 118
}
119
 
255 nishi 120
void StartTewi(void) {
253 nishi 121
	EnableWindow(button_start, FALSE);
122
	EnableWindow(button_stop, FALSE);
123
	_beginthread(tewi_thread, 0, NULL);
124
}
125
 
255 nishi 126
void StopTewi(void) {
253 nishi 127
	EnableWindow(button_start, FALSE);
128
	EnableWindow(button_stop, FALSE);
129
	running = 0;
244 nishi 130
}
131
 
255 nishi 132
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
133
	if(msg == WM_COMMAND) {
244 nishi 134
		int trig = LOWORD(wp);
135
		int ev = HIWORD(wp);
255 nishi 136
		if(trig == GUI_BUTTON_ABOUT) {
137
			if(ev == BN_CLICKED) {
249 nishi 138
				DialogBox(hInst, "VERSIONDLG", hWnd, (DLGPROC)VersionDialog);
244 nishi 139
			}
255 nishi 140
		} else if(trig == GUI_BUTTON_START) {
141
			if(ev == BN_CLICKED) {
289 nishi 142
				SendMessage(statuswnd, SB_SETTEXT, 0, (LPARAM) "Starting Tewi HTTPd");
244 nishi 143
				StartTewi();
144
			}
255 nishi 145
		} else if(trig == GUI_BUTTON_STOP) {
146
			if(ev == BN_CLICKED) {
289 nishi 147
				SendMessage(statuswnd, SB_SETTEXT, 0, (LPARAM) "Stopping Tewi HTTPd");
244 nishi 148
				StopTewi();
149
			}
255 nishi 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) {
289 nishi 159
					SendMessage(statuswnd, SB_SETTEXT, 0, (LPARAM) "Stopping Tewi HTTPd");
244 nishi 160
					StopTewi();
161
					exiting = TRUE;
255 nishi 162
				} else {
244 nishi 163
					SendMessage(hWnd, WM_CLOSE, 0, 0);
164
				}
165
			}
255 nishi 166
		} else if(trig == GUI_LOG) {
244 nishi 167
		}
255 nishi 168
	} else if(msg == WM_CLOSE) {
244 nishi 169
		DestroyWindow(hWnd);
255 nishi 170
	} else if(msg == WM_DESTROY) {
244 nishi 171
		DeleteObject(pbtewi_brush);
172
		PostQuitMessage(0);
255 nishi 173
	} else if(msg == WM_CREATE) {
244 nishi 174
		RECT rc, src;
175
		GetClientRect(hWnd, &rc);
176
 
177
		InitCommonControls();
178
 
253 nishi 179
		monospace = (HFONT)GetStockObject(SYSTEM_FIXED_FONT);
180
 
289 nishi 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);
244 nishi 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);
255 nishi 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);
253 nishi 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
 
244 nishi 196
		SetTimer(hWnd, TIMER_WATCH_TEWI, 100, NULL);
255 nishi 197
	} else if(msg == WM_TIMER) {
198
		if(wp == TIMER_WATCH_TEWI) {
199
			if(idle) {
200
			} else if(tewi_alive) {
201
				if(was_starting) {
244 nishi 202
					was_starting = FALSE;
289 nishi 203
					SendMessage(statuswnd, SB_SETTEXT, 0, (LPARAM) "Started Tewi HTTPd");
244 nishi 204
				}
205
				EnableWindow(button_start, FALSE);
206
				EnableWindow(button_stop, TRUE);
253 nishi 207
				idle = TRUE;
255 nishi 208
			} else {
209
				if(was_starting) {
244 nishi 210
					was_starting = FALSE;
289 nishi 211
					SendMessage(statuswnd, SB_SETTEXT, 0, (LPARAM) "Stopped Tewi HTTPd");
244 nishi 212
				}
213
				EnableWindow(button_start, TRUE);
214
				EnableWindow(button_stop, FALSE);
255 nishi 215
				if(exiting) {
244 nishi 216
					KillTimer(hWnd, TIMER_WATCH_TEWI);
217
					SendMessage(hWnd, WM_CLOSE, 0, 0);
218
				}
253 nishi 219
				idle = TRUE;
244 nishi 220
			}
221
		}
255 nishi 222
	} else if(msg == WM_PAINT) {
244 nishi 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);
255 nishi 234
	} else {
244 nishi 235
		return DefWindowProc(hWnd, msg, wp, lp);
236
	}
237
	return 0;
238
}
239
 
255 nishi 240
BOOL InitApp(void) {
253 nishi 241
	WNDCLASSEX wc;
242
	wc.cbSize = sizeof(WNDCLASSEX);
244 nishi 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 nishi 253
	wc.hIconSm = LoadIcon(hInst, "TEWI");
254
	return RegisterClassEx(&wc);
244 nishi 255
}
256
 
255 nishi 257
BOOL InitWindow(int nCmdShow) {
244 nishi 258
	HWND hWnd;
259
	RECT deskrc, rc;
260
	HWND hDeskWnd = GetDesktopWindow();
261
	GetWindowRect(hDeskWnd, &deskrc);
253 nishi 262
	hWnd = CreateWindow("tewihttpd", "Tewi HTTPd", (WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME) ^ WS_MAXIMIZEBOX, 0, 0, 600, 400, NULL, 0, hInst, NULL);
244 nishi 263
 
255 nishi 264
	if(!hWnd) {
244 nishi 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
 
255 nishi 274
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) {
244 nishi 275
	MSG msg;
276
	BOOL bret;
277
	hInst = hCurInst;
278
	tewi_alive = FALSE;
279
	was_starting = FALSE;
280
	exiting = FALSE;
253 nishi 281
	idle = TRUE;
282
	logfile = stderr;
255 nishi 283
	if(!InitApp()) {
244 nishi 284
		return FALSE;
285
	}
255 nishi 286
	if(!InitWindow(nCmdShow)) {
244 nishi 287
		return FALSE;
288
	}
289
 
255 nishi 290
	while((bret = GetMessage(&msg, NULL, 0, 0)) != 0) {
244 nishi 291
		if(bret == -1) {
292
			break;
293
		} else {
294
			TranslateMessage(&msg);
295
			DispatchMessage(&msg);
296
		}
297
	}
298
	return (int)msg.wParam;
299
}
291 nishi 300
 
301
#endif