static void make_window(const char* title) {
    RECT WindowRect = {0,0,0,0};
    int width, height;
    DWORD dwExStyle;
    DWORD dwStyle;

    if (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 {
        // Version 5 screensaver logic kills all MODE_WINDOW graphics before starting one
        // in fullscreen mode, then restarts the ones it killed when screensaver stops.
        // To be compatible with V5, we remember and restore the MODE_WINDOW dimensions.
        FILE *f = boinc_fopen("gfx_info", "r");
        if (f) {
            // ToDo: change this to XML parsing
            fscanf(f, "%d %d %d %d\n", &rect.left, &rect.top, &rect.right, &rect.bottom);
            fclose(f);
        }
        WindowRect = rect;
        dwExStyle=WS_EX_APPWINDOW|WS_EX_WINDOWEDGE;
        dwStyle=WS_OVERLAPPEDWINDOW;
        while(ShowCursor(true) < 0);
    }

    char window_title[256];
    if (title) {
        strcpy(window_title, title);
    } else {
        APP_INIT_DATA aid;
        boinc_get_init_data(aid);
        if (!strlen(aid.app_name)) strcpy(aid.app_name, "BOINC Application");
        get_window_title(window_title, 256);
    }

    //fprintf(stderr, "Setting window title to '%s'.\n", window_title);

    hWnd = CreateWindowEx(dwExStyle, BOINC_WINDOW_CLASS_NAME, window_title,
        dwStyle|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, WindowRect.left, WindowRect.top,
        WindowRect.right-WindowRect.left,WindowRect.bottom-WindowRect.top,
        NULL, NULL, hInstance, NULL
    );

    if (!SetForegroundWindow(hWnd)) {
        fprintf(stderr,
            "%s ERROR: Unable to set foreground window (0x%x).\n",
            boinc_msg_prefix(), GetLastError()
        );
    }

    if (!GetCursorPos(&mousePos)) {
        fprintf(stderr,
            "%s ERROR: Unable to get mouse cursor position (0x%x).\n",
            boinc_msg_prefix(), GetLastError()
        );
    }

    hDC = GetDC(hWnd);
    if (!hDC) {
        fprintf(stderr,
            "%s ERROR: Couldn't get a device context for the window (0x%x).\n",
            boinc_msg_prefix(), GetLastError()
        );
    }
    SetupPixelFormat(hDC);

    hRC = wglCreateContext(hDC);
    if (!hRC) {
        fprintf(stderr,
            "%s ERROR: Unable to create OpenGL context (0x%x).\n",
            boinc_msg_prefix(), GetLastError()
        );
        ReleaseDC(hWnd, hDC);
        return;
    }

    if(!wglMakeCurrent(hDC, hRC)) {
        fprintf(stderr,
            "%s ERROR: Unable to make OpenGL context current (0x%x).\n",
            boinc_msg_prefix(), GetLastError()
        );
        ReleaseDC(hWnd, hDC);
        wglDeleteContext(hRC);
        return;
    }

    // use client area for resize when not fullscreen
    if (current_graphics_mode != MODE_FULLSCREEN) {
        GetClientRect(hWnd, &WindowRect);
	}

    width = WindowRect.right-WindowRect.left;
    height = WindowRect.bottom-WindowRect.top;

    ShowWindow(hWnd, SW_SHOW);
    SetFocus(hWnd);

    app_graphics_init();
    app_graphics_resize(width, height);

    window_ready=true;
}
// 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
) {
    switch(uMsg) {
    case WM_ERASEBKGND:        // Check To See If Windows Is Trying To Erase The Background
            return 0;
    case WM_KEYDOWN:
        if(!window_ready) return 0;    
        if (current_graphics_mode == MODE_FULLSCREEN) {
               set_mode(MODE_HIDE_GRAPHICS);
        } else {           
            boinc_app_key_press((int)wParam, (int)lParam);
        }
        return 0;
    case WM_KEYUP:
        if(!window_ready) return 0;    
        if (current_graphics_mode == MODE_FULLSCREEN) {
            set_mode(MODE_HIDE_GRAPHICS);
        } else {
            boinc_app_key_release((int)wParam, (int)lParam);           
        }
        return 0;
    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
        if(!window_ready) return 0;    

        if (current_graphics_mode == MODE_FULLSCREEN) {
            set_mode(MODE_HIDE_GRAPHICS);
        } else  {
            int which;
            bool down;
            POINT cPos;
            GetCursorPos(&cPos);
            parse_mouse_event(uMsg, which, down);
            boinc_app_mouse_button(cPos.x, cPos.y, which, down);
        }
        return 0;
    case WM_MOUSEMOVE:
        if(!window_ready) return 0;    
        POINT cPos;
        GetCursorPos(&cPos);
        if (current_graphics_mode == MODE_FULLSCREEN) { 
            if(cPos.x != mousePos.x || cPos.y != mousePos.y) {
                set_mode(MODE_HIDE_GRAPHICS);
            }
        } else {
            boinc_app_mouse_move(
                cPos.x, cPos.y,
                (wParam&MK_LBUTTON)!=0,
                (wParam&MK_MBUTTON)!=0,
                (wParam&MK_RBUTTON)!=0
            );
        }
        return 0;
    case WM_CLOSE:
        if (boinc_is_standalone()) {
            boinc_exit(0);
        } else {
            if (current_graphics_mode != MODE_FULLSCREEN) {
                set_mode(MODE_HIDE_GRAPHICS);
            }
        }
        return 0;
    case WM_POWERBROADCAST:
        if (PBT_APMSUSPEND == wParam) {
            set_mode(MODE_HIDE_GRAPHICS);
            suspend_activities();
            return TRUE;
        } 
        if (PBT_APMQUERYSUSPENDFAILED == wParam || PBT_APMRESUMESUSPEND == wParam) {
            set_mode(acked_graphics_mode);
            restore_activities();
            return TRUE;
        }
        if (PBT_APMQUERYSUSPEND == wParam) {
            return TRUE;
        }
        break;
    case WM_PAINT:
        PAINTSTRUCT ps;
        RECT winRect;
        HDC pdc;
        if (!graphics_threadh) graphics_threadh=(HANDLE)GetCurrentThreadId();  
        pdc = BeginPaint(hWnd, &ps);
        GetClientRect(hWnd, &winRect);
        FillRect(pdc, &winRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
        EndPaint(hWnd, &ps);
        return 0;
    case WM_SIZE:
        if ( SIZE_MINIMIZED == wParam ) {
            visible = FALSE;
        } else {
            visible = TRUE;
        }          
        if(!window_ready) return 0;    
        app_graphics_resize(LOWORD(lParam), HIWORD(lParam));
        return 0;
    case WM_SHUTDOWNGFX:
        set_mode(MODE_HIDE_GRAPHICS);
        return 0;
    default:
        if ( WM_BOINCSFW == uMsg ) {
            SetForegroundWindow(hWnd);
        }
    }

    // Pass All Unhandled Messages To DefWindowProc
    return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
// 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
) {
    switch(uMsg) {
    case WM_ERASEBKGND:        // Check To See If Windows Is Trying To Erase The Background
            return 0;
    case WM_KEYDOWN:
        if(!window_ready) return 0;    
        if (fullscreen) {
            boinc_close_window_and_quit("key down");
        } else {           
            boinc_app_key_press((int)wParam, (int)lParam);
        }
        return 0;
    case WM_KEYUP:
        if(!window_ready) return 0;    
        if (fullscreen) {
            boinc_close_window_and_quit("key up");
        } else {
            boinc_app_key_release((int)wParam, (int)lParam);           
        }
        return 0;
    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
        if(!window_ready) return 0;    

        if (fullscreen) {
            boinc_close_window_and_quit("button up");
        } else  {
            int which;
            bool down;
            parse_mouse_event(uMsg, which, down);
            boinc_app_mouse_button(
                (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam),
                which, down
            );
        }
        return 0;
    case WM_MOUSEMOVE:
        if(!window_ready) return 0;    
        if (fullscreen) { 
            if((int)(short)LOWORD(lParam) != mousePos.x || (int)(short)HIWORD(lParam) != mousePos.y) {
                boinc_close_window_and_quit("mouse move");
            }
        } else {
            boinc_app_mouse_move(
                (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam),
                (wParam&MK_LBUTTON)!=0,
                (wParam&MK_MBUTTON)!=0,
                (wParam&MK_RBUTTON)!=0
            );
        }
        return 0;
    case WM_CLOSE:
        boinc_close_window_and_quit("WM_CLOSE");
        return 0;
    case WM_SHUTDOWNGFX:
        boinc_close_window_and_quit("WM_SHUTDOWNGFX");
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        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:
        if ( SIZE_MINIMIZED == wParam ) {
            visible = FALSE;
        } else {
            visible = TRUE;
        }          
        if(!window_ready) return 0;    
        app_graphics_resize(LOWORD(lParam), HIWORD(lParam));
        return 0;
    }

    // Pass All Unhandled Messages To DefWindowProc
    return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
static void make_new_window() {
    RECT WindowRect = {0,0,0,0};
    int width, height;
    DWORD dwExStyle;
    DWORD dwStyle;

    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);
    }

    APP_INIT_DATA aid;
    boinc_get_init_data(aid);
    if (!strlen(aid.app_name)) {
        strlcpy(aid.app_name, "BOINC Application", sizeof(aid.app_name));
    }
    char window_title[256];
    get_window_title(aid, window_title, 256);
    hWnd = CreateWindowEx(dwExStyle, BOINC_WINDOW_CLASS_NAME, window_title,
        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);

    hRC = wglCreateContext(hDC);
    if (hRC == 0) {
        ReleaseDC(hWnd, hDC);
        return;
    }

    if(!wglMakeCurrent(hDC, hRC)) {
        ReleaseDC(hWnd, hDC);
        wglDeleteContext(hRC);
        return;
    }

    // use client area for resize when not fullscreen
    if (current_graphics_mode != MODE_FULLSCREEN) {
        GetClientRect(hWnd, &WindowRect);
	}

    width = WindowRect.right-WindowRect.left;
    height = WindowRect.bottom-WindowRect.top;

    ShowWindow(hWnd, SW_SHOW);
    SetFocus(hWnd);

    app_graphics_init();
    app_graphics_resize(width, height);     
    window_ready=true;
}