boinc/client/app_graphics.cpp

142 lines
4.4 KiB
C++

// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2008 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
// Graphics-related interaction with running apps.
//
// NOTE: This code is deprecated.
// We're keeping it in so that "Show Graphics" will work
// when pre-V6 apps run on a V6 client.
// At some point (when all projects have V6 apps,
// and all old CPDN jobs are finished) we can remove this.
#include "cpp.h"
#ifdef _WIN32
#include "boinc_win.h"
#else
#include "config.h"
#endif
#include "diagnostics.h"
#include "client_state.h"
#include "client_msgs.h"
#include "app.h"
#include "util.h"
void ACTIVE_TASK::request_graphics_mode(GRAPHICS_MSG& m) {
char buf[MSG_CHANNEL_SIZE], buf2[256];
if (!app_client_shm.shm) return;
if (m.mode == MODE_FULLSCREEN) {
// Remember mode before screensaver
graphics_mode_before_ss = graphics_mode_acked;
} else if (graphics_mode_acked != MODE_FULLSCREEN) {
graphics_mode_before_ss = MODE_HIDE_GRAPHICS;
}
if ( (m.mode == MODE_HIDE_GRAPHICS) && (graphics_mode_acked == MODE_FULLSCREEN) ) {
// Restore mode from before screensaver
m.mode = graphics_mode_before_ss;
}
graphics_msg = m; // save graphics_station, desktop, display
safe_strcpy(buf, xml_graphics_modes[m.mode]);
if (strlen(m.window_station)) {
snprintf(buf2, sizeof(buf2), "<window_station>%s</window_station>", m.window_station);
strcat(buf, buf2);
}
if (strlen(m.desktop)) {
snprintf(buf2, sizeof(buf2), "<desktop>%s</desktop>", m.desktop);
strcat(buf, buf2);
}
if (strlen(m.display)) {
snprintf(buf2, sizeof(buf2), "<display>%s</display>", m.display);
strcat(buf, buf2);
}
if (log_flags.scrsave_debug) {
msg_printf(wup->project, MSG_INFO,
"[scrsave] ACTIVE_TASK::request_graphics_mode(): requesting graphics mode %s for %s",
xml_graphics_modes[m.mode], result->name
);
}
graphics_request_queue.msg_queue_send(
buf,
app_client_shm.shm->graphics_request
);
}
// handle messages on the "graphics_reply" channel
//
void ACTIVE_TASK::check_graphics_mode_ack() {
GRAPHICS_MSG gm;
char buf[MSG_CHANNEL_SIZE];
#if (defined (__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
// PowerPC apps emulated on i386 Macs crash if running graphics
if (powerpc_emulated_on_i386) {
graphics_mode_acked = MODE_UNSUPPORTED;
return;
}
#endif
if (!app_client_shm.shm) return;
if (app_client_shm.shm->graphics_reply.get_msg(buf)) {
app_client_shm.decode_graphics_msg(buf, gm);
if (log_flags.scrsave_debug) {
msg_printf(wup->project, MSG_INFO,
"[scrsave] ACTIVE_TASK::check_graphics_mode_ack(): got graphics ack %s for %s, previous mode %s",
buf, result->name, xml_graphics_modes[graphics_mode_acked]
);
}
if (gm.mode != MODE_REREAD_PREFS) {
graphics_mode_acked = gm.mode;
}
}
}
void ACTIVE_TASK_SET::graphics_poll() {
unsigned int i;
ACTIVE_TASK* atp;
for (i=0; i<active_tasks.size(); i++) {
atp = active_tasks[i];
if (!atp->process_exists()) continue;
atp->graphics_request_queue.msg_queue_poll(
atp->app_client_shm.shm->graphics_request
);
atp->check_graphics_mode_ack();
}
}
bool ACTIVE_TASK::supports_graphics() {
#if (defined (__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
// PowerPC apps emulated on i386 Macs crash if running graphics
if (powerpc_emulated_on_i386)
return false;
#endif
if (graphics_mode_acked == MODE_UNSUPPORTED) return false;
if (scheduler_state != CPU_SCHED_SCHEDULED) return false;
return true;
}