PSALM - demo4.lsp
Not logged in
#!/usr/bin/newlisp
#
# Demonstration on how to create a GTK GUI using Psalm with newLisp 10.7.5 using TCP.
#
# Supposes the presence of 'socat' on the system. Requires Psalm 1.0.8 or higher.
#
# When using a remote system, socat must be started specifying the IP address of that system, eg:
#   socat EXEC:./psalm TCP-LISTEN:50000,bind=1.2.3.4 &
#
# The script on this system should then setup the appropriate socket:
#   (until (!= socket nil) (set 'socket (net-connect "1.2.3.4" 50000)))
#
# When Psalm is running on a remote system then extra measures must be taken to accomplish a GUI.
# For non-GUI programs it should be fine though.
#
# Run this script as follows:
#   ./demo4.lsp
#
# December 18, 2022 by Peter van Eerten.
#
#------------------------------------------------------------------------------------

# Define communication function
(define (comm str)
    (net-send socket (append str "\n"))
    (net-receive socket tmp 64)
    (trim tmp))

# Start psalm in TCP server mode using socat
(! "socat EXEC:./psalm TCP-LISTEN:50000 &")

# Connect to the GTK-server
(until (!= socket nil) (set 'socket (net-connect "localhost" 50000)))

# Send definitions first
(comm "DEF libgtk-3.so.0 void gtk_init int int")
(comm "DEF libgtk-3.so.0 long gtk_window_new int")
(comm "DEF libgtk-3.so.0 void gtk_window_set_title int char*")
(comm "DEF libgtk-3.so.0 void gtk_window_set_position long int")
(comm "DEF libgtk-3.so.0 long gtk_button_new_with_label char*")
(comm "DEF libgtk-3.so.0 long gtk_table_new int int int")
(comm "DEF libgtk-3.so.0 void gtk_table_attach_defaults long long int int int int")
(comm "DEF libgtk-3.so.0 long gtk_entry_new void")
(comm "DEF libgtk-3.so.0 char* gtk_entry_get_text long")
(comm "DEF libgtk-3.so.0 void gtk_main_iteration void")
(comm "DEF libgtk-3.so.0 void gtk_widget_show_all int")
(comm "DEF libgtk-3.so.0 void gtk_widget_set_size_request long int int")
(comm "DEF libgtk-3.so.0 void gtk_container_add long long")
(comm "DEF libgobject-2.0.so.0 long g_signal_connect_data int char* address void* void* int")

# Setup GUI
(comm "EXE gtk_init NULL NULL")
(set 'window (comm "EXE gtk_window_new 0"))
(comm (append "EXE gtk_window_set_title " window " \"This is a title\""))
(comm (append "EXE gtk_widget_set_size_request " window " 100 100"))
(comm (append "EXE gtk_window_set_position " window " 1"))
(set 'table (comm "EXE gtk_table_new 30 30 1"))
(comm (append "EXE gtk_container_add " window " " table))
(set 'button1 (comm "EXE gtk_button_new_with_label Exit"))
(comm (append "EXE gtk_table_attach_defaults " table " " button1 " 17 28 20 25"))
(set 'button2 (comm "EXE gtk_button_new_with_label \"Print text\""))
(comm (append "EXE gtk_table_attach_defaults " table " " button2 " 2 13 20 25"))
(set 'entry (comm "EXE gtk_entry_new"))
(comm (append "EXE gtk_table_attach_defaults " table " " entry " 2 28 5 10"))
(comm (append "EXE gtk_widget_show_all " window))

# Connect signals
(comm (append "EXE g_signal_connect_data " window " delete-event callback NULL NULL 0"))
(comm (append "EXE g_signal_connect_data " button1 " clicked callback NULL NULL 0"))
(comm (append "EXE g_signal_connect_data " button2 " clicked callback NULL NULL 0"))

# Mainloop starts here
(until (or (= event button1) (= event window))
    (comm "EXE gtk_main_iteration")
    (set 'event (comm "CALLBACK 1"))
    (if (= event button2)
        (println "This is the contents: " (comm (append "EXE gtk_entry_get_text " entry)))
    )
)

# Exit Psalm
(comm "EXIT")

# Exit newLisp
(exit)

Return to PSALM