[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [pygame] windows screen saver in pygame?



"R. Alan Monroe" <amonroe@columbus.rr.com> writes:

> > It works, it works. I now have the preview working. I had to be
> > careful to not only do 'pygame.init()' after the os.environ calls
> but
> 
> > also do 'import pygame' after calling os.environ.
> 
> Cool, what kind of stub exe (.scr) are you using to spawn the python
> interpreter? Can you post its source?

Of course, it's just a very simple c++ program. 

By the way, I have a simple python script that makes an .exe file from
a python script too (just adds about 3 KB to the size of it). If you
use that you don't have to use the stub, you just make an exe of your
script and rename it to .scr. I think it is a drawback that python
doesn't provide for "real" executables under win32, in quite many
cases one has to provide tiny stub programs or dynamic link libraries
to bootstrap python into doing something useful on this platform. It
would be nice to have something like a generic .dll stub for python,
does anybody have any ideas on how to accomplish that?

Here is the source for a very simple pygame screensaver, it doesn't do
anything interesting, but allows me to see the different commandlines
and simulates the operation of a "real" screensaver.

import sys
import os
import pdb
import win32gui
import win32api
import win32con
import threading
import time

def DoScreensave():
    timerEvent = pygame.event.Event(USEREVENT + 1, {})
    pygame.time.set_timer(timerEvent.type, 1000)
    initialized = False
    flip = 1
    while 1:
        event = pygame.event.wait()
        print event
        if event.type == timerEvent.type:
            initialized = True
            if flip:
                screen.fill((250, 0, 0))
            else:
                screen.fill((0, 0, 196))
            flip = not flip
            pygame.display.flip()
        else:
            if initialized:
                 break

def MakeChildWindow(width, height):
    """

    The screensaver dialog tells us to stop previewing when it
    destroys our child window. As far as I have understood the win32
    documentation, we should paint on the this child window but pygame
    locks up when I try to do this, so the thing we use the window for
    is to catch WM_DESTROY and quit the previewing then.

    """
    wc = win32gui.WNDCLASS()
    wc.hInstance = win32api.GetModuleHandle(None)
    wc.hbrBackground = win32con.COLOR_WINDOW + 1
    wc.lpszClassName = 'SyverScreensaverClass'
    wc.lpfnWndProc = {win32con.WM_DESTROY:OnDestroy}
    classAtom = win32gui.RegisterClass(wc)
    childWnd = win32gui.CreateWindow(classAtom, 'SyverScreenTitle',
                            win32con.WS_CHILD | win32con.WS_BORDER,
                            0, 0, width, height,
                            hwnd,
                            0,
                            wc.hInstance,
                            None)
    win32gui.UpdateWindow(childWnd)

def OnDestroy(hwnd, msg, wparam, lparam):
    print 'Child Window destoyed'
    print hwnd, msg, wparam, lparam
    pygame.event.post(pygame.event.Event(USEREVENT, {}))
    
print 'Current directory is: ', os.getcwd()
print 'Printing from python', sys.argv

if len(sys.argv) == 1 or (len(sys.argv) == 2
                          and sys.argv[1].upper().startswith('/C:')):
    print 'Configuring Screensaver'
    print sys.argv
    pdb.set_trace()
    
elif len(sys.argv) > 2 and sys.argv[1].upper() == '/P':
    print 'Preview window mode'
    hwnd = int(sys.argv[2])
    left, top, right, bottom = win32gui.GetWindowRect(hwnd)
    width = right - left
    height = bottom - top
    assert (width, height) == (152, 112)
    MakeChildWindow(width, height)
    os.environ['SDL_VIDEODRIVER'] = 'windib'
    os.environ['SDL_WINDOWID'] = str(hwnd)
    import pygame
    from pygame.locals import *
    pygame.init()
    screen = pygame.display.set_mode((width, height))
    DoScreensave()
    #pdb.set_trace()

elif len(sys.argv) == 2 and sys.argv[1].upper() == '/S':
    print 'Normal screensaver operation'
    import pygame
    from pygame.locals import *
    pygame.init()
    screen = pygame.display.set_mode((640, 480), DOUBLEBUF|FULLSCREEN|HWSURFACE)
    DoScreensave()
else:
    print 'Unsupported commandline:', sys.argv
    pdb.set_trace()

print 'Printing from python over'
#pdb.set_trace()




#include <process.h>
#include <iostream>
#include <windows.h>
#include <scrnsave.h>

using namespace std;

int main(int argc, char* argv[])
{
    // first massage the cmdline arguments
    // we receive something like this:
    //
    // {"pythonscr.scr", "/S", "another"}
    //
    // We want to pass on this:
    //
    // {"python.exe", "scriptname.py" "/S", "another"}
    //
    // Which in turn is received as the scriptname.py sys.argv
    //
    // ['scriptname.py', '/S', 'another']
    char* args[30];
    args[0] = "python.exe";
    args[1] = "screensaver.py";    
    int argsIndex = 2;
    int argvIndex = 1; // skip argv[0] (we use python.exe instead)
    while (true){
        args[argsIndex] = argv[argvIndex]; 
        if (args[argsIndex] == NULL) { // argv is null terminated
				   // so we break after copying
				   // the NULL into args
            break;
        }
        argsIndex++;
	argvIndex++;
    }

    int retval = _spawnvp(_P_WAIT, "python.exe", args);
    cout<<"Return from python"<<retval<<endl;

    int index = 0;
    while (args[index] != NULL) {
        cout<<" Argument was: "<<args[index]<<endl;
        index++;
    }
    return 0;
}
# Microsoft Developer Studio Project File - Name="Screensav" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **

# TARGTYPE "Win32 (x86) Console Application" 0x0103

CFG=Screensav - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE 
!MESSAGE NMAKE /f "Screensav.mak".
!MESSAGE 
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE 
!MESSAGE NMAKE /f "Screensav.mak" CFG="Screensav - Win32 Debug"
!MESSAGE 
!MESSAGE Possible choices for configuration are:
!MESSAGE 
!MESSAGE "Screensav - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "Screensav - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE 

# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe

!IF  "$(CFG)" == "Screensav - Win32 Release"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x414 /d "NDEBUG"
# ADD RSC /l 0x414 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/Pythonscr.scr"
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Desc=Copy to working directory
PostBuild_Cmds=copy $(Target) ..\.
# End Special Build Tool

!ELSEIF  "$(CFG)" == "Screensav - Win32 Debug"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x414 /d "_DEBUG"
# ADD RSC /l 0x414 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/Pythonscr.scr" /pdbtype:sept

!ENDIF 

# Begin Target

# Name "Screensav - Win32 Release"
# Name "Screensav - Win32 Debug"
# Begin Source File

SOURCE=.\Screensav.cpp
# End Source File
# End Target
# End Project

-- 

Vennlig hilsen 

Syver Enstad