gtk-server(1)

πŸ“¦ version 2.4.6, in alpine 3.24, nixos 26.05, nixpkgs unstable

πŸ’… gtk-server(1) β€” the manual, but make it make sense

okay so bestie, welcome to the General Commands Manual entry for gtk-server, and before you ask β€” yes, it's that gtk-server, and yes, we're gonna get through the whole thing together. grab a boba. πŸ§‹


✨ NAME ✨

gtk-server β€” it's literally GUI access for shellscripts and interpreted languages. that's the whole vibe. 🫢


🌸 SYNOPSIS 🌸

gtk-server <-stdin> | <-tcp>=host:port[:max] | <-sock>=host:port |
       <-udp>=host:port | <-fifo>=filename | <-ipc>=number [-log=filename]
       [-signal=number] [-cfg=filename] [-pre=string] [-post=string] [-handle]
       [-detach] [-nocreate] [-showconf] [-start=macro] [-init=handshake]
       [-ssl=[cert.pem]] [-password=passwd] [-ca=cert.pem]

like, yes, that's a lot of options. breathe. we'll go through every single one, i promise. πŸŽ€


πŸ¦‹ DESCRIPTION πŸ¦‹

So the GTK-server is a binary, right? and you can start it straight from a (shell-)script or from an interpreted language. no cap.

Once it's up, it reads the configuration file gtk-server.cfg, and after that your client script can execute GTK functions. and how do those functions get there? they're sent in plain text to the gtk-server, using a 2-way pipe, a named pipe, or a TCP or UDP connection. iconic behaviour honestly. ✨

Fun little lore drop: the GTK-server was inspired by dtksh for the Common Desktop Environment (CDE). yes, that CDE. we love a retro king. πŸ‘‘


πŸ”₯ ARGUMENTS πŸ”₯

The GTK-server must be started with one of the following arguments β€” like, pick one, bestie, it's not optional:

  • -stdin β€” starts the GTK-server with 2-way pipes. your client script language has to start a 2-way pipe to the GTK-server so they can actually talk. (in KSH and AWK, for example, the symbol |& is what does this.)
  • -tcp=host:port[:max] β€” starts the GTK-server as a TCP server. your client script language then connects to this host and port. commonly localhost and a portnumber higher than 1024 are used. the max part decides the maximum amount of client scripts that can connect β€” and if you omit max, only 1 client script may connect. so don't forget it unless you're feeling exclusive. πŸ’…
  • -sock=host:port β€” starts the GTK-server as a TCP client. here your client script language acts like a server, sending the commands to the GTK-server. role reversal, love that for them.
  • -udp=host:port β€” starts the GTK-server in UDP mode. your client script must connect to host and port using the UDP protocol.
  • -fifo=<file> β€” starts the GTK-server with a named pipe. the pipe is created by the GTK-server automatically and has the name of file. when the script is finished, the named pipe gets deleted automatically. and if you don't want the pipe created automatically? also use the option nocreate. πŸŽ€
  • -ipc=number β€” starts the GTK-server with a message queue. the number must lay within the range from 1 to 65535 and specifies the queue number. when the script is finished, the GTK-server will delete the message queue from memory.

after the GTK-server has been started with a message queue, subsequent GTK requests must be sent with the GTK-server binary using the argument msg. the number of the communication channel must be specified, as well as the string to be sent. for example:

gtk-server -msg=1,"gtk_init NULL NULL"

here a GTK function is sent to communication channel 1. make sure there is no space between the number, the comma and the string β€” otherwise the GTK-server will regard these as separate arguments and everything gets weird. 😭

message queues also can be retrieved using the Unix command ipcs, and can be deleted using the Unix command ipcrm. iykyk.


πŸ’œ OPTIONS πŸ’œ

The GTK-server accepts the following optional parameters β€” and yes, we're doing all of them:

  • -log=<filename> β€” starts the GTK-server in debug mode. a file with the name filename will be created. this logfile contains the strings which were received by the GTK-server, and the responses of the GTK-server to those strings. receipts, basically. πŸ“
  • -signal=<number> β€” define a signal which must be sent to the clientprogram when the GTK-server exits (UNIX only).
  • -cfg=<filename> β€” explains to the GTK-server where it can find the configfile if it cannot be found at a standard location. it's giving "google maps but for config files."
  • -pre=<string> β€” puts the specified string in front of the GTK-server returnstrings.
  • -post=<string> β€” puts the specified string behind the GTK-server returnstrings.
  • -nocreate β€” to be used in combination with the fifo option. when specified, the pipefile will not be created by the GTK-server β€” it must be created by the client program instead. your pipe, your problem. 🫢
  • -handle β€” this option can be used to synchronize communication. when specified, the client script can send requests starting with a self-defined handle, for example a unique number. the GTK-server will ignore this handle when parsing the incoming request, but the returnstring for this request will start with the same handle. matching tags, cute.
  • -detach β€” when specified, the GTK-server will try to spawn to the background. bye bestie πŸ‘‹
  • -showconf β€” when the GTK-server starts, it will read information about GTK-calls from the configfile. this argument dumps that information to stdout. this is particularly useful when debugging scripts. honestly a lifesaver ngl.
  • -start=<macro> β€” when the GTK-server starts, first execute the specified macro before doing anything else. priorities, it has them.
  • -init=<handshake> β€” when running in socket mode, the GTK-server can send a string to handshake and identify itself with the other side. hi, it's me. πŸ¦‹
  • -ssl[=cert.pem] β€” when running in socket mode, this option sets up an SSL connection. an optional certificatefile can be provided which is presented by the GTK-server to the remote host during the SSL negotiation. secure vibes only.
  • -ca=cert.pem β€” when running in socket mode, this option sets up an SSL connection. a certificatefile must be provided to this option to verify the certificate presented by the remote host. no cert, no entry.
  • -password=string β€” to be used in combination with the ssl option. this option should provide a password to decrypt the SSL certificate's key if the key was encrypted.
  • -debug β€” the GTK-server will start a small graphical panel containing the output of the information exchange between client script and GTK-server. four buttons are visible: (1) the "Step" button to execute the input from the client script line by line, (2) the "Run" button to let the client script execute its commands all at once, (3) the "Pause" button to pause such execution and (4) a "Quit" button to stop the GTK-server altogether. four buttons, main character energy each. πŸ‘‘
  • -nonl β€” by default, the GTK-server adds a newline after each reply. this option will prevent this from happening. no newline, just vibes.

🌈 SHEBANG 🌈

A GTK-server configfile can contain a standalone program implemented with macro's. and like with most Unix scripts, a shebang can be added to the first line of the configfile to execute it with the GTK-server:

#!/usr/bin/gtk-server -this

the GTK-server searches for a macro with the name main which will be executed first. main is the main character, obviously. ⭐


πŸ“ STRINGS πŸ“

Client programs can send strings to the GTK-server. if a string contains spaces, the client program should enclose the string within double quotes. alternatively, single quotes may be used as well. and to make sure the string arrives literally at the GTK-server including the single quotes, the whole string should be preceded with a @ symbol. little at-sign, big job. πŸ’–


🧚 SHARED OBJECT / DLL / MODULE 🧚

If the GTK-server is compiled as a shared object, the function gtk can be imported into the client program. all GTK calls can be passed as a stringargument to this function (formatted as S-expression). the function always will return a pointer to a string containing the result of the last GTK call. always. it's reliable like that. 🫢

The C-prototype definition for the gtk function in the GTK-server is as follows:

(char*) gtk (char* S-expression)

It's also possible to compile the GTK-server as an S-Lang, Scriptbasic or Kornshell module, which can be imported in a client program. see the respective directories in the sourcepackage for details. ✨

Only with a first call gtk_server_cfg to the imported gtk-function the options log, cfg, pre and post can be submitted. for example:

gtk "gtk_server_cfg log=/dir/logfile cfg=/my/dir/gtk-server.cfg post=."

now the GTK-server module will open the configfile at location /my/dir, output it's logging to the configured logfile and also will put a dot behind all returned answers. (these separate options also may be preceded by the dummy command gtk_server_cfg.) slay. πŸ’…


πŸ’€ INTERNAL COMMANDS πŸ’€

The GTK-server recognizes the following internal commands:

  • gtk_server_version β€” this command returns the current version of the GTK-server.
  • gtk_server_ffi β€” this command returns the Foreign Function interface which has been used to compile the GTK-server: FFI, FFCALL, C/Invoke or DYNCALL.
  • gtk_server_toolkit β€” this command returns the backend which has been used to compile the GTK-server: GTK1, GTK2 or XForms.
  • gtk_server_os β€” this command returns the platform for which the GTK-server was compiled.
  • gtk_server_enum β€” this command returns the value belonging to a enumeration defined in the GTK-server configfile. if the enumeration is not defined then an empty response is returned. example:
gtk_server_enum GTK_RESPONSE_OK
  • gtk_server_callback <argument> β€” with this command the client program will fetch a signal for one of the widgets. by default the widget ID is returned when a signal is received. if argument is 0, the command will return to the client program immediately, and the client program has to perform a GTK iteration by itself. if there was no signal, the returnvalue will be 0. if argument is 1, the command also will update all GTK widgets, but *only* return to the client script if a signal has occured. this setting will be appropriate in most situations. instead of 1 also the terms wait or WAIT may be used. finally, if argument is 2, the command will update all pending GTK-events and return immediately with the last known signal. if there was no signal, the returnvalue will be 0. instead of 2 also the terms update or UPDATE may be used. 🌸
okay that's part one bestie, don't go anywhere β€” there's more coming πŸŽ€

gtk_server_callback_value <argument> <type>

Okay so sometimes the values you need are hiding inside a callback, and this is the little function that goes in and grabs them for you πŸ’… Picture this: the "select-row" signal on the CList widget in GTK1 hands the row number and the column number straight to the callback function β€” they show up as the 1st and 2nd argument of that signal (and btw, argument 0 is the widget ID, always). So if you want the clicked column number of a CList widget, you just run gtk_server_callback_value 2 INT in your client program right after a signal fires on that widget, and boom β€” you've got the column 🌟

  • The first argument can be anything from 0 to 7.
  • The second argument, type, can be INT, STRING or POINTER β€” that's your type picker, bestie.
Heads up: this one is not available when GTK-server is compiled for the XForms or Motif backend. Sorry babe 😭

gtk_server_connect <widgetID> <signal> <description> [flag]

This one adds an extra callback signal to a widget, and it's lowkey one of the most useful things in here 🫢

  • First argument = the widget ID (which is what you got back when you created the widget, duh).
  • Second argument = the signal name, exactly like it's used in GTK programming β€” "clicked", "enter", "pressed", you know the vibe.
  • Third argument = the string that GTK-server will return to you when that signal goes off.
  • The optional last argument tells GTK to propagate the event further.

If [flag] is left out or is 0, the signal that happened only gets handled by your client program. Any value that isn't 0 will propagate the event to GTK as well β€” so GTK gets a turn too, main character energy for everyone ✨

XForms flavour: when GTK-server is compiled for XForms, the ID of the form has to be the first argument, and then you put in the event mask as the next one. That mask can be one of KeyPressMask, KeyReleaseMask, ButtonPressMask, ButtonReleaseMask, EnterWindowMask, LeaveWindowMask, PointerMotionMask or ButtonMotionMask. You can type them as a plain value (the ones mentioned in the X-Server header files) or define them as an ENUM in the GTK-server config file. Dealer's choice πŸ’–

Motif flavour: for Motif, the widget ID is the first argument and the name of the callback signal is the second. If that callback signal name is set as the original Motif string β€” like 'XmNactivateCallback' β€” then you can convert it to its real string using the STR_NAME configuration field in the GTK-server configfile. The real string names live in the header files from Motif, so go look there πŸ‘‘


gtk_server_connect_after <widgetID> <signal> <description> [flag]

Basically gtk_server_connect's sibling, except the signal fires after the other signals have done their thing πŸ¦‹ Same energy, different timing.

Not available when GTK-server is compiled for the XForms or Motif backend πŸ™ˆ

gtk_server_disconnect <widgetID> <description>

Breaking up with a signal πŸ’” This disconnects a signal from a widget that you previously set up with gtk_server_connect or gtk_server_connect_after.

Cute detail: signals that were defined in the configfile can also be disconnected β€” you just use the signal names as the description. So no ghost signals haunting you πŸ‘»

Not available when GTK-server is compiled for the XForms backend.

gtk_server_enable_c_string_escaping

Puts GTK-server into C escaping mode 😎 Here's the tea: returned strings get wrapped in double quotes, and by default these special characters β€” BELL, CR, newline, TAB, doublequote and backslash β€” get an escape sign '\' in front of them. Why do you care? Because it lets you debug strings without your client program actually interpreting the special characters. Iconic for debugging, ngl πŸŽ€

Wanna change which characters get the escape treatment? Use gtk_server_set_c_string_escaping (it's right below, keep scrolling bestie).


gtk_server_disable_c_string_escaping

Switches the C escaping mode back off. And yes β€” off is the default behavior, so if you never turned it on, you're already here 🌸


gtk_server_set_c_string_escaping <argument>

This is where you pick the set of characters that should get escaped before GTK-server hands them back to you. Customize your escape squad πŸ’…


gtk_server_enable_print_line_count

Okay this mode is genuinely so handy β€” it makes GTK-server print the number of lines contained in the returned string, right there on the first line πŸ“ Obsessed. This is what you want for grabbing multiline values when the server is started with 2-way pipes (the -stdin option).

Here's what the client-server interaction actually looks like:

> gtk_text_buffer_get_text <widgetID> <startIter> <endIter> 0
line1
line2
> gtk_server_enable_printing_line_count
1
ok
> gtk_text_buffer_get_text <widgetID> <startIter> <endIter> 0
2
line1
line2

See how the 2 shows up first the second time? That's the line count doing its thing ✨ (and yes, keep the command spelled exactly like that when you type it, bestie 🫢)


gtk_server_disable_print_line_count

Turns the line-count-printing mode back off β€” and again, off is the default, so nothing to do if you never enabled it πŸ¦‹


gtk_server_mouse <argument>

Mouse status check, let's gooo 🐭 With this call you can pull the status of the mouse pointer. Here's the decoder ring:

  • <argument> = 0 β†’ returns the x-coordinate of the mouse on the widget.
  • <argument> = 1 β†’ returns the y-coordinate on the widget.
  • <argument> = 2 β†’ returns the status of the mousebutton: a value of 1 (left button), 2 (middle button), 3 (right button), 4 or 5 (other buttons).
  • <argument> = 3 β†’ returns the direction of the scrollbutton(s) on the mouse: '0' means up, '1' down, '2' left and '3' means right.
For arguments 0/1/2 you must connect the 'button-press-event' signal to the widget. And for argument 3 you must connect the 'scroll-event' signal. No signal, no results, periodt πŸ’€

XForms: you need to connect the 'ButtonPressMask' and 'PointerMotion' mask to the form. Motif: the signal 'XmNinputCallback' should be connected to the DrawingArea.

For XForms, the result is an X event type enumeration β€” so if the return value is 256, the left mousebutton is pressed; 512 means the middle mousebutton is pressed; and 1024 means the right mousebutton is pressed. Modifier keys like CTRL, ALT, SHIFT etc. get notified too πŸ”₯ Here's the complete table of return values, no cap:

  • 1 = SHIFT KEY
  • 2 = CAPS_LOCK or SHIFT_LOCK
  • 4 = CONTROL KEY
  • 8 = MODIFIER1 (determined by the configuration of X)
  • 16 = MODIFIER2 (determined by the configuration of X)
  • 32 = MODIFIER3 (determined by the configuration of X)
  • 64 = MODIFIER4 (determined by the configuration of X)
  • 128 = MODIFIER5 (determined by the configuration of X)
  • 256 = MOUSEBUTTON1 (left)
  • 512 = MOUSEBUTTON2 (middle)
  • 1024 = MOUSEBUTTON3 (right)
  • 2048 = MOUSEBUTTON4
  • 4096 = MOUSEBUTTON5

The returned result can also be a combination of the values above πŸ‘‘ E.g. a result of 260 means that both the CTRL key and the left mousebutton are pressed at the same time. Slay, multitasking.


gtk_server_define <gtk function> <signal> <returnvalue> <amount> <arg1> ... <argn>

Defines a brand-new GTK function ✨ And plot twist β€” if that GTK function is already available in the configfile, it just gets redefined automatically. No drama. The syntax for defining a GTK function is the same kind of syntax used in the gtk-server.cfg file, so please refer to the man page of gtk-server.cfg for the details, bestie πŸ’–


gtk_server_redefine <gtk function> <signal> <returnvalue> <amount> <arg1> ... <argn>

Redefines a GTK function that's mentioned in the gtk-server.cfg file. And the reverse plot twist: if the GTK function isn't in the configfile, it'll just get defined as a new GTK function. Either way you win πŸŽ€

Same deal as above β€” the syntax is similar to the syntax used in the gtk-server.cfg file, so refer to the man page of gtk-server.cfg for details.


gtk_server_require <libraryname>

A vibe check for libraries πŸ” This checks whether <libraryname> is actually available on your system or not.

  • Not available? It returns a "0".
  • Available? It returns a "1".

And if <libraryname> isn't mentioned in the configfile, this call will try to open it during the runtime of the clientscript β€” living on the edge, love that for you 😌


gtk_server_timeout <milliseconds> <widget> <signal>

Sets up a timeout in the idle loop of GTK or Motif ⏰ When you're waiting for an event with gtk_server_callback wait, after however many milliseconds you configured, an event gets generated so the callback function returns with the configured widgetID or string. So cozy.

Make sure you connect the signal in the GTK-server configfile or with a gtk_server_connect-call first β€” otherwise the signal won't be recognised and you'll be sitting there like ?? 😭

This function returns a unique handle to identify the timeout, and you can use that handle to remove the timeout with gtk_server_timeout_remove. Also, important distinction: GTK will execute the timeout repeatedly, but in Motif the timeout will be executed once πŸ™ˆ

Not available when GTK-server is compiled for the XForms backend.

gtk_server_timeout_remove <handle>

Removes a timeout you set up earlier. Cleanup era πŸ’…

Not available when GTK-server is compiled for the XForms backend.

gtk_server_opaque

Returns an undefined widget 🫧 Use this when GTK has no explicit call to create a widget of a certain type β€” for example with GtkIter or GdkColor. It's giving "trust me, it's a widget."

Not available when GTK-server is compiled for the XForms or Motif backend.

gtk_server_toplevel

Returns the toplevel widget in an X hierarchy πŸ‘‘ Very main character.

This function is only available when GTK-server is compiled for the Motif backend.

gtk_server_echo <string1> <string2>...<stringn>

Debug function, but make it communication πŸ’¬ It returns the string that's sent to GTK-server β€” super convenient when you're in STDIN mode, or when you're using GTK-server from a programming language console. Bonus: you can also use this function to keep an IP connection open when running in TCP/UDP mode. Multitasking icon ✨


gtk_server_exit

Exits GTK-server and frees all allocated resources. Goodbye forever (affectionate) πŸ‘‹πŸ’–


gtk_server_pid

Returns the current process ID of GTK-server πŸ•΅οΈ (Unix only, bestie.)


gtk_server_macro_var <macro> <variablename>

Returns the value of a variable defined in a macro 🌸 Heads up: the variable names may vary from 'a' to 'z' β€” that's the whole range. See also the gtk-server.cfg manpage for more info on macros, iykyk πŸŽ€

  • gtk_server_macro_define <macrodefinition> β€” makes a whole new macro for you πŸ’… the definition has to be in the exact same format as it would be in the configfile, and the lines inside the macro get separated with a newline. want the full tea on macros? go read the gtk-server.cfg manpage, it's all there 🫢
  • gtk_server_macro_redefine <macrodefinition> β€” same energy as above but for a macro that already exists, so it gets a whole new personality ✨ definition format = same as the configfile, and again, the gtk-server.cfg manpage has the macro lore πŸ”₯
  • gtk_server_key β€” hands back the value of the last key that got pressed ⌨️ important: you have to connect the key-press-event to the widget first, otherwise GTK straight up won't recognize the event, no cap 😭 like this:
gtk_server_connect <widgetID> "key-press-event" "keypressed"

For XForms you gotta connect at least the KeyPressMask event mask to the form β€” XForms uses the standard event masks from the X header files. If KeyPressMask has a value of 1, connect it like this:

gtk_server_connect <formID> 1

For Motif, literally only the DrawingArea widget can capture input πŸ™ˆ so the signal XmNinputCallback needs to be connected to the DrawingArea:

gtk_server_connect <DrawingAreaID> "XmNinputCallback" "keypressed"
  • gtk_server_cfg β€” when the GTK-server is compiled as a library, this one sets the location of the log file plus other options πŸŽ€ example:
gtk_server_cfg -log=/tmp/gtk-server.log -post=. -debug
  • gtk_server_state β€” tells you the value of a state key if it's currently pressed πŸ‘‘ SHIFT down β†’ a 1 comes back, CTRL down β†’ 4, ALT down β†’ 8, and so on. In GTK you gotta connect key-press-event to the widget first or the event is not recognized by GTK, periodt. For Motif, the signal XmNinputCallback should be connected to the DrawingArea. heads up: this function is not available when the GTK-server has been compiled for the XForms backend πŸ’€ example:
GTK: gtk_server_connect <widgetID> "key-press-event" "keypressed"

Motif: gtk_server_connect <DrawingArea> XmNinputCallback "keypressed"
  • gtk_server_pack <format> <value1> [...value n] β€” returns a memory layout as a base64 encoded string 🧚 use it when one of the arguments in a GTK function is defined as BASE64 type, like when it's an array or a struct bestie. the <format> says what the types are, similar to how printf does it: %c is a char, %s means short, %i means integer, %l means long, %f means float and %d means double. the number of <values> should match the number of format specifiers, obvs ✨ example β€” creating a memory layout containing a struct with 4 integer members:
gtk_server_pack %i%i%i%i 1 1 5 6

the returned string AQAAAAEAAAAFAAAABgAAAA== can be passed on as an argument to the function which has BASE64 as argument type πŸŽ€

  • gtk_server_unpack <format> <base64 string> β€” returns an S-expression from a base64 encoded string πŸ¦‹ it's the one for when one of the arguments in a GTK function is defined as PTR_BASE64 type, like when an argument contains a definition for an array or a struct. <format> specifies the type, same printf-ish deal: %c is a char, %s means short, %i means integer, %l means long, %f means float and %d means double. example β€” unpacking a memory layout containing a struct with 4 integer members:
gtk_server_unpack %i%i%i%i AQAAAAEAAAAFAAAABgAAAA==

and this returns the string "1 1 5 6" 🌸

  • gtk_server_data_format <format> β€” sets the memory layout for PTR_BASE64 arguments πŸ’œ it should be set before the actual function with PTR_BASE64 argument types gets used, so like, don't be late to that party. example:
gtk_server_data_format %i%i%i%i
  • gtk_server_unpack_from_pointer <format> <pointer> β€” returns an S-expression from a memory area that a pointer points to 🌈 it's for when one of the arguments in a GTK function is defined as PTR_LONG type, like when an argument contains a pointer to an array or a struct. <format> specifies the type, printf-style again: %c is a char, %s means short, %i means integer, %l means long, %f means float and %d means double. example β€” unpacking a memory layout containing a struct with 3 integer members:
gtk_server_unpack_from_pointer %i%i%i 7478512
  • gtk_server_string_from_pointer <pointer> β€” returns a string from a pointer to a character pointer πŸ“ in C syntax that's the ** construct, which the GTK API sometimes uses when it's returning error messages. example:
gtk_server_string_from_pointer 62667232

πŸ“ FILES πŸ“

  • gtk-server.cfg β€” the configuration file for the GTK-server. that's the one, the blueprint, the moment πŸ’…

✨ EXAMPLES ✨

Examples of scripts using the GTK-server can be found in the sourcepackage 🫢 and if you want the freshest demoscripts, go consult http://www.gtk-server.org/ β€” that's the spot, iykyk πŸ”₯


πŸ‘‘ LICENSE πŸ‘‘

GPL License.

This program 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 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY 😭 not 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 this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.


πŸ’€ BUGS πŸ’€

Please report bugs to: bugs@gtk-server.org β€” tell them everything bestie, they wanna know πŸ™ˆ


🌟 SEE ALSO 🌟

stop-gtk-server(1), gtk-server.cfg(1)


πŸŽ€ AUTHORS πŸŽ€

Orignal concept, design and implementation by Peter van Eerten, e-mail : peter@gtk-server.org πŸ‘‘

Current version of the GTK-server was created with help of many others β€” see the CREDITS file in the sourcepackage for credits. it takes a village fr fr 🫢


and that's the whole page, bestie!! this was gtk-server(1), section 1 of the manual β€” mwah πŸ’‹ go build something iconic 🌈✨

πŸ“¦ where this page comes from