| /* | |
| * Copyright (C) Igor Sysoev | |
| */ | |
| #include <ngx_config.h> | |
| #include <ngx_core.h> | |
| #include <ngx_event.h> | |
| #include <nginx.h> | |
| static ngx_thread_value_t __stdcall 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; | |
| sig_atomic_t ngx_reap; | |
| sig_atomic_t ngx_timer; | |
| #endif | |
| ngx_uint_t ngx_process; | |
| ngx_pid_t ngx_pid; | |
| ngx_uint_t ngx_threaded; | |
| ngx_uint_t ngx_inherited; | |
| sig_atomic_t ngx_terminate; | |
| sig_atomic_t ngx_quit; | |
| ngx_uint_t ngx_exiting; | |
| #if 0 | |
| sig_atomic_t ngx_noaccept; | |
| sig_atomic_t ngx_reconfigure; | |
| sig_atomic_t ngx_reopen; | |
| sig_atomic_t ngx_change_binary; | |
| #endif | |
| static HMENU ngx_menu; | |
| void | |
| ngx_master_process_cycle(ngx_cycle_t *cycle) | |
| { | |
| ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "master mode is not supported"); | |
| exit(2); | |
| } | |
| void | |
| ngx_single_process_cycle(ngx_cycle_t *cycle) | |
| { | |
| 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(); | |
| for (i = 0; ngx_modules[i]; i++) { | |
| if (ngx_modules[i]->init_process) { | |
| if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) { | |
| /* fatal */ | |
| exit(2); | |
| } | |
| } | |
| } | |
| 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_OK) | |
| { | |
| 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 ngx_thread_value_t __stdcall | |
| ngx_worker_thread_cycle(void *data) | |
| { | |
| ngx_cycle_t *cycle; | |
| cycle = (ngx_cycle_t *) ngx_cycle; | |
| while (!ngx_quit) { | |
| ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); | |
| ngx_process_events_and_timers(cycle); | |
| } | |
| return 0; | |
| } | |
| 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-2005 Igor Sysoev"); | |
| return 0; | |
| } | |
| if (wparam == NGX_WM_EXIT) { | |
| if (ngx_system_tray_icon(window, NIM_DELETE, NULL, NULL) | |
| != NGX_OK) | |
| { | |
| 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); | |
| } | |
| } |