Author Topic: GTK-Server 64  (Read 8912 times)

Offline John

  • Forum Support / SB Dev
  • Posts: 3562
    • ScriptBasic Open Source Project
GTK-Server 64
« on: April 23, 2011, 11:57:23 PM »
I was able to create a GTK-Server under Ubuntu 10.10 64 bit.



My next step is getting the custom version of GTK-Server for ScriptBasic (shared object extension module) I modified compiled so I can start scripting API's rather than having the write dedicated shared objects as interfaces.

 
« Last Edit: April 23, 2011, 11:59:19 PM by ABB »

Offline John

  • Forum Support / SB Dev
  • Posts: 3562
    • ScriptBasic Open Source Project
Re: GTK-Server 64
« Reply #1 on: April 25, 2011, 02:04:42 AM »
I was able to compile a 64 bit version of GTK-Server for ScriptBasic as a shared object extension module. Here is Peter's online dictionary example using his HUG library.




Offline John

  • Forum Support / SB Dev
  • Posts: 3562
    • ScriptBasic Open Source Project
Re: GTK-Server 64
« Reply #2 on: April 26, 2011, 09:39:18 AM »
This is an example of scripting the SQLite3 API rather then having to create a C extension module in ScriptBasic. (Ubuntu 64) My plan is to provide a suite of popular library interfaces in a scripted format. The addition of VARPTR to the SB version of GTK-Server has extended the reach of API scripting in an interpretive environment.

Code: [Select]
' SQLite3 Test Script

DECLARE SUB DLL ALIAS "_idll" LIB "gtk-server"
DECLARE SUB REQUIRE ALIAS "_idll_require" LIB "gtk-server"
DECLARE SUB DEFINE ALIAS "_idll_define" LIB "gtk-server"
DECLARE SUB VARPTR ALIAS "varptr" LIB "gtk-server"

REQUIRE "libsqlite3.so"

DEFINE "sqlite3_open NONE INT 2 STRING LONG"
DEFINE "sqlite3_exec NONE INT 5 LONG STRING INT NULL PTR_STRING"
DEFINE "sqlite3_prepare_v2 NONE INT 5 LONG STRING INT PTR_LONG NULL"
DEFINE "sqlite3_step NONE INT 1 LONG"
DEFINE "sqlite3_column_text NONE STRING 2 LONG INT"
DEFINE "sqlite3_close NONE INT 1 LONG"

CONST SQLITE_ROW = 100
db = 0
dberr = 0
stmt = 0

DLL("sqlite3_open \"testsql\" " & VARPTR(db))
errmsg = DLL("sqlite3_exec " & db & " \"CREATE TABLE demo(someval INTEGER,  sometxt TEXT);\" 0 0 " & VARPTR(dberr))
PRINT "DB ERROR: ",errmsg,"\n"
DLL("sqlite3_exec " & db & " \"INSERT INTO demo VALUES (123, 'Hello');\" 0 0 " & VARPTR(dberr))
DLL("sqlite3_exec " & db & " \"INSERT INTO demo VALUES (234, 'cruel');\" 0 0 " & VARPTR(dberr))
DLL("sqlite3_exec " & db & " \"INSERT INTO demo VALUES (345, 'world');\" 0 0 " & VARPTR(dberr))
result = DLL("sqlite3_prepare_v2 " & db & " \"SELECT * FROM demo;\" -1 " & VARPTR(stmt) & " 0")
SPLIT result BY " " TO ok, stmt

WHILE DLL("sqlite3_step " & stmt) = SQLITE_ROW
  PRINT DLL("sqlite3_column_text " & stmt & " " & 0) & " - " & DLL("sqlite3_column_text " & stmt & " " & 1),"\n"
WEND

DLL("sqlite3_close " & db)

jrs@laptop:~/sb/test$ scriba sqlite3.sb
DB ERROR: 0 (null)
123 - Hello
234 - cruel
345 - world
jrs@laptop:~/sb/test$

A few advantages I see scripting an API over linking with a compiler.

  • Error isolation. If I do something wrong at the interface level, GTK-Server complains and causes an exception (error) with SB. If the interface is returning an error like no more rows to fetch, I can deal with it in my script and SB continues on as normal.
  • If the interface changes, you only need to modify your script with no recompile of an interface.
  • DEFINE only the functions you need for your application.
  • It should only take minor tweaking of your scripts to get a multi-platform API to run on any OS.

« Last Edit: April 26, 2011, 01:21:04 PM by ABB »

Offline John

  • Forum Support / SB Dev
  • Posts: 3562
    • ScriptBasic Open Source Project
Re: GTK-Server 64
« Reply #3 on: April 26, 2011, 09:11:43 PM »
For those interested in the changes made to GTK-Server for ScriptBasic, here is the code.

Code: [Select]
#ifdef GTK_SERVER_SCRIPTBASIC
besVERSION_NEGOTIATE
    return (int)INTERFACE_VERSION;
besEND

besSUB_START

besEND

besSUB_FINISH

besEND

besFUNCTION(_idll)
    VARIABLE ptr;
    char* arg0;
    char* retstr;

    if(besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
    if(besARGNR<1) return EX_ERROR_TOO_FEW_ARGUMENTS;

    ptr = besARGUMENT(1);
    besDEREFERENCE(ptr);
    arg0 = besCONVERT2ZCHAR(besCONVERT2STRING(ptr),arg0);

    retstr = (char*)gtk(arg0);

    besALLOC_RETURN_STRING(strlen(retstr));
    memcpy(STRINGVALUE(besRETURNVALUE),retstr,strlen(retstr));

    besFREE(arg0);
besEND

besFUNCTION(varptr)
  VARIABLE ptr;

  if(besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
  if(besARGNR<1) return EX_ERROR_TOO_FEW_ARGUMENTS;

  besALLOC_RETURN_LONG
 
  ptr = besARGUMENT(1);
  besDEREFERENCE(ptr);
 
  LONGVALUE(besRETURNVALUE) = (int)ptr;

besEND

besFUNCTION(_idll_require)
    VARIABLE ptr;
    char* arg0;
    char* retstr;
    char sb_require[64];

    strcpy (sb_require,"gtk_server_require ");

    if(besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
    if(besARGNR<1) return EX_ERROR_TOO_FEW_ARGUMENTS;

    ptr = besARGUMENT(1);
    besDEREFERENCE(ptr);
    arg0 = besCONVERT2ZCHAR(besCONVERT2STRING(ptr),arg0);

    strcat (sb_require,arg0); 

    retstr = (char*)gtk(sb_require);

    besALLOC_RETURN_STRING(strlen(retstr));
    memcpy(STRINGVALUE(besRETURNVALUE),retstr,strlen(retstr));

    besFREE(arg0);
besEND

besFUNCTION(_idll_define)
    VARIABLE ptr;
    char* arg0;
    char* retstr;
    char sb_define[256];

    strcpy (sb_define,"gtk_server_define ");

    if(besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
    if(besARGNR<1) return EX_ERROR_TOO_FEW_ARGUMENTS;

    ptr = besARGUMENT(1);
    besDEREFERENCE(ptr);
    arg0 = besCONVERT2ZCHAR(besCONVERT2STRING(ptr),arg0);

    strcat (sb_define,arg0);

    retstr = (char*)gtk(sb_define);

    besALLOC_RETURN_STRING(strlen(retstr));
    memcpy(STRINGVALUE(besRETURNVALUE),retstr,strlen(retstr));

    besFREE(arg0);
besEND

/* Needed to compile standalone Scriptbasic programs */
SLFST VISIO_SLFST[] = {

    {"versmodu", versmodu},
    {"bootmodu", bootmodu},
    {"finimodu", finimodu},
    {"_idll", _idll},
    {"varptr",varptr},
    {"_idll_require", _idll_require},
    {"_idll_define", _idll_define},
    {NULL, NULL}
};

#endif /* End of ScriptBasic code */

Offline John

  • Forum Support / SB Dev
  • Posts: 3562
    • ScriptBasic Open Source Project
Re: GTK-Server 64
« Reply #4 on: April 30, 2011, 03:17:37 AM »
This is a bare bones Gtk example in C.

Code: [Select]
#include <gtk/gtk.h>

static gboolean delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
{
    gtk_main_quit ();
    return FALSE;
}

int main (int argc, char *argv[])
{
    GtkWidget *window;
    
    gtk_init (&argc, &argv);
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    g_signal_connect (window, "delete-event", G_CALLBACK (delete_event), NULL);
    gtk_widget_show (window);
    gtk_main ();
    return 0;
}

compile with:  gcc gtkwin.c -o gtkwin `pkg-config --cflags --libs gtk+-2.0`

« Last Edit: April 30, 2011, 03:36:54 AM by ABB »

Offline John

  • Forum Support / SB Dev
  • Posts: 3562
    • ScriptBasic Open Source Project
Re: GTK-Server 64
« Reply #5 on: April 30, 2011, 12:34:41 PM »
This is a ScriptBasic GTK-Server HUG demo that comes with the distribution. (slightly modified/updated)

Code: [Select]
' *************************************
' Demo program using the GTK-Server HUG
' *************************************

IMPORT gtk.bas

CONST nl = "\n"

' Window prototype: window(title, xsize, ysize) -> returns windowID
win = GTK::window("Hello world!", 400, 250)

' Button prototype: button(label, xsize, ysize -> returns buttonID
exit_but = GTK::button("Exit", 100, 50)

' Foreground/background color prototype: fg_color(widget, r, g, b) -> no returnvalue
GTK::fg_color(exit_but, 0, 65535, 0)
GTK::bg_color(exit_but, 10240, 32768, 10240)

' Attach widget to parent prototype: attach(widget, parent, xpos, ypos) -> no returnvalue
GTK::attach(exit_but, win, 290, 190)

print_but = GTK::button("Print text", 100, 50)
GTK::attach(print_but, win, 10, 190)

' Frame prototype: frame(text, xsize, ysize) -> returns frameID
fr = GTK::frame(" Frame ", 120, 50)
GTK::attach(fr, win, 150, 190)
GTK::fg_color(fr, 65535, 0, 0)

' Separator widget prototype: separator(length) -> returns separatorID
sep = GTK::separator(400)
GTK::attach(sep, win, 0, 180)
GTK::bg_color(sep, 65535, 65535, 0)

' Entry/password prototype: entry(xsize, ysize)  - or -  password(xsize, ysize) -> returns entryID
entry = GTK::entry(205, 25)
GTK::attach(entry, win, 10, 10)
GTK::bg_color(entry, 65535, 65535, 0)

' Label prototype: label(text, xsize, ysize) -> returns labelID
lab = GTK::label("This is a demo", 110, 20)
GTK::attach(lab, win, 10, 50)
GTK::fg_color(lab, 49152, 0, 49152)

' Check button prototype: check(text, xsize, ysize) -> returns checkbuttonID
c_but = GTK::check("Option here", 110, 20)
GTK::attach(c_but, win, 10, 80)
GTK::fg_color(c_but, 0, 0, 65535)

' Set value of check/option button: select(button) -> no returnvalue
GTK::set_value(c_but)

' Radio button prototype: radio(text, xsize, ysize, group) -> returns radiobuttonID
' (First radiobutton should be attached to group "NULL")
r1_but = GTK::radio("Selection 1", 110, 20, "NULL")
GTK::attach(r1_but, win, 120, 50)
GTK::bg_color(r1_but, 65535, 0, 0)
r2_but = GTK::radio("Selection 2", 110, 20, r1_but)
GTK::attach(r2_but, win, 120, 70)
r3_but = GTK::radio("Selection 3", 110, 20, r1_but)
GTK::attach(r3_but, win, 120, 90)
GTK::disable(r3_but)

' Droplist prototype: droplist(array, xsize, ysize) -> returns droplistID
a[1] = "value one"
a[2] = "value two"
a[3] = "value three"
drop = GTK::droplist(a, 205, 30)
GTK::attach(drop, win, 10, 130)
b[1] = "peter"
b[2] = "van"
b[3] = "eerten surname"
GTK::set_text(drop, b)
GTK::set_value(drop, 2)
GTK::bg_color(drop, 0,0,65535)

list = GTK::list(b, 150, 150)
GTK::attach(list, win, 240, 10)
GTK::bg_color(list, 0,65535,0)
GTK::fg_color(list, 0,0,65535)
GTK::set_value(list, 0)

' Focus prototype: focus(widget) -> no returnvalue
GTK::focus(entry)

' Event Processing - gtk_main() / callback encapsulation
REPEAT
' Event prototype: event() -> returns widgetID on which event occured
action = GTK::event()
IF action = print_but THEN PRINT GTK::get_text(list), nl

' Selected prototype: get_value(widget) -> returns 0 or 1 depending on state
IF GTK::get_value(r2_but) THEN PRINT "Radio button 2!", nl

UNTIL action = exit_but OR action = win

END

« Last Edit: April 30, 2011, 02:38:52 PM by ABB »

Offline John

  • Forum Support / SB Dev
  • Posts: 3562
    • ScriptBasic Open Source Project
Re: GTK-Server 64
« Reply #6 on: April 30, 2011, 11:10:04 PM »
I have attached the compiled gtk-server.so which was extended for SB and the gtk.bas extension module interface that includes Peter's original version of his HUG (Highlevel Universal GUI) that was the basis for the BaCon version after Peter wrote his own Basic. (to C translator)

GTK.BAS - ScriptBasic Gtk / HUG source online.

I have attached both 64 and 32 bit versions of the GTK-Server extension module for ScriptBasic Linux. (Built on Ubuntu 10.10 32/64)

Put the shared object in /usr/local/lib/scriba and the gtk.bas file in  the /usr/share/scriba/include. Make sure your shared object has executable permissions.

The following code examples are what Peter wrote for ScriptBasic and Bacon for his HUG library. I hope to update the ScriptBasic version with improvements made in the BaCon version.

Code: Text
  1. FUNCTION window(title, xsize, ysize)
  2.  
  3. LOCAL win$, fix$
  4.  
  5. win$ = GUI("gtk_window_new 0")
  6. GUI("gtk_window_set_title", win$, "\"" & title & "\"")
  7. GUI("gtk_widget_set_size_request", win$, xsize, ysize)
  8. GUI("gtk_window_set_resizable", win$, 0)
  9. GUI("gtk_widget_set_name", win$, win$)
  10. GUI("gtk_widget_show", win$)
  11.  
  12. fix$ = GUI("gtk_fixed_new")
  13. GUI("gtk_container_add", win$, fix$)
  14. GUI("gtk_widget_show", fix$)
  15.  
  16. GTK_CONTAINER{win$} = fix$
  17. GTK_TYPE{win$} = "window"
  18.  
  19. window = win$
  20.  
  21. END FUNCTION
  22.  


Code: Text
  1. FUNCTION WINDOW (STRING title$, int xsize, int ysize)
  2.  
  3.     LOCAL win, layer, dim, i
  4.  
  5.     win = gtk_window_new(GTK_WINDOW_TOPLEVEL)
  6.     gtk_window_set_title(win, title$)
  7.     gtk_window_set_position(win, GTK_WIN_POS_CENTER)
  8.  
  9.     g_signal_connect_data(win, "delete-event", exit, 0, 0, 0)
  10.     g_signal_connect_data(win, "key-press-event", hug_key_press, 0, 0, 0)
  11.  
  12.     IF INSTR(hug_gui_properties.options$, "TABLE") THEN
  13.         SPLIT hug_gui_properties.options$ BY " " TO opt$ SIZE dim
  14.         FOR i = 0 TO dim - 1
  15.             IF INSTR(opt$[i], "TABLE") AND i+2 < dim THEN
  16.                 layer = gtk_table_new(VAL(opt$[i+2]), VAL(opt$[i+1]), 1)
  17.                 BREAK
  18.             END IF
  19.         NEXT
  20.     ELSE
  21.         gtk_window_set_resizable(win, 0)
  22.         layer = gtk_fixed_new()
  23.     END IF
  24.  
  25.     gtk_container_add(win, layer)
  26.  
  27.     gtk_widget_set_size_request(win, INT(xsize*HUG_FONT_SIZE_FACTOR*HUG_XFT_SIZE_FACTOR), INT(ysize*HUG_FONT_SIZE_FACTOR*HUG_XFT_SIZE_FACTOR))
  28.     IF HUG_WIDGET_SHOW THEN gtk_widget_show_all(win)
  29.  
  30.     hug_winstate(STR$(win)) = 0
  31.  
  32.     WITH hug_widget_properties[hug_pointer]
  33.         .widget = win
  34.         .font = win
  35.         .focus = win
  36.         .attach = layer
  37.         .signal = 1
  38.         .s_widget = win
  39.         .xsize = xsize
  40.         .ysize = ysize
  41.         .grab = WINDOW_GRAB$
  42.         .text = WINDOW_TEXT
  43.         .get = WINDOW_GET
  44.         .set = WINDOW_SET
  45.     END WITH
  46.  
  47.     hug_pointer = hug_pointer + 1
  48.  
  49.     RETURN win
  50.  
  51. END FUNCTION
  52.  
« Last Edit: May 01, 2011, 01:33:04 AM by ABB »

Offline John

  • Forum Support / SB Dev
  • Posts: 3562
    • ScriptBasic Open Source Project
Re: GTK-Server 64
« Reply #7 on: May 04, 2011, 12:34:59 AM »
Here is an example of ScriptBasic being embedded within itself. A BCX(MBC3) shared object was created as in interface to to the ScriptBasic API.

iDLL.bas (libiDLL.so 9KB)
Code: [Select]
$dll
$execon "-static -I /home/jrs/sb/scriptbasic /home/jrs/sb/scriptbasic/lmt_none.c -lscriba"
 
#include <scriba.h>
#include <getopt.h>

Global pProgram as pSbProgram

function sb_new() as pSbProgram export
  function = scriba_new(malloc,free)
end function

Code: [Select]
DECLARE SUB DLL ALIAS "_idll" LIB "gtk-server"
DECLARE SUB REQUIRE ALIAS "_idll_require" LIB "gtk-server"
DECLARE SUB DEFINE ALIAS "_idll_define" LIB "gtk-server"

REQUIRE "libiDLL.so"

DEFINE "sb_new NONE POINTER 0"
DEFINE "scriba_LoadConfiguration NONE INT 2 POINTER STRING"
DEFINE "scriba_SetFileName NONE INT 2 POINTER STRING"
DEFINE "scriba_Run NONE INT 2 POINTER STRING"
DEFINE "scriba_LoadSourceProgram NONE INT 1 POINTER"
DEFINE "scriba_destroy NONE NONE 1 POINTER"

pProgram = DLL("sb_new")
DLL("scriba_LoadConfiguration " & pProgram & " \"/etc/scriba/basic.conf\"")
DLL("scriba_SetFileName " & pProgram & " \"E01.sb\"")
DLL("scriba_LoadSourceProgram " & pProgram)
DLL("scriba_Run " & pProgram & " \"JRS\"")
DLL("scriba_destroy " & pProgram)

E01.sb
Code: [Select]
cmd = COMMAND()

PRINT "ARG = ",cmd,"\n"

FOR x = 1 TO 10
  PRINT x,"\n"
NEXT

jrs@Laptop:~/SB/test$ scriba embed.sb
ARG = JRS
1
2
3
4
5
6
7
8
9
10
jrs@Laptop:~/SB/test$

I have tested this under Ubuntu 10.10 32 bit and Ubuntu 11.04 64 bit.

I plan to expand on this embedding demo to show some of the other API calls you can use in your own compiled applications if runtime scripting ever becomes a need.  

  • Call an embedded library of SB functions from the main application
  • Get and set embedded script variables from the main application
  • Attempt to start a script as a thread and use the MT extension module to share variables among threads and the main process.
  • Anything else I run into I think you might find interesting
« Last Edit: May 04, 2011, 12:44:24 AM by ABB »