shithub: choc

Download patch

ref: dd4e95dc08087503e1467a3ba8c6d534f285d5dd
parent: daaf0d1fcf4d3ed5c77806b3ea15db0f3a787f1e
author: Simon Howard <fraggle@gmail.com>
date: Tue Nov 14 15:09:26 EST 2006

Support running as a screensaver under X!

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 750

--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -138,7 +138,10 @@
 
 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 $@
--- /dev/null
+++ b/src/chocolate-doom-screensaver.desktop
@@ -1,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
+
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -111,7 +111,11 @@
 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;
 //extern  int	musicVolume;
@@ -1295,7 +1299,7 @@
     char            demolumpname[9];
 
     FindResponseFile ();
-	
+
     // print banner
 
     PrintBanner(PACKAGE_STRING);
--- a/src/doomstat.h
+++ b/src/doomstat.h
@@ -55,6 +55,7 @@
 extern  boolean	devparm;	// DEBUG: launched with -devparm
 
 
+extern  boolean screensaver_mode;    // game running as a screensaver?
 
 // -----------------------------------------------------
 // Game Mode - identify IWAD as shareware, retail etc.
--- a/src/i_sound.c
+++ b/src/i_sound.c
@@ -462,8 +462,9 @@
 
     // 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)
--- a/src/i_system.c
+++ b/src/i_system.c
@@ -106,6 +106,7 @@
 //
 void I_Init (void)
 {
+    I_CheckIsScreensaver();
     I_InitSound();
     I_InitMusic();
     I_InitTimer();
@@ -164,10 +165,15 @@
     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();
     }
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -132,6 +132,11 @@
 
 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 @@
             continue;
         }
 
+        if (screensaver_mode && sdlevent.type == SDL_QUIT)
+        {
+            I_Quit();
+        }
+
         // process event
         
         switch (sdlevent.type)
@@ -392,11 +402,13 @@
 		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 @@
                 D_PostEvent(&event);
                 break;
                 */
+
             case SDL_MOUSEBUTTONDOWN:
 		if (usemouse && !nomouse)
 		{
@@ -415,6 +428,7 @@
                     D_PostEvent(&event);
 		}
                 break;
+
             case SDL_MOUSEBUTTONUP:
 		if (usemouse && !nomouse)
 		{
@@ -424,15 +438,18 @@
                     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 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 @@
         {
             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; y<y2; ++y)
             {
@@ -586,7 +596,7 @@
             bufp = screens[0] + y1 * SCREENWIDTH + x1;
             screenp = (byte *) screen->pixels 
                     + (y1 + y_offset) * pitch 
-                    + x1 * 2;
+                    + (x1 + x_offset) * 2;
             screenp2 = screenp + screen->pitch;
     
             for (y=y1; y<y2; ++y)
@@ -623,7 +633,7 @@
             bufp = screens[0] + y1 * SCREENWIDTH + x1;
             screenp = (byte *) screen->pixels 
                     + (y1 + y_offset) * pitch 
-                    + x1 * 3;
+                    + (x1 + x_offset) * 3;
             screenp2 = screenp + screen->pitch;
             screenp3 = screenp2 + screen->pitch;
     
@@ -664,7 +674,7 @@
             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,11 +1051,76 @@
     }
 }
 
+// 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
 
     // Allow -gdi as a shortcut for using the windib driver.
@@ -1096,6 +1171,12 @@
         flags |= SDL_FULLSCREEN;
     }
 
+    if (screensaver_mode)
+    {
+        windowwidth = 0;
+        windowheight = 0;
+    }
+
     screen = SDL_SetVideoMode(windowwidth, windowheight, 8, flags);
 
     if (screen == NULL)
@@ -1103,6 +1184,15 @@
         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 @@
     // 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);
     }
--- a/src/i_video.h
+++ b/src/i_video.h
@@ -58,6 +58,8 @@
 void I_SetWindowCaption(void);
 void I_SetWindowIcon(void);
 
+void I_CheckIsScreensaver(void);
+
 extern int autoadjust_video_settings;
 extern boolean screenvisible;
 extern int screenmultiply;