diff options
Diffstat (limited to 'src/os/win32/ngx_process_cycle.c')
-rw-r--r-- | src/os/win32/ngx_process_cycle.c | 207 |
1 files changed, 206 insertions, 1 deletions
diff --git a/src/os/win32/ngx_process_cycle.c b/src/os/win32/ngx_process_cycle.c index 843c3111e..e0635a5eb 100644 --- a/src/os/win32/ngx_process_cycle.c +++ b/src/os/win32/ngx_process_cycle.c @@ -7,8 +7,13 @@ #include <ngx_config.h> #include <ngx_core.h> #include <ngx_event.h> +#include <nginx.h> +static void *ngx_worker_thread_cycle(void *data); +static long __stdcall ngx_window_procedure(HWND window, u_int message, + u_int wparam, long lparam); + #if 0 ngx_pid_t ngx_new_binary; @@ -37,6 +42,8 @@ sig_atomic_t ngx_change_binary; #endif +static HMENU ngx_menu; + void ngx_master_process_cycle(ngx_cycle_t *cycle) { @@ -48,7 +55,17 @@ void ngx_master_process_cycle(ngx_cycle_t *cycle) void ngx_single_process_cycle(ngx_cycle_t *cycle) { - ngx_int_t i; + int rc; + ngx_int_t i; + ngx_err_t err; + ngx_tid_t tid; + MSG message; + HWND window; + HMENU menu; + HICON icon,tray; + WNDCLASS wc; + HINSTANCE instance; + ngx_core_conf_t *ccf; ngx_init_temp_number(); @@ -61,9 +78,197 @@ void ngx_single_process_cycle(ngx_cycle_t *cycle) } } + + ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); + + if (ngx_init_threads(ngx_threads_n, + ccf->thread_stack_size, cycle) == NGX_ERROR) + { + /* fatal */ + exit(2); + } + + err = ngx_thread_key_create(&ngx_core_tls_key); + if (err != 0) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, err, + ngx_thread_key_create_n " failed"); + /* fatal */ + exit(2); + } + + + instance = GetModuleHandle(NULL); + + icon = LoadIcon(instance, "nginx"); + if (icon == NULL) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "LoadIcon(\"nginx\") failed"); + /* fatal */ + exit(2); + } + + tray = LoadIcon(instance, "tray"); + if (icon == NULL) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "LoadIcon(\"tray\") failed"); + /* fatal */ + exit(2); + } + + menu = LoadMenu(instance, "nginx"); + if (menu == NULL) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "LoadMenu() failed"); + /* fatal */ + exit(2); + } + + ngx_menu = GetSubMenu(menu, 0); + if (ngx_menu == NULL) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "GetSubMenu() failed"); + /* fatal */ + exit(2); + } + + + wc.style = CS_HREDRAW|CS_VREDRAW; + wc.lpfnWndProc = ngx_window_procedure; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = instance; + wc.hIcon = icon; + wc.hCursor = NULL; + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = "nginx"; + + if (RegisterClass(&wc) == 0) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "RegisterClass() failed"); + /* fatal */ + exit(2); + } + + + window = CreateWindow("nginx", "nginx", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, instance, NULL); + + if (window == NULL) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "CreateWindow() failed"); + /* fatal */ + exit(2); + } + + + if (ngx_system_tray_icon(window, NIM_ADD, tray, (u_char *) " nginx") + == NGX_ERROR) + { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "Shell_NotifyIcon(NIM_ADD) failed"); + /* fatal */ + exit(2); + } + + + if (ngx_create_thread(&tid, ngx_worker_thread_cycle, NULL, cycle->log) != 0) + { + /* fatal */ + exit(2); + } + + + for ( ;; ) { + rc = GetMessage(&message, NULL, 0, 0); + + if (rc == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "GetMessage() failed"); + continue; + } + + if (rc == 0) { + exit(0); + } + + TranslateMessage(&message); + DispatchMessage(&message); + } +} + + +static void *ngx_worker_thread_cycle(void *data) +{ + ngx_cycle_t *cycle; + + cycle = (ngx_cycle_t *) ngx_cycle; + for ( ;; ) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); ngx_process_events(cycle); } + + return NULL; +} + + +static long __stdcall ngx_window_procedure(HWND window, u_int message, + u_int wparam, long lparam) +{ + POINT mouse; + + switch (message) { + + case NGX_WM_TRAY: + if (lparam == WM_RBUTTONDOWN) { + if (GetCursorPos(&mouse) == 0) { + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, + "GetCursorPos() failed"); + return 0; + } + + if (SetForegroundWindow(window) == 0) { + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, + "SetForegroundWindow() failed"); + return 0; + } + + if (TrackPopupMenu(ngx_menu, TPM_RIGHTBUTTON, + mouse.x, mouse.y, 0, window, NULL) == 0) + { + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, + "TrackPopupMenu() failed"); + return 0; + } + } + + return 0; + + case WM_COMMAND: + if (wparam == NGX_WM_ABOUT) { + ngx_message_box("nginx", MB_OK, 0, + NGINX_VER CRLF "(C) 2002-2004 Igor Sysoev"); + return 0; + } + + if (wparam == NGX_WM_EXIT) { + if (ngx_system_tray_icon(window, NIM_DELETE, NULL, NULL) + == NGX_ERROR) + { + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, + "Shell_NotifyIcon(NIM_DELETE) failed"); + } + } + + PostQuitMessage(0); + + return 0; + + default: + return DefWindowProc(window, message, wparam, lparam); + } } |