/* Quit the program on close button press for now */ static LRESULT CALLBACK window_callback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { AL_DISPLAY_D3D *d; WINDOWINFO wi; int w; int h; int x; int y; unsigned int i; int fActive; AL_EVENT_SOURCE *es; if (message == msg_call_proc) { return ((int (*)(void))wParam) (); } if (message == msg_suicide) { DestroyWindow(hWnd); return 0; } for (i = 0; i < d3d_system->system.displays._size; i++) { AL_DISPLAY_D3D **dptr = _al_vector_ref(&d3d_system->system.displays, i); d = *dptr; if (d->window == hWnd) { break; } } es = &d->display.es; switch (message) { case WM_SIZING: return 0; case WM_ACTIVATE: fActive = LOWORD(wParam); if (fActive != WA_INACTIVE) { for (i = 0; i < d3d_system->system.displays._size; i++) { AL_DISPLAY_D3D **dptr = _al_vector_ref(&d3d_system->system.displays, i); d = *dptr; if (d->window == hWnd) { break; } } _al_current_display = (AL_DISPLAY *)d; d3d_active_window = d->window; //d3d_win_grab_input(); key_dinput_acquire(); } return 0; case WM_CLOSE: _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es, AL_EVENT_DISPLAY_CLOSE)) { AL_EVENT *event = _al_event_source_get_unused_event(es); if (event) { event->display.type = AL_EVENT_DISPLAY_CLOSE; event->display.timestamp = al_current_time(); _al_event_source_emit_event(es, event); } } _al_event_source_unlock(es); return 0; case WM_SIZE: if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED) { /* Generate a resize event if the size has changed. We cannot asynchronously * change the display size here yet, since the user will only know about a * changed size after receiving the resize event. Here we merely add the * event to the queue. */ h = HIWORD(lParam); w = LOWORD(lParam); wi.cbSize = sizeof(WINDOWINFO); GetWindowInfo(d->window, &wi); x = wi.rcClient.left; y = wi.rcClient.top; if (d->display.w != w || d->display.h != h) { _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es, AL_EVENT_DISPLAY_RESIZE)) { AL_EVENT *event = _al_event_source_get_unused_event(es); if (event) { event->display.type = AL_EVENT_DISPLAY_RESIZE; event->display.timestamp = al_current_time(); event->display.x = x; event->display.y = y; event->display.width = w; event->display.height = h; _al_event_source_emit_event(es, event); } } /* Generate an expose event. */ if (_al_event_source_needs_to_generate_event(es, AL_EVENT_DISPLAY_EXPOSE)) { AL_EVENT *event = _al_event_source_get_unused_event(es); if (event) { event->display.type = AL_EVENT_DISPLAY_EXPOSE; event->display.timestamp = al_current_time(); event->display.x = x; event->display.y = y; event->display.width = w; event->display.height = h; _al_event_source_emit_event(es, event); } } _al_event_source_unlock(es); } return 0; } } return DefWindowProc(hWnd,message,wParam,lParam); } /* wnd_thread_proc: * Thread function that handles the messages of the directx window. */ static void d3d_wnd_thread_proc(HANDLE setup_event) { DWORD result; MSG msg; unsigned int i; HWND my_window; // Create A Window Class Structure WNDCLASSEX wc; wc.cbClsExtra = 0; wc.cbSize = sizeof(wc); wc.cbWndExtra = 0; wc.hbrBackground = NULL; wc.hCursor = NULL; wc.hIcon = NULL; wc.hIconSm = NULL; wc.hInstance = GetModuleHandle(NULL); wc.lpfnWndProc = window_callback; wc.lpszClassName = "X3D"; wc.lpszMenuName = NULL; wc.style = CS_VREDRAW|CS_HREDRAW|CS_OWNDC; // Register Window Class RegisterClassEx(&wc); // Create Window my_window = CreateWindowEx(0, "X3D", "D3D Window", WS_OVERLAPPEDWINDOW|WS_VISIBLE, 100, 100, new_window_width, new_window_height, NULL,NULL,wc.hInstance,0); new_window = my_window; _win_thread_init(); for (;;) { while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (GetMessage(&msg, NULL, 0, 0)) { DispatchMessage(&msg); } else { goto End; } } } End: _TRACE("window thread exits\n"); _win_thread_exit(); } static void start_window_thread() { HANDLE hThread; hThread= (HANDLE) _beginthread(d3d_wnd_thread_proc, 0, hThread); } HWND d3d_create_window(int width, int height) { new_window = (HWND)-1; new_window_width = width; new_window_height = height; start_window_thread(); while (new_window == (HWND)-1) ; if (_d3d_keyboard_initialized) { AL_DISPLAY_D3D *d = (AL_DISPLAY_D3D *)_al_current_display; key_dinput_set_cooperation_level(new_window); d->keyboard_initialized = true; } d3d_active_window = new_window; return new_window; }