From dd4e95dc08087503e1467a3ba8c6d534f285d5dd Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 14 Nov 2006 20:09:26 +0000 Subject: Support running as a screensaver under X! Subversion-branch: /trunk/chocolate-doom Subversion-revision: 750 --- src/Makefile.am | 5 +- src/chocolate-doom-screensaver.desktop | 12 ++++ src/d_main.c | 6 +- src/doomstat.h | 1 + src/i_sound.c | 3 +- src/i_system.c | 10 ++- src/i_video.c | 122 ++++++++++++++++++++++++++++----- src/i_video.h | 2 + 8 files changed, 140 insertions(+), 21 deletions(-) create mode 100644 src/chocolate-doom-screensaver.desktop diff --git a/src/Makefile.am b/src/Makefile.am index 5d038675..bb44f207 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -138,7 +138,10 @@ endif chocolate_doom_LDADD = ../textscreen/libtextscreen.a @LDFLAGS@ @SDL_LIBS@ @SDLMIXER_LIBS@ @SDLNET_LIBS@ -EXTRA_DIST = convert-icon chocolate_doom_icon.c +EXTRA_DIST = \ + convert-icon \ + chocolate_doom_icon.c \ + chocolate-doom-screensaver.desktop .rc.o: $(WINDRES) $^ -o $@ diff --git a/src/chocolate-doom-screensaver.desktop b/src/chocolate-doom-screensaver.desktop new file mode 100644 index 00000000..d90127a3 --- /dev/null +++ b/src/chocolate-doom-screensaver.desktop @@ -0,0 +1,12 @@ + +[Desktop Entry] +Encoding=UTF-8 +Name=Doom +Comment=DOOM by Id Software. +TryExec=chocolate-doom +Exec=chocolate-doom +StartupNotify=false +Terminal=false +Type=Application +Categories=Screensaver + diff --git a/src/d_main.c b/src/d_main.c index 707f8c99..9d3e0076 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -111,6 +111,10 @@ boolean fastparm; // checkparm of -fast boolean singletics = false; // debug flag to cancel adaptiveness +// If true, game is running as a screensaver + +boolean screensaver_mode = false; + //extern int soundVolume; //extern int sfxVolume; @@ -1295,7 +1299,7 @@ void D_DoomMain (void) char demolumpname[9]; FindResponseFile (); - + // print banner PrintBanner(PACKAGE_STRING); diff --git a/src/doomstat.h b/src/doomstat.h index e49ee54f..4fc174cd 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -55,6 +55,7 @@ extern boolean fastparm; // checkparm of -fast extern boolean devparm; // DEBUG: launched with -devparm +extern boolean screensaver_mode; // game running as a screensaver? // ----------------------------------------------------- // Game Mode - identify IWAD as shareware, retail etc. diff --git a/src/i_sound.c b/src/i_sound.c index 5bc9d109..165be416 100644 --- a/src/i_sound.c +++ b/src/i_sound.c @@ -462,8 +462,9 @@ I_InitSound() // If music or sound is going to play, we need to at least // initialise SDL + // No sound in screensaver mode. - if (nomusicparm && nosfxparm) + if (screensaver_mode || (nomusicparm && nosfxparm)) return; if (SDL_Init(SDL_INIT_AUDIO) < 0) diff --git a/src/i_system.c b/src/i_system.c index bf8daa3a..4f1bdac3 100644 --- a/src/i_system.c +++ b/src/i_system.c @@ -106,6 +106,7 @@ byte *I_ZoneBase (int *size) // void I_Init (void) { + I_CheckIsScreensaver(); I_InitSound(); I_InitMusic(); I_InitTimer(); @@ -164,10 +165,15 @@ void I_Quit (void) G_CheckDemoStatus(); I_ShutdownSound(); I_ShutdownMusic(); - M_SaveDefaults (); + + if (!screensaver_mode) + { + M_SaveDefaults (); + } + I_ShutdownGraphics(); - if (show_endoom && !testcontrols) + if (show_endoom && !testcontrols && !screensaver_mode) { I_Endoom(); } diff --git a/src/i_video.c b/src/i_video.c index 6604ca04..669e6eec 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -132,6 +132,11 @@ int mouse_threshold = 10; static boolean MouseShouldBeGrabbed() { + // never grab the mouse when in screensaver mode + + if (screensaver_mode) + return false; + // if the window doesnt have focus, never grab it if (!window_focused) @@ -382,6 +387,11 @@ void I_GetEvent(void) continue; } + if (screensaver_mode && sdlevent.type == SDL_QUIT) + { + I_Quit(); + } + // process event switch (sdlevent.type) @@ -392,11 +402,13 @@ void I_GetEvent(void) event.data2 = sdlevent.key.keysym.unicode; D_PostEvent(&event); break; + case SDL_KEYUP: event.type = ev_keyup; event.data1 = TranslateKey(&sdlevent.key.keysym); D_PostEvent(&event); break; + /* case SDL_MOUSEMOTION: event.type = ev_mouse; @@ -406,6 +418,7 @@ void I_GetEvent(void) D_PostEvent(&event); break; */ + case SDL_MOUSEBUTTONDOWN: if (usemouse && !nomouse) { @@ -415,6 +428,7 @@ void I_GetEvent(void) D_PostEvent(&event); } break; + case SDL_MOUSEBUTTONUP: if (usemouse && !nomouse) { @@ -424,15 +438,18 @@ void I_GetEvent(void) D_PostEvent(&event); } break; + case SDL_QUIT: // bring up the "quit doom?" prompt S_StartSound(NULL,sfx_swtchn); M_QuitDOOM(0); break; + case SDL_ACTIVEEVENT: // need to update our focus state UpdateFocus(); break; + default: break; } @@ -534,18 +551,10 @@ static void UpdateGrab(void) static void BlitArea(int x1, int y1, int x2, int y2) { int w = x2 - x1; - int y_offset; + int x_offset, y_offset; - // Y offset when running in letterbox mode - - if (fullscreen == FULLSCREEN_LETTERBOX) - { - y_offset = (LETTERBOX_SCREENHEIGHT - SCREENHEIGHT) / 2; - } - else - { - y_offset = 0; - } + x_offset = ((screen->w / screenmultiply) - SCREENWIDTH) / 2; + y_offset = ((screen->h / screenmultiply) - SCREENHEIGHT) / 2; // Need to byte-copy from buffer into the screen buffer @@ -559,7 +568,8 @@ static void BlitArea(int x1, int y1, int x2, int y2) { pitch = screen->pitch; bufp = screens[0] + y1 * SCREENWIDTH + x1; - screenp = (byte *) screen->pixels + (y1 + y_offset) * pitch + x1; + screenp = (byte *) screen->pixels + (y1 + y_offset) * pitch + + x1 + x_offset; for (y=y1; ypixels + (y1 + y_offset) * pitch - + x1 * 2; + + (x1 + x_offset) * 2; screenp2 = screenp + screen->pitch; for (y=y1; ypixels + (y1 + y_offset) * pitch - + x1 * 3; + + (x1 + x_offset) * 3; screenp2 = screenp + screen->pitch; screenp3 = screenp2 + screen->pitch; @@ -664,7 +674,7 @@ static void BlitArea(int x1, int y1, int x2, int y2) bufp = screens[0] + y1 * SCREENWIDTH + x1; screenp = (byte *) screen->pixels + (y1 + y_offset) * pitch - + x1 * 4; + + (x1 + x_offset) * 4; screenp2 = screenp + screen->pitch; screenp3 = screenp2 + screen->pitch; screenp4 = screenp3 + screen->pitch; @@ -1041,10 +1051,75 @@ static void AutoAdjustSettings(void) } } +// Check if we have been invoked as a screensaver by xscreensaver. + +void I_CheckIsScreensaver(void) +{ + char *env; + + env = SDL_getenv("XSCREENSAVER_WINDOW"); + + if (env != NULL) + { + screensaver_mode = true; + } +} + +// In screensaver mode, pick a screenmultiply value that fits +// inside the screen. It is okay to do this because settings +// are not saved in screensaver mode. + +static void FindScreensaverMultiply(void) +{ + int i; + + for (i=1; i<=4; ++i) + { + if (SCREENWIDTH * i <= screen->w + && SCREENHEIGHT * i <= screen->h) + { + screenmultiply = i; + } + } +} + +// Blank cursor so we don't see the mouse. It is not okay to +// do SDL_ShowCursor(0) because this will hide the mouse in +// the configuration dialog. Only show no mouse when over this +// window. + +static void SetBlankCursor(void) +{ + Uint8 zero = zero; + SDL_Cursor *cursor; + + cursor = SDL_CreateCursor(&zero, &zero, 1, 1, 0, 0); + + SDL_SetCursor(cursor); +} + void I_InitGraphics(void) { SDL_Event dummy; int flags = 0; + char *env; + + // Pass through the XSCREENSAVER_WINDOW environment variable to + // SDL_WINDOWID, to embed the SDL window into the Xscreensaver + // window. + + env = SDL_getenv("XSCREENSAVER_WINDOW"); + + if (env != NULL) + { + char winenv[30]; + int winid; + + sscanf(env, "0x%x", &winid); + sprintf(winenv, "SDL_WINDOWID=%i", winid); + + SDL_putenv(winenv); + } #ifdef _WIN32 @@ -1096,6 +1171,12 @@ void I_InitGraphics(void) flags |= SDL_FULLSCREEN; } + if (screensaver_mode) + { + windowwidth = 0; + windowheight = 0; + } + screen = SDL_SetVideoMode(windowwidth, windowheight, 8, flags); if (screen == NULL) @@ -1103,6 +1184,15 @@ void I_InitGraphics(void) I_Error("Error setting video mode: %s\n", SDL_GetError()); } + // In screensaver mode, screenmultiply as large as possible + // and set a blank cursor. + + if (screensaver_mode) + { + FindScreensaverMultiply(); + SetBlankCursor(); + } + // Start with a clear black screen // (screen will be flipped after we set the palette) @@ -1137,7 +1227,7 @@ void I_InitGraphics(void) // setting the screen mode, so that the game doesn't start immediately // with the player unable to see anything. - if (fullscreen) + if (fullscreen && !screensaver_mode) { SDL_Delay(startup_delay); } diff --git a/src/i_video.h b/src/i_video.h index 2df17962..e9904fd8 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -58,6 +58,8 @@ void I_EndRead (void); void I_SetWindowCaption(void); void I_SetWindowIcon(void); +void I_CheckIsScreensaver(void); + extern int autoadjust_video_settings; extern boolean screenvisible; extern int screenmultiply; -- cgit v1.2.3