diff --git a/api/boinc_api.C b/api/boinc_api.C
index aa3b564920..746800b5df 100644
--- a/api/boinc_api.C
+++ b/api/boinc_api.C
@@ -487,6 +487,34 @@ int boinc_wu_cpu_time(double& cpu_t) {
return 0;
}
+// this can be called from the graphics thread
+//
+int suspend_activities() {
+#ifdef _WIN32
+ if (options.direct_process_action) {
+ // in Windows this is called from a separate "timer thread",
+ // and Windows lets us suspend the worker thread
+ //
+ SuspendThread(worker_thread_handle);
+ }
+#endif
+ return 0;
+}
+
+// this can be called from the graphics thread
+//
+int resume_activities() {
+#ifdef _WIN32
+ if (options.direct_process_action) {
+ // in Windows this is called from a separate "timer thread",
+ // and Windows lets us resume the worker thread
+ //
+ ResumeThread(worker_thread_handle);
+ }
+#endif
+ return 0;
+}
+
static void handle_heartbeat_msg() {
char buf[MSG_CHANNEL_SIZE];
if (app_client_shm->shm->heartbeat.get_msg(buf)) {
@@ -550,26 +578,12 @@ static void handle_process_control_msg() {
if (app_client_shm->shm->process_control_request.get_msg(buf)) {
if (match_tag(buf, "")) {
boinc_status.suspended = true;
-#ifdef _WIN32
- if (options.direct_process_action) {
- // in Windows this is called from a separate "timer thread",
- // and Windows lets us suspend the worker thread
- //
- SuspendThread(worker_thread_handle);
- }
-#endif
+ boinc_suspend_activities();
}
if (match_tag(buf, "")) {
boinc_status.suspended = false;
-#ifdef _WIN32
- if (options.direct_process_action) {
- // in Windows this is called from a separate "timer thread",
- // and Windows lets us resume the worker thread
- //
- ResumeThread(worker_thread_handle);
- }
-#endif
+ boinc_resume_activities();
}
if (match_tag(buf, "")) {
diff --git a/api/boinc_api.h b/api/boinc_api.h
index 24c0827a13..ccb7b6ad87 100755
--- a/api/boinc_api.h
+++ b/api/boinc_api.h
@@ -117,6 +117,8 @@ extern HANDLE worker_thread_handle;
#else
extern void block_sigalrm();
#endif
+extern int suspend_activities(void);
+extern int resume_activities(void);
extern int boinc_init_options_general(BOINC_OPTIONS& opt);
extern int set_worker_timer(void);
extern void (*stop_graphics_thread_ptr)();
diff --git a/api/windows_opengl.C b/api/windows_opengl.C
index 3205afaadb..ef9d509532 100755
--- a/api/windows_opengl.C
+++ b/api/windows_opengl.C
@@ -25,7 +25,8 @@
#include "graphics_impl.h"
-#define BOINC_WINDOW_CLASS_NAME "BOINC_app"
+#define BOINC_WINDOW_CLASS_NAME "BOINC_app"
+#define WM_SHUTDOWNGFX WM_USER+1
const UINT WM_BOINCSFW = RegisterWindowMessage(TEXT("BOINCSetForegroundWindow"));
@@ -370,8 +371,17 @@ LRESULT CALLBACK WndProc(
}
return 0;
case WM_POWERBROADCAST:
- if (PBT_APMQUERYSUSPEND == wParam && current_graphics_mode == MODE_FULLSCREEN) {
+ 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);
+ resume_activities();
+ return TRUE;
+ }
+ if (PBT_APMQUERYSUSPEND == wParam) {
return TRUE;
}
break;
@@ -396,6 +406,9 @@ LRESULT CALLBACK WndProc(
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);
@@ -509,7 +522,7 @@ static void stop_graphics_thread() {
// Close down open window and clean up
//
if (!boinc_is_standalone()) {
- SendMessage(hWnd, WM_DESTROY, NULL, NULL);
+ SendMessage(hWnd, WM_SHUTDOWNGFX, NULL, NULL);
}
}
diff --git a/checkin_notes b/checkin_notes
index aecec66b4b..60b51a7128 100755
--- a/checkin_notes
+++ b/checkin_notes
@@ -2253,3 +2253,13 @@ David 22 Feb 2006
client/
http_curl.C
+
+Rom 22 Feb 2006
+ - Bug Fix: Close down the OpenGL handles as well as the window handles
+ when boinc_finish() is called.
+ - Bug Fix: Add better power management handling to science applications
+ if they have a lingering graphics window open.
+
+ api/
+ boinc_api.C, .h
+ windows_opengl.C