// Event loop and support functions for Windows versions // of BOINC applications w/ graphics. // Platform-independent code should NOT be here. // // TODO: Is any of this related to or dependent on OpenGL?? // Why not make it independent of OpenGL? // /* This Code Was Created By Jeff Molofee 2000 * A HUGE Thanks To Fredric Echols For Cleaning Up * And Optimizing This Code, Making It More Flexible! * If You've Found This Code Useful, Please Let Me Know. * Visit My Site At nehe.gamedev.net * Adapted to BOINC by Eric Heien */ #include #include // Header File For The OpenGL32 Library #include // Header File For The GLu32 Library #include #include #include "boinc_api.h" #include "graphics_api.h" #include "app_ipc.h" #include "util.h" //#include "win_idle_tracker.h" //remove if there are windows problems #define WIN32_LEAN_AND_MEAN // This trims down the windows libraries. #define WIN32_EXTRA_LEAN // Trims even farther. //#define DRAW_WITH_DLL #ifdef DRAW_WITH_DLL __declspec(dllimport) void vis_render(int,int,double,float*,int); __declspec(dllimport) void vis_unload(); __declspec(dllimport) void vis_init(); #pragma comment(lib,"../../vis_dll/debug/vis.lib") #endif static HDC hDC; static HGLRC hRC; static HWND hWnd=NULL; // Holds Our Window Handle static HINSTANCE hInstance; // Holds The Instance Of The Application static RECT rect = {50, 50, 50+640, 50+480}; static int current_graphics_mode = MODE_HIDE_GRAPHICS; static POINT mousePos; static UINT m_uEndSSMsg; HDC myhDC; BOOL win_loop_done; extern bool using_opengl; extern bool standalone; extern HANDLE hQuitEvent; extern void MyCreateFont(unsigned int &base, char *fontName, int Size, int weight); void SetupPixelFormat(HDC hDC); double starttime; double fps=60.; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc BOOL reg_win_class(); BOOL unreg_win_class(); bool KillWindow() { #ifdef DRAW_WITH_DLL if(hDC) vis_unload(); #else //if(hDC) app_unload_gl(); #endif if (hRC) { // Do We Have A Rendering Context? if (!wglMakeCurrent(NULL,NULL)) { // Are We Able To Release The DC And RC Contexts? return false; } if (!wglDeleteContext(hRC)) { // Are We Able To Delete The RC? return false; } hRC=NULL; // Set RC To NULL } if (hDC && !ReleaseDC(hWnd,hDC)) { // Are We Able To Release The DC hDC=NULL; // Set DC To NULL return false; } KillTimer(hWnd, 1); if (hWnd && !DestroyWindow(hWnd)) { // Are We Able To Destroy The Window? return false; hWnd=NULL; // Set hWnd To NULL } return true; } // switch to the given graphics mode. This is called: // - on initialization // - when get mode change msg (via shared mem) // - when in SS mode and get user input // void SetMode(int mode) { RECT WindowRect = {0,0,0,0}; int width, height; DWORD dwExStyle; DWORD dwStyle; if (current_graphics_mode != MODE_FULLSCREEN) GetWindowRect(hWnd, &rect); KillWindow(); current_graphics_mode = mode; if (current_graphics_mode == MODE_FULLSCREEN) { HDC screenDC=GetDC(NULL); WindowRect.left = WindowRect.top = 0; WindowRect.right=GetDeviceCaps(screenDC, HORZRES); WindowRect.bottom=GetDeviceCaps(screenDC, VERTRES); ReleaseDC(NULL, screenDC); dwExStyle=WS_EX_TOPMOST; dwStyle=WS_POPUP; while(ShowCursor(false) >= 0); } else { WindowRect = rect; dwExStyle=WS_EX_APPWINDOW|WS_EX_WINDOWEDGE; dwStyle=WS_OVERLAPPEDWINDOW; while(ShowCursor(true) < 0); } // Do not do AdjustWindowRectEx here, this will // cause the window to creep upwards APP_INIT_DATA aid; boinc_get_init_data(aid); if (!strlen(aid.app_name)) strcpy(aid.app_name, "BOINC Application"); hWnd = CreateWindowEx(dwExStyle, "BOINC_OpenGL", aid.app_name, dwStyle|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, WindowRect.left, WindowRect.top, WindowRect.right-WindowRect.left,WindowRect.bottom-WindowRect.top, NULL, NULL, hInstance, NULL ); SetForegroundWindow(hWnd); GetCursorPos(&mousePos); hDC = GetDC(hWnd); myhDC=hDC; SetupPixelFormat(myhDC); if(!(hRC = wglCreateContext(hDC))) { ReleaseDC(hWnd, hDC); return; } if(!wglMakeCurrent(hDC, hRC)) { ReleaseDC(hWnd, hDC); wglDeleteContext(hRC); return; } width = WindowRect.right-WindowRect.left; height = WindowRect.bottom-WindowRect.top; SetTimer(hWnd, 1, 100, NULL); starttime=dtime(); if(current_graphics_mode == MODE_FULLSCREEN || current_graphics_mode == MODE_WINDOW) { ShowWindow(hWnd, SW_SHOW); SetFocus(hWnd); } else { ShowWindow(hWnd, SW_HIDE); } ReSizeGLScene(width, height); InitGL(); #ifdef DRAW_WITH_DLL vis_init(); #else app_init_gl(); #endif app_client_shm->send_graphics_mode_msg(APP_CORE_GFX_SEG, current_graphics_mode); } // message handler (includes timer, Windows msgs) // LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window UINT uMsg, // Message For This Window WPARAM wParam, // Additional Message Information LPARAM lParam) // Additional Message Information { RECT rt; int width, height, new_mode; switch(uMsg) { case WM_KEYDOWN: case WM_KEYUP: case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: if(current_graphics_mode == MODE_FULLSCREEN) { SetMode(MODE_HIDE_GRAPHICS); PostMessage(HWND_BROADCAST, m_uEndSSMsg, 0, 0); } return 0; case WM_MOUSEMOVE: if(current_graphics_mode == MODE_FULLSCREEN) { POINT cPos; GetCursorPos(&cPos); if(cPos.x != mousePos.x || cPos.y != mousePos.y) { SetMode(MODE_HIDE_GRAPHICS); PostMessage(HWND_BROADCAST, m_uEndSSMsg, 0, 0); } } return 0; case WM_CLOSE: SetMode(MODE_HIDE_GRAPHICS); return 0; case WM_PAINT: PAINTSTRUCT ps; RECT winRect; HDC pdc; pdc = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &winRect); FillRect(pdc, &winRect, (HBRUSH)GetStockObject(BLACK_BRUSH)); EndPaint(hWnd, &ps); return 0; case WM_SIZE: ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); return 0; case WM_TIMER: if (app_client_shm->get_graphics_mode_msg(CORE_APP_GFX_SEG, new_mode)) { SetMode(new_mode); } if (current_graphics_mode == MODE_HIDE_GRAPHICS) return 0; // TODO: remove width, height from API // GetClientRect(hWnd, &rt); width = rt.right-rt.left; height = rt.bottom-rt.top; #ifdef DRAW_WITH_DLL float* data; int data_size=100; data=(float*)malloc(sizeof(float)*data_size); for(int i=0;i