Atacama has asked for the wisdom of the Perl Monks concerning the following question:

Hi.

I'm trying to get SDL and Cairo working together using the code below.

I expect Cairo to draw a red square inside the SDL window.

The program segfaults instead.

This page cairographics.org/SDL says that libraries should work fine together if they "agree on the pixel format"

I tried to change pixel format to 24/rgb24 and other permutations of available formats without success.

Am I missing something?

Thank you for your time.

use strict; use warnings; use SDL v2.3; use SDL::Video; use SDL::Event; use SDL::Events; use SDL::Surface; use Cairo; my $WIDTH = 400; my $HEIGHT = 300; # relevant part starts: my $screen = SDL::Video::set_video_mode($WIDTH, $HEIGHT, 32, SDL_SWSUR +FACE); SDL::Video::lock_surface($screen); my $surface = Cairo::ImageSurface->create_for_data ( $screen->get_pixels_ptr, 'argb32', $screen->w, $screen->h, $screen->pitch ); my $cairo = Cairo::Context->create($surface); $cairo->rectangle(0, 0, 100, 100); $cairo->set_source_rgb(255, 0, 0); $cairo->fill; SDL::Video::unlock_surface($screen); SDL::Video::update_rect($screen, 0, 0, $WIDTH, $HEIGHT); # relevant part ends LOOP: while (1) { my $event = SDL::Event->new(); while (SDL::Events::poll_event($event)) { last LOOP if $event->type == SDL_KEYDOWN || $event->type == SDL_QUIT; } SDL::Events::pump_events(); } SDL::quit;

Replies are listed 'Best First'.
Re: SDL and Cairo segfault
by Khen1950fx (Canon) on Jan 08, 2011 at 07:17 UTC
    Why use Cairo? SDL::Video can produce a beautiful red rectangle all by itself.

    The segmentation fault was happening because the video mode wasn't being set right, and you were missing SDL::Rect. Here's a script that works for me:

    #!/usr/bin/perl use strict; no warnings; use SDL; use SDL::Video; use SDL::Surface; use SDL::Rect; use constant WIDTH => 400; use constant HEIGHT => 300; SDL::init( SDL_INIT_VIDEO ); my $screen = SDL::Video::set_video_mode( WIDTH, HEIGHT, 32, SDL_SWSURFACE ); my $mcolor = SDL::Video::map_RGB($screen->format(), 255, 0, 0); SDL::Video::fill_rect($screen, SDL::Rect->new( WIDTH / 4, HEIGHT / 4, WIDTH / 2, HEIGHT / 2), $mcolor); SDL::Video::update_rect( $screen, 0, 0, WIDTH, HEIGHT ); sleep 10; SDL::quit();
    If that works, then you can add whatever you need to add. If you run into problems, post another question. Good luck.

      Thank you for reply.

      The main reasons for cairo were to draw more interesting stuff than a red rectangle (which was used to make example code short) and to do it fast enough for a simple game.

      Your code worked perfectly, but would you like to explain what is the reason for "no warnings", please? Everybody seems to be advocating for "use warnings".

      I suddenly discovered SDL::GFX::Primitives namespace which looks suitable

      Just in case, here are two pieces of code: Perl version segfaults and C one works. Either they are not equivalent or perl-cairo and perl-sdl are not compatible

        I used "no warnings" after I finished the script. Always "use warnings" is always the right thing, but, with SDL, it likes to keep sending out little messsages that aren't useful. That's why I used "no warnings".

        I adjusted your script a little. It produces a red rectangle png. Give it a test drive.

        #!/usr/bin/perl use strict; use Cairo; use SDL; use SDL::Video; use SDL::Surface; use SDL::Rect; use constant WIDTH => 400; use constant HEIGHT => 300; SDL::init(SDL_INIT_VIDEO); my $screen = SDL::Video::set_video_mode(WIDTH, HEIGHT, 32, SDL_SWSURFACE); my $surface = Cairo::ImageSurface->create( 'rgb24', WIDTH, HEIGHT); my $cr = Cairo::Context->create($surface); $0 =~ /(.*)\.pl/; my $out = "$1.png"; $cr->rectangle (0, 0, WIDTH, HEIGHT); $cr->set_source_rgb (255, 0, 0); $cr->fill; $cr->show_page; $surface->write_to_png ($out); SDL::quit();