[fpc-pascal] Linux : Using SDL with GTK2 ?

Darius Blaszyk dhkblaszyk at zeelandnet.nl
Wed Dec 2 01:00:18 CET 2009


Hi Andrew,

I found this mail from you regarding attaching SDL to the used
widgetset. But whatever I do I cannot get it to work. The example you
attached in the email below works fine, so it has to be possible. So why
not when using the LCL?

I hope you don;t mind me bugging you about this, but I've been staring
at the code for two days now, and you're my last resort...

The code I've been using is pasted below. If you don't feel like fixing
my mess (or simply don't have the time to) just let me know and I'll
understand.

function GetX11Window(AWidget: PGtkWidget): X.TWindow;
begin
  // first make sure the x11 window is created for the gtk widget
  if GTK_WIDGET_REALIZED(AWidget) = False then
    gtk_widget_realize(AWidget);

  // now retrieve the X window
{$IFDEF GTK2}
  Result := GDK_WINDOW_XWINDOW(PGdkDrawAble(AWidget^.window));
{$ENDIF}
{$IFDEF GTK1}
  Result := GDK_WINDOW_XWINDOW(PGdkWindowPrivate(AWidget^.window));
{$ENDIF}
end;

procedure SetSDLWidget(AWidget: PGtkWidget);
var
  X11Window:    QWord;
  SDL_WINDOWID: string;
begin
  X11Window    := GetX11Window(AWidget);
  SDL_WINDOWID := 'SDL_WINDOWID=' + IntToStr(PtrUint(X11Window));
  _putenv(PChar(SDL_WINDOWID));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  SetSDLWidget(PGtkWidget(Panel));
end;

In a Button1Click handler SDL is initialized like so;

  if SDL_Init(SDL_INIT_VIDEO or SDL_INIT_AUDIO or SDL_INIT_TIMER) <> 0
then
    raise Exception.CreateFmt('Could not initialize SDL - %s',
[SDL_GetError]);

Regards, Darius

On Fri, 2007-11-16 at 14:42 -0500, Andrew Haines wrote:
> T.Guilleminot wrote:
> > 1. I'm unsure of chronology of things to do in the program body. Is the
> > following correct :
> >    a) Create GTK stuff
> >    b) SDL Hack/SDL_WINDOWID
> >    c) SDL_INIT
> >    d) Show GTK widgets
> > 
> 
> Yes that's right. With the only exception being that you have to use
> gtk_widget_realize on whatever gtk widget you are using for sdl so that
> the x11 window will be allocated.
> 
> > 2. You mentioned "this is for gtk1 only. gtk2 is similar but different".
> > What to do for GTK2 ?
> > 
> 
> I've attached a simple program that will compile for gtk1 or gtk2. you
> can change a define at the top of the source to switch between gtk 1 or 2.
> 
> > 3. Which kind of GTK Object "APanel" can be ?
> > 
> > 4. FPC complains on "handle". What's wrong ?
> > 
> 
> Sorry I thought you were using the LCL and so my example was for that. I
> attached an example program that doesn't use the LCL.
> 
> > Thanks Again.
> > Tom
> > 
> > 
> 
> It's worth noting that you cannot have more than one sdl window per
> application. It's a limitation of sdl.
> 
> Andrew
> plain text document attachment (project1.lpr)
> program Project1;
> 
> {$mode objfpc}{$H+}
> 
> {$DEFINE GTK1}
> 
> uses
>   Classes, SysUtils,
>   {$IFDEF GTK2} Gtk2, Gdk2, Gdk2x, Glib2, {$ENDIF}
>   {$IFDEF GTK1} Gtk, Gdk, Glib,{$ENDIF}
>   X, sdl, sdlutils;
>   
> var
>   MainWindow,
>   Drawable: PGtkWidget;
>   SDLSurface: PSDL_Surface = nil;
> 
> 
> 
> procedure InitGtk;
> begin
>   gtk_init(@argc, @argv);
>   
>   MainWindow := gtk_window_new(GTK_WINDOW_TOPLEVEL);
>   gtk_window_set_title(PGtkWindow(MainWindow), 'Hey there''s SDL in this window!');
> 
>   Drawable := gtk_drawing_area_new;
> 
>   gtk_widget_set_app_paintable(Drawable, False);
>   {$IFDEF GTK2}
>   gtk_widget_set_double_buffered(Drawable, False);
>   {$ENDIF}
> 
>   gtk_container_add(PGtkContainer(MainWindow), Drawable);
>   {$IFDEF GTK1}
>   gtk_widget_show(MainWindow);
>   {$ENDIF}
> end;
> 
> procedure ResizeSDL(AWidget: PGtkWidget; Allocation: PGtkAllocation; userdata: pointer); cdecl;
> begin
>   SDLSurface := SDL_SetVideoMode(Allocation^.width, Allocation^.height, 0, SDL_HWSURFACE);
> end;
> 
> procedure ExposeSDL(widget: PGtkWidget; event: PGdkEventExpose; Data: Pointer); cdecl;
> var
>   Col1, Col2: TSDL_Color;
>   ARect: TSDL_Rect;
> 
> begin
>   Col1.r := 255;
>   Col1.b := 0;
>   Col1.g := 0;
> 
>   Col2.r := 0;
>   Col2.b := 255;
>   Col2.g := 0;
> 
>   ARect := SDLRect(0,0,Drawable^.allocation.width, Drawable^.allocation.height);
> 
>   SDL_FillRect(SDLSurface, @ARect, $FFFF0000);
>   SDL_Flip(SDLSurface);
> end;
> 
> procedure SetGtkCallbacks;
> begin
>   gtk_signal_connect(GTK_OBJECT(Drawable), 'expose-event', TGtkSignalFunc(@ExposeSDL), nil);
>   gtk_signal_connect(GTK_OBJECT(Drawable), 'size-allocate', TGtkSignalFunc(@ResizeSDL), nil);
> 
>   gtk_signal_connect(GTK_OBJECT(MainWindow), 'destroy', TGtkSignalFunc(@gtk_main_quit), nil)
> end;
> 
> function GetX11Window(AWidget: PGtkWidget): X.TWindow;
> begin
>   // first make sure the x11 window is created for the gtk widget
>   if GTK_WIDGET_REALIZED(AWidget) = False then
>     gtk_widget_realize(AWidget);
> 
> 
>   // now retrieve the X window
>   {$IFDEF GTK2}
>   Result := GDK_WINDOW_XWINDOW(PGdkDrawAble(AWidget^.window));
>   {$ENDIF}
>   {$IFDEF GTK1}
>   Result := GDK_WINDOW_XWINDOW(PGdkWindowPrivate(AWidget^.window));
>   {$ENDIF}
> 
> end;
> 
> procedure SetSDLWidget(AWidget: PGtkWidget);
> var
>   X11Window: QWord;
>   SDL_WINDOWID: String;
> begin
>  X11Window := GetX11Window(AWidget);
>  SDL_WINDOWID := 'SDL_WINDOWID='+IntToStr(PtrUint(X11Window));
>  _putenv(PChar(SDL_WINDOWID));
> end;
> 
> procedure SyncGtk;
> begin
>   gtk_main_iteration_do(True);
> end;
> 
> procedure InitSDL;
> begin
>   SDL_Init(SDL_INIT_VIDEO or SDL_INIT_JOYSTICK);
>   SDLSurface := SDL_SetVideoMode(Drawable^.allocation.width, Drawable^.allocation.height, 0, SDL_HWSURFACE);
> end;
> 
> procedure Run;
> begin
>   gtk_widget_show_all(MainWindow);
>   gtk_main;
> end;
> 
> begin
>   InitGtk;
>   SetGtkCallbacks;
>   SetSDLWidget(Drawable);
>   SyncGtk;
>   InitSDL;
>   Run;
> end.
> 
> _______________________________________________
> fpc-pascal maillist  -  fpc-pascal at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
> No virus found in this incoming message. Checked by AVG Free Edition. Version: 7.5.503 / Virus Database: 269.16.0/1136 - Release Date: 11/17/2007 2:55 PM




More information about the fpc-pascal mailing list