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.:
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]
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.
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
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:
importstrazoloidwmasstzdesk=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()
whats event_test you might ask? well:
defevent_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.
ifframeobj.statflg==1:print(frameobj.name+" stat 1: init call")elifframeobj.statflg==2:print(frameobj.name+" stat 2: post-resize call")elifframeobj.statflg==3:print(frameobj.name+" stat 3: frame terminate call. type:")ifframeobj.runflg==0:print(" run 0: wm quit call")print(frameobj.pid)print(frameobj.wo)ifframeobj.runflg==2:#the desktop class should never set runflg=2
print(" run 2: frame (window) close call")print(frameobj.pid)print(frameobj.wo)elifframeobj.statflg==4:print(frameobj.name+" stat 4: clickdown")elifframeobj.statflg==5:print(frameobj.name+" stat 5: clickup")elifframeobj.statflg==6:print(frameobj.name+" stat 6: keydown")elifframeobj.statflg==7:print(frameobj.name+" stat 7: keyup")elifframeobj.statflg==8:print(frameobj.name+" stat 8: desktop window resize")elifframeobj.statflg==9:print(frameobj.name+" stat 9: frame shade")elifframeobj.statflg==10:print(frameobj.name+" stat 10: frame unshade")
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.
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…
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.