Pascal on the Raspberry Pi first created 01/07/16 - last modified 24/07/16 Page Author: Ty Harness
Using Free Pascal on the Raspberry Pi(running Raspbian) I've created a fractal voyager program. The program is written in plain old Pascal and an X11 window to visualise the fractals.

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install fpc
sudo apt-get install lazarus


Although you can use a text editor to write your source and use fpc to compile and link the program it's far easier to install the Lazarus-ide. Here's some general notes: wiki.freepascal.org/Lazarus_on_Raspberry_Pi



./x11_demo_fp_raspberry_pi_ver_11



C = 0.3+ 0i elephant valley
./x11_demo_fp_raspberry_pi_ver_11 0.3 0.0 0.05 512

C = -0.75+0.1i sea horse valley
./x11_demo_fp_raspberry_pi_ver_11 -0.75 0.1 0.01 512

To grab images I've used the xwd (X window dump) command. To use the feature you'll need to install the X11 utilites:

sudo apt-get install x11-utils

To view the images you can use the xwud command or The Gimp now opens xwd files.
If you then want to make an animated gif with all the saved frames them imagemagick convert application. http://www.imagemagick.org/

Press s to grab screen shots using x11 utils and use imagemagik to convert to an animated gif.
Download the source code tarball below and extract the 4 pas files. You need all 4 files in the same directory.
tar zxvf fractal_voyage-11.tar.gz

fractal_voyage-11.tar.gz

Start the lazarus-ide and open x11_demo_fp_raspberry_pi_ver_11.pas (make a simple program if asked.) Either run in the program in the ide or press Build. Once built you can execute from the command line:
./x11_demo_fp_raspberry_pi_ver_11
program x11_demo_fp_raspberry_pi_ver_11;

{$mode objfpc}{$H+}

(*
Version 1.1
This is a example to help pascal programmers on the raspberry pi get started with Xlib
Please improve this example as you see fit - Ty Harness.


The easiest way to compile the code is to install fpc and lazarus-ide on the Raspberry pi
and use the Lazarus-ide to compile,link and build the program.  You know all the units for xlib
are installed correctly. You'll be pleasently surprised how quick it is.  The source will compile
for other X11 linux distros, but wont cross compile for the windows gdi.

Source files needed to compile:
x11_demo_fp_raspberry_pi_ver_1.pas
unitmandelbrot.pas
unitnewton.pas
commonDataTypes.pas

to compile via the command line:
fpc x11_demo_fp_raspberry_pi_ver_1.pas
and execute with
./x11_demo_fp_raspberry_pi_ver_1 <parameters>

<parameters can be left blank or use specify a complex number and region of interest
Re img Re+/-ROI Max. Iterations e.g.>


C = -0.75+0.1i sea horse valley
./x11_demo_fp_raspberry_pi_ver_11 -0.75 0.1 0.01 512

C = 0.3+0i elephant valley
./x11_demo_fp_raspberry_pi_ver_11 0.3 0.0 0.05 512


if you want to use xwd on the raspberry pi you'll need the x11-utils

sudo apt-get install x11-utils

xwd -out frame0000.xwd
xwud -in frame0000.xwd

Using imagemagik to make an animated gif out of the frames saved.
convert -delay 100 frame*xwd fractalvoyage.gif


references:

http://wiki.freepascal.org/Lazarus_on_Raspberry_Pi

http://www.freepascal.org/
http://www.lazarus-ide.org/


http://wiki.lazarus.freepascal.org/X11
http://www-h.eng.cam.ac.uk/help/tpl/graphics/X/X11R5/node3.html#SECTION00030000000000000000
http://math.msu.su/~vvb/2course/Borisenko/CppProjects/GWindow/xintro.html
https://tronche.com/gui/x/xlib/
http://www.imagemagick.org/script/convert.php
*)



uses
  xlib, x, ctypes, unitmandelbrot, unitnewton, commonDataTypes,unix,sysutils;


const
  Height = 480;
  Width = 600;





procedure zoomer(factor:double);
var
 d : double;
begin

d :=  (URZ.Re - LLZ.Re)*factor*0.01;

LLZ.Re := LLZ.Re - d;
LLZ.i  := LLZ.i - d*aspect;

URZ.Re := URZ.Re + d;
URZ.i  := URZ.i + d*aspect;

end;


procedure pan(panRe,pani:double);
var
  x,y : double;
begin

 x :=   (URZ.Re - LLZ.Re)*panRe*0.01;
 y :=   (URZ.i - LLZ.i)*pani*0.01;

 LLZ.Re := LLZ.Re + x;
 URZ.Re := URZ.Re + x;

 LLZ.i  := LLZ.i  + y;
 URZ.i  := URZ.i  + y;

end;


procedure InitGCarray(d: PDisplay; w: TWindow;s: cint);
begin
  //set up a colour pallette for Xwindow -gotter be a better way than this

XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:00/00/00', @color, @dummy);
xgv10.foreground := color.pixel;
xgc10[0] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:ff/00/00', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[1] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:ff/80/00', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[2] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:ff/ff/00', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[3] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:80/ff/00', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[4] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:00/ff/80', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[5] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:00/ff/ff', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[6] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:00/80/ff', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[7] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:00/00/ff', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[8] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:80/00/ff', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[9] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:ff/00/ff', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[10] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:ff/00/80', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[11] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:ff/00/80', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[12] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:ff/ff/ff', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[13] := XCreateGC(d,w,GCForeground, @xgv10); //white

XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:10/10/10', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[14] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:40/40/40', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[15] := XCreateGC(d,w,GCForeground, @xgv10);
XAllocNamedColor(d,  DefaultColormap(d, s),'rgb:90/90/90', @color, @dummy); xgv10.foreground := color.pixel;
xgc10[16] := XCreateGC(d,w,GCForeground, @xgv10);



end;



procedure OpenX11Window(Amsg: string;choice: integer);
var
  d: PDisplay;
  w: TWindow;
  e: TXEvent;
  msg: PChar;
  s: cint;
  Xattributes : TXSetWindowAttributes;


  skeysym     : TKeysym ; skeycode           : TkeyCode;
  mkeysym     : TKeysym ; mkeycode           : TkeyCode;
  nkeysym     : TKeysym ; nkeycode           : TkeyCode;
  Upkeysym    : TKeysym ; upkeycode          : TkeyCode;
  Downkeysym  : TKeysym ; downkeycode        : TkeyCode;
  Leftkeysym  : TKeysym ; leftkeycode        : TkeyCode;
  Rightkeysym : TKeysym ; rightkeycode      : TkeyCode;
  pluskeysym  : TKeysym ; pluskeycode        : TkeyCode;
  minuskeysym : TKeysym ; minuskeycode       : TkeyCode;
  ikeysym     : TKeysym ; ikeycode           : TkeyCode;
  keycode     : TKeyCode;

  draw_once   : boolean;

  frame : integer;

begin
  msg := PChar(Amsg);
  draw_once := true;

  frame := 0;



  //xserver connection
  d := XOpenDisplay(nil);
  if (d = nil) then
  begin
    WriteLn('Cannot open display');
    exit;
  end;

   s := DefaultScreen(d);


   Xattributes.background_pixel := WhitePixel(d, s);

   w := XCreateWindow(d, RootWindow(d, s),  0, 0, Width, Height, 0, DefaultDepth(d,s),
   InputOutput, DefaultVisual(d,s), CWBackPixel, @Xattributes);



   InitGCarray(d,w,s);

     Xstorename(d,w,msg); //caption
  // Xstorename(d,w,Displaystring(d)); //caption

  { select kind of events we are interested in }
  XSelectInput(d, w, ExposureMask or KeyPressMask or KeyReleaseMask);


  { map (show) the window }
  XMapWindow(d, w);
  Xflush(d);


  {set up keys}
  sKeySym  := XStringToKeysym ('s');
  sKeycode  := XKeysymToKeycode (d, sKeySym);

  mKeySym  := XStringToKeysym ('m');
  mKeycode  := XKeysymToKeycode (d, mKeySym);

  nKeySym  := XStringToKeysym ('n');
  nKeycode  := XKeysymToKeycode (d, nKeySym);

  iKeySym       := XStringToKeysym ('i');
  iKeycode      := XKeysymToKeycode (d, iKeySym);

  upKeySym      := XStringToKeysym ('Up');
  upKeycode     := XKeysymToKeycode (d, upKeySym);

  rightKeySym   := XStringToKeysym ('Right');
  rightKeycode  := XKeysymToKeycode (d, rightKeySym);

  leftKeySym    := XStringToKeysym ('Left');
  leftKeycode   := XKeysymToKeycode (d, leftKeySym);

  downKeySym    := XStringToKeysym ('Down');
  downKeycode   := XKeysymToKeycode (d, downKeySym);

  plusKeySym    := XStringToKeysym ('KP_Add');
  plusKeycode   := XKeysymToKeycode (d, plusKeySym);

  minusKeySym   := XStringToKeysym ('KP_Subtract');
  minusKeycode  := XKeysymToKeycode (d, minusKeySym);


  { event loop }
  while (True) do
   begin

     XNextEvent(d, @e);

    if draw_once = true then
         begin
          if choice = 1 then DrawMandelbrotSet(d,w,s,Width,Height);   //Plot the Mandelbrot set.
          if choice = 2 then DrawNewtonSet(d,w,s,Width,Height);
          draw_once := false;
         end;




    //keep checking the events for a key press
    if (e._type = KeyPress) then
      begin
       // xmodmap -pk to display keycodes and keysym
       if  e.xkey.keycode = 9 then break;  //break on escape keycode


       Keycode := XKeysymToKeycode (d, XStringToKeysym ('1'));
       if  e.xkey.keycode = Keycode then
         begin
          Maxiter := 48;
          choice := 1;
         end;

       Keycode := XKeysymToKeycode (d, XStringToKeysym ('2'));
       if  e.xkey.keycode = Keycode then
         begin
          Maxiter := 15;
          choice := 2;
         end;

       if  e.xkey.keycode = sKeycode then
         begin
          //fpSystem('xwd -out tydump.xwd -name "' + Displaystring(d) + '"'  );
          fpSystem('xwd -out frame' +   Format('%.4d',[frame]) + '.xwd -name "X11 Example"'  );
          frame := frame + 1;
         end;

       if  e.xkey.keycode = mkeycode then
         begin
          maxiter := maxiter + 12;
         end;

       if  e.xkey.keycode = nKeycode then
         begin
         maxiter := maxiter - 12;
         if maxiter < 2 then maxiter := 2;
         end;
;
       if  e.xkey.keycode = plusKeycode then
         begin
          zoomer(-20);
         end;

       if  e.xkey.keycode = minusKeycode then
         begin
          zoomer(20);
         end;

       if  e.xkey.keycode = UpKeycode then
         begin
          Pan(0,15);
         end;

       if  e.xkey.keycode = downKeycode then
         begin
           Pan(0,-15);
         end;

       if  e.xkey.keycode = rightKeycode then
         begin
           Pan(15,0);
         end;

       if  e.xkey.keycode = leftKeycode then
         begin
          Pan(-15,0);
         end;

       if  e.xkey.keycode = iKeycode then
         begin
          writeinformation;
         end;

         XclearWindow(d,w); //you may prefer to paint on a blank canvas
         draw_once := true;
         Xflush(d);


      end;



 end;

  { close connection to server }
  XCloseDisplay(d);
end;

var
  c : integer;

begin  {Main}


  writedestructions; //general instructions on program use

  c := 1; //kick off with the Mandelbrot Plot

  if c = 1 then Init_MandelBrot_variables(Width,Height,ParamCount,Paramstr(1),Paramstr(2),Paramstr(3),Paramstr(4));

  if c = 2 then Newton_Init_globals(Width,Height);

  OpenX11Window('X11 Example',c);

end.