Concerning SDL2 as a GTK2 form control in Pascal/Lazarus

I hop between Windows 10 and Linux Mint constantly. The basic Lazarus components work fine without much changes need, if any at all. However, I wanted to use SDL2 as a form component because CPU rendering was too slow for my needs. I had for the first time to actually use compile time conditionals for these GTK2 specific problems to get SDL2 running without any issues on Linux Mint.

SDL2 for Pascal

Before continuing, I have to mention that I’m using the SDL2-for-Pascal units that can be found on GitHub. There you can find more details about how to install and use the Pascal units. For more information about SDL2 and how to use it in Pascal, visit FreePascal-meets-SDL.net.

Facing some problems

I’m using the bare minimum of SDL2 just to draw a single texture to screen. SDL2 works auto-magically on Windows, but I needed to do some actual work on Linux to make it work properly.

Some relevant code

Starting with the uses block, these are the most relevant units for making SDL2 work as a form control.

uses
  {$IFDEF LCLGTK2}
  gtk2, gdk2x,
  {$ENDIF}
  OpenGLContext, SDL2;

Getting the pointer for the control handle is a bit more complicated in Mint than it is on Windows when it comes to SDL2 window creation (I found this snippet online but can’t recall where).

{$IFDEF LCLGTK2}
// Linux with GTK2 widget-set
sdlWindow := SDL_CreateWindowFrom(Pointer(GDK_WINDOW_XWINDOW(PGtkWidget(PtrUInt(OpenGLControl.Handle))^.window)));
{$ELSE}
// My targets are Windows and Linux (GTK2) so a simple ELSE works
sdlWindow := SDL_CreateWindowFrom(Pointer(OpenGLControl.Handle));
{$ENDIF}

Naturally, SDL_SetWindowSize() needs to be called preferably in the OnPaint event (keeping in mind that OnPaint nor Invalidate() seem to not be working with TOpenGLControl on Linux so assign/use them on the TOpenGLControl’s parent instead).

{$IFDEF LCLGTK2}
SDL_GetWindowSize(sdlWindow, @currentWidth, @currentHeight);
if (currentWidth <> actualWidth) or (currentHeight <> actualHeight) then
  SDL_SetWindowSize(sdlWindow, actualWidth, actualHeight);
{$ENDIF}
Tags: lazarus pascal sdl2