Hello,
I am a really gambit newbie and I was toying with the idea of creating a GUI application with gambit.
Is there some GUI library? By that I mean a widget collection library like GTK+ or QT.
As I didn't find one I think it is probably a good idea to use C to drive the GUI part and gambit for the rest.
What would be the right way to do it?
Also, I would like to use GTK+, as I'm experienced with it, but it has some requirements, like having control of the main thread and never returning. Would this be a problem?
Afficher les réponses par date
2011/3/31 Diogo F. S. Ramos diogofsr@gmail.com
Hello,
I am a really gambit newbie and I was toying with the idea of creating a GUI application with gambit.
Is there some GUI library? By that I mean a widget collection library like GTK+ or QT.
You can check Jazz Scheme, it's based on Gambit, multiplatform, and has a GUI library.
As regards GTK or QT, you plug them in via the FFI. You can both make calls to C and get callbacks from C using it. Check in the Dumping grounds on the wiki if there's any FFI integration for them, alternatively take inspiration from one that already exists for another Scheme implementation while implementing your own for Gambit.
As I didn't find one
(Above)
I think it is probably a good idea to use C to
drive the GUI part and gambit for the rest.
If by GUI part you mean an UI library such as GTK, sure.
What would be the right way to do it?
Also, I would like to use GTK+, as I'm experienced with it, but it has some requirements, like having control of the main thread and never returning. Would this be a problem?
If your app doesn't need to do anything in the background while GTK is having the control, then no. Otherwise, also no, but you'd need to make an own OS thread or process for GTK's thread.
Kind regards, Mikael
--
Diogo F. S. Ramos _______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
2011/3/31 Diogo F. S. Ramos diogofsr@gmail.com
Hello, I am a really gambit newbie and I was toying with the idea of creating a GUI application with gambit. Is there some GUI library? By that I mean a widget collection library like GTK+ or QT.
You can check Jazz Scheme, it's based on Gambit, multiplatform, and has a GUI library.
As regards GTK or QT, you plug them in via the FFI. You can both make calls to C and get callbacks from C using it. Check in the Dumping grounds on the wiki if there's any FFI integration for them, alternatively take inspiration from one that already exists for another Scheme implementation while implementing your own for Gambit.
Nice.
I took you suggestion and went to Dumping Grounds. There I found a cairo binding that inspired me. :)
AFAICS it generates bindings from the C functions directly to gambit and creates a loadable object. It is really nice and it is very different from what I was trying to do.
What I had in mind was using a main C program for the GUI and to use gambit like an extension. Just like the server/client example, actually. Although I must say that I didn't went too far as I keep getting a 'undefined reference to `____20_server__'' linker error. And I didn't quite find a place where it's describe what functions have to be called to initiate the gambit library.
I also tried to create a shared library and link it against an ordinary C program but I kept getting seg faults. I guess I need to initiate the gambit library from the C program.
But nevertheless, the way cairo's binding does it seems really cool. Thank you.
Hallo,
On Thu, Mar 31, 2011 at 12:06 PM, Diogo F. S. Ramos diogofsr@gmail.com wrote:
AFAICS it generates bindings from the C functions directly to gambit and creates a loadable object. It is really nice and it is very different from what I was trying to do.
What I had in mind was using a main C program for the GUI and to use gambit like an extension. Just like the server/client example, actually. Although I must say that I didn't went too far as I keep getting a 'undefined reference to `____20_server__'' linker error. And I didn't quite find a place where it's describe what functions have to be called to initiate the gambit library.
You can approach the problem either by embedding or extending Gambit-C. The embedding case will give you a program in less time because you won't need to write bindings to GTK+. On the other hand, once the bindings are written, you can reuse them in several different projects.
I also tried to create a shared library and link it against an ordinary C program but I kept getting seg faults. I guess I need to initiate the gambit library from the C program.
When embedding Gambit-C you have to initialise it before calling any Scheme functions with ___setup().
Can someone point me to some info on this? Also does Gambit have a method for accessing databases?
Thanks, Steve
On 2011-03-31, at 5:16 PM, Steve Graham wrote:
Can someone point me to some info on this?
I'm not sure what level of detail you want. One approach is to use the FFI to create an interface to the Win32 functions. Below is a small example which gives the rough idea. I have tested it on Gambit-C v4.6.1 using MinGW.
Marc
;; File: "windows-gui-example.scm"
;; On Windows, compile and run with: ;; ;; $ gsc -exe windows-gui-example.scm ;; $ ./windows-gui-example.exe
;;-----------------------------------------------------------------------------
;; Win32 types, constants and functions.
(c-define-type HWND "HWND") (c-define-type WPARAM "WPARAM") (c-define-type LPARAM "LPARAM")
(define-macro (import-int-constants . names) `(begin ,@(map (lambda (name) `(define ,name ((c-lambda () int ,(string-append "___result = " (symbol->string name) ";"))))) names)))
(import-int-constants WM_DESTROY WM_CLOSE )
(define DefWindowProc (c-lambda (HWND unsigned-int WPARAM LPARAM) long "DefWindowProc"))
(define DestroyWindow (c-lambda (HWND) bool "DestroyWindow"))
(define PostQuitMessage (c-lambda (int) void "PostQuitMessage"))
;;-----------------------------------------------------------------------------
;; Utility functions to create windows and run the message loop.
(c-declare #<<end-of-c-declare
#include <windows.h>
/* The window procedure which handles events is defined in Scheme */
long CALLBACK window_procedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
HWND create_window(char *window_class, char *title, int width, int height) { WNDCLASSEX wc; HWND hwnd;
/* Get the program startup information which was passed to WinMain */
HINSTANCE hInstance; HINSTANCE hPrevInstance; LPSTR lpCmdLine; int nCmdShow;
___program_startup_info_struct *psi = ___EXT(___get_program_startup_info)();
hInstance = psi->hInstance; hPrevInstance = psi->hPrevInstance; lpCmdLine = psi->lpCmdLine; nCmdShow = psi->nCmdShow;
/* Register the Window Class */
wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = window_procedure; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = window_class; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc)) return NULL;
/* Create the window */
hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, window_class, title, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, hInstance, NULL);
if (hwnd == NULL) return NULL;
/* Show the window */
ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd);
return hwnd; }
int message_loop() { MSG Msg;
while (GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); }
return Msg.wParam; }
end-of-c-declare )
(define create-window (c-lambda (char-string char-string int int) HWND "create_window"))
(define message-loop (c-lambda () int "message_loop"))
(c-define (window-procedure hwnd msg wparam lparam) (HWND unsigned-int WPARAM LPARAM) long "window_procedure" "CALLBACK"
;; (pp msg)
(cond ((= msg WM_CLOSE) (DestroyWindow hwnd) 0) ((= msg WM_DESTROY) (PostQuitMessage 0) 0) (else (DefWindowProc hwnd msg wparam lparam))))
;;-----------------------------------------------------------------------------
;; Main program. Open a window which can be moved, resized and closed.
(define hwnd (create-window "mywindowclass" "My Window" 500 200))
(message-loop) ;; run the message loop, which calls "window-procedure"
;;-----------------------------------------------------------------------------
On 2011-03-30, at 8:48 PM, Diogo F. S. Ramos wrote:
Hello,
I am a really gambit newbie and I was toying with the idea of creating a GUI application with gambit.
Is there some GUI library? By that I mean a widget collection library like GTK+ or QT.
One approach which is portable is to use Tcl/Tk. Check out the examples/tcltk directory. It contains several examples (translations of the examples in the Tcl/Tk book).
As I didn't find one I think it is probably a good idea to use C to drive the GUI part and gambit for the rest.
It depends on the GUI library. In many GUIs there is a main event loop that is part of the GUI API. This can be a problem because that event loop takes over control of the execution, and prevents the Gambit thread scheduler, and timeouts to operate properly. Single-thread programs should be OK.
The "main" program can either be in C or in Scheme (but if in C don't forget to initialize your compiled Scheme code by calling ___setup()). The event handlers and the rest of your GUI logic can be in Scheme. The Scheme code will call the GUI's C API exposed through Gambit's FFI (creating windows, getting the details of an event, etc).
What would be the right way to do it?
Also, I would like to use GTK+, as I'm experienced with it, but it has some requirements, like having control of the main thread and never returning. Would this be a problem?
It is only a problem if you want to use multiple Scheme threads. But a workaround is to hook into "idle" events so that the Scheme event handler calls (thread-yield!), thus allowing the Gambit thread scheduler to give time to the other Scheme threads. This is more or less how the iPhone "Gambit REPL" was implemented (see examples/iOS).
Marc
Hallo,
On Fri, Apr 1, 2011 at 11:13 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
As I didn't find one I think it is probably a good idea to use C to drive the GUI part and gambit for the rest.
It depends on the GUI library. In many GUIs there is a main event loop that is part of the GUI API. This can be a problem because that event loop takes over control of the execution, and prevents the Gambit thread scheduler, and timeouts to operate properly. Single-thread programs should be OK.
GTK+ at least lets you take control of the main loop. But the programmer must call a function to let GTK+ process events, so it must be called often:
http://library.gnome.org/devel/gtk3/stable/gtk3-General.html#gtk-main-iterat...
On 2011-04-01, at 10:20 AM, Alex Queiroz wrote:
Hallo,
On Fri, Apr 1, 2011 at 11:13 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
As I didn't find one I think it is probably a good idea to use C to drive the GUI part and gambit for the rest.
It depends on the GUI library. In many GUIs there is a main event loop that is part of the GUI API. This can be a problem because that event loop takes over control of the execution, and prevents the Gambit thread scheduler, and timeouts to operate properly. Single-thread programs should be OK.
GTK+ at least lets you take control of the main loop. But the
programmer must call a function to let GTK+ process events, so it must be called often:
http://library.gnome.org/devel/gtk3/stable/gtk3-General.html#gtk-main-iterat...
Yes. The other nice thing about GTK on X11 is that you can avoid busy waiting for events by calling (##device-port-wait-for-input! x11-display-port) where display-port is obtained with ##open-predefined using the X11 connection file descriptor. This is what's done in the Gambit Xlib-simple example (see the file examples/Xlib-simple/bounce.scm).
Marc