DEV Community

Thomas Leathers
Thomas Leathers

Posted on

pygame, gopherspace, and window managers

Some people may think pygame is mostly useful for games and multimedia, that's not all its useful for. Some people may also think you can't use multiple windows in pygame. While the latter is true, i managed to work around that.

What is gopherspace

First off, I want to give a brief description of what gopherspace actually is.

Way back before the web, in the year 1991, a new protocol emerged onto the internet. Gopher. Rather than being hyper text, or as crude as a FTP directory listing, gopher is kinda in-between.

Gopherspace is really just one big series of menus. No scripts, no more formatting than a plain .txt document, and no CSS. Over the years, gopher slid into obsucurity. However, its still out there, in part to its absurdly simple protocol:

Step 1:

client connects to server.

Step 2:

client sends a 'selector' aka path of the desired document, a tap+query if its a search query, and a CR+LF.:

/some/document[CRLF]
/some/query[tab]some search terms[CRLF]
Enter fullscreen mode Exit fullscreen mode

Step 3:

Client waits for server to send the full document/file selected, or, if an error occurs, usually an error page containing item type '3'

The Menus:

A gopher menu's synax probably couldn't be simpler (literally):
usually the port is 70. The first char of each line defines the item's type.
notice the 'i' type has a 'null' selector field, as its not supposed to be even selectable.

iI'm an information type[tab]null[tab]server[tab]port[CRLF]
1I'm a gopher menu somewhere[tab]/this/is/a/selector/[tab]server[tab]port[CRLF]
0I'm a text document somewhere[tab]/this/is/a/selector/also.txt[tab]server[tab]port[CRLF]
7I'm a text query (or index search) somewhere[tab]/some/search[tab]server[tab]port[CRLF]
Enter fullscreen mode Exit fullscreen mode

a type '3' is returned upon an error of some kind. most commonly a nonexistent selector, which is akin to a 404 error.

There are plenty of other types and things, but that's the basics.

how i got around pygame/sdl's 1-window limit (sort of ;D )

Now to the fun part. how do you run multiple windows, while you only have 1?
a virtual window manager.

GitHub logo ThomasTheSpaceFox / Strazoloid-windowing-framework

Strazoloid is a virtual window manager for pygame applications & games. Useful for creating custom multi-window enviornments. such as with many 2D simulation games.

Strazoloid windowing framework

v1.4.0
a Python/pygame virtual window manager framework.
Copyright (c) 2018-2020 Thomas Leathers and Contributors

Need help? For documentation see the docs directory

Strazoloid windowing framework is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Strazoloid windowing framework 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 General Public License for more details.

You should have received a copy of the GNU General Public License along with Strazoloid windowing framework. If not, see http://www.gnu.org/licenses/.

all images and other media content, unless otherwise noted are licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a…

I actually had already written the basic structure of strazoloid before working on zoxenpher, but it was greatly improved.

Starting up strazoloidwm is easy enough:

import strazoloidwm as stz
desk=stz.desktop(800, 600, "This is the window title", pumpcall=event_test, resizable=1)
#init Framework
framesc=stz.framescape(desk)
#create new 'framex' object (virtual window)
testframe2=stz.framex(200, 100, "test2", pumpcall=event_test)
#add the frame (window) to our framescape instance.
framesc.add_frame(testframe2)
#hand over main thread to framescape instance, starting the window manager.
framesc.process()
Enter fullscreen mode Exit fullscreen mode

whats event_test you might ask? well:

def event_test(frameobj, data=None):
    #note: you should make sure all non if-statement code is behind if statements. see comments on frame/desktop flags below.
    if frameobj.statflg==1:
        print(frameobj.name + " stat 1: init call")
    elif frameobj.statflg==2:
        print(frameobj.name + " stat 2: post-resize call")
    elif frameobj.statflg==3:
        print(frameobj.name + " stat 3: frame terminate call. type:")
        if frameobj.runflg==0:
            print("   run 0: wm quit call")
            print(frameobj.pid)
            print(frameobj.wo)
        if frameobj.runflg==2:#the desktop class should never set runflg=2
            print("   run 2: frame (window) close call")
            print(frameobj.pid)
            print(frameobj.wo)
    elif frameobj.statflg==4:
        print(frameobj.name + " stat 4: clickdown")
    elif frameobj.statflg==5:
        print(frameobj.name + " stat 5: clickup")
    elif frameobj.statflg==6:
        print(frameobj.name + " stat 6: keydown")
    elif frameobj.statflg==7:
        print(frameobj.name + " stat 7: keyup")
    elif frameobj.statflg==8:
        print(frameobj.name + " stat 8: desktop window resize")
    elif frameobj.statflg==9:
        print(frameobj.name + " stat 9: frame shade")
    elif frameobj.statflg==10:
                print(frameobj.name + " stat 10: frame unshade")
Enter fullscreen mode Exit fullscreen mode

Whats all the statflg checks? well. that's how strazoloidwm lets the program know, what reason frame/desktop object's 'pumpcall' was called. Note that pumpcall can easily be a class instance method.

You can find a full test program here.

Zoxenpher

GitHub logo ThomasTheSpaceFox / Zoxenpher

A python/pygame gopherspace client, in the style of a retro desktop GUI.

Zoxenpher

A python & pygame gopher client.
v3.0.0.indev

powered by:

  • libgop gopher library v0.2
  • strazoloid virtual window manager framework v1.4.0

Screenshot of Zoxenpher

Copyright (c) 2018-2020 Thomas Leathers and contributors

Zoxenpher is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Zoxenpher 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with Zoxenpher. If not, see http://www.gnu.org/licenses/.

all images and other media content, unless otherwise noted,
are licensed under the Creative Commons Attribution-ShareAlike 4.0
International License. To view a copy of this license…



Screenshot of zoxenpher

Combining a custom gopher parser/access library, and some implementation-specific code, and the power of strazoloidwm, zoxenpher Is a neat gopher client sure, i was able to get the basic functionality up and going quite quickly, as much of the grunt work was already handled by strazoloidwm.

Its complete with bookmarks, window-history navigation, images and even sound type support. plus using pygame allowed me to give it a bit of a retro-ish look that fits the protocol quite well i think.

Top comments (0)