[fpc-pascal] Simple X11 program
Graeme Geldenhuys
graemeg.lists at gmail.com
Fri Mar 14 14:30:54 CET 2008
On 14/03/2008, Rainer Stratmann <RainerStratmann at t-online.de> wrote:
> Exists there documentation about X11 interface?
> Or an example program?
Here is a basic example as show in many X11 documentation.
As I said, fpGUI will do all this hard work for you. ;-)
You can compile it as follows: fpc basicwin.pas
-------------------[ basicwin.pas ]--------------------
program basicwin;
{$mode objfpc}{$H+}
uses
SysUtils, xlib, x, xutil;
const
IconBitmapWidth = 40;
IconBitmapHeight = 40;
IconBitmapBits: packed array[1..200] of Byte = (
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $80, $00,
$00, $00, $00, $40, $00, $00, $10, $00, $20, $00, $00, $20,
$00, $10, $00, $00, $40, $00, $10, $00, $00, $80, $00, $08,
$00, $00, $00, $01, $04, $00, $00, $00, $01, $02, $00, $00,
$00, $02, $01, $00, $00, $00, $84, $00, $00, $00, $00, $48,
$00, $00, $00, $00, $30, $00, $00, $00, $00, $20, $00, $00,
$00, $00, $50, $00, $00, $00, $00, $88, $00, $00, $00, $00,
$04, $01, $00, $00, $00, $02, $02, $00, $00, $00, $01, $02,
$00, $00, $80, $00, $04, $00, $00, $40, $00, $08, $00, $00,
$40, $00, $10, $00, $00, $20, $00, $20, $00, $00, $10, $00,
$00, $00, $00, $08, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00);
BITMAPDEPTH = 1;
TOO_SMALL = 0;
BIG_ENOUGH = 1;
var
Display: PDisplay;
ScreenNum: Integer;
ProgName: String;
procedure CheckMemory(P: Pointer);
begin
if P = nil then
begin
Writeln(ProgName,': Failure Allocating Memory');
Halt(0);
end;
end;
procedure GetDC(Win: TWindow;var GC: TGC; FontInfo: PXFontStruct);
const
DashList: packed array[1..2] of Byte = (12, 24);
var
ValueMask: Cardinal;
Values: TXGCValues;
LineWidth: Cardinal;
LineStyle: Integer;
CapStyle: Integer;
JoinStyle: Integer;
DashOffset: Integer;
ListLength: Integer;
begin
ValueMask := 0;
LineWidth := 6;
LineStyle := LineOnOffDash;
CapStyle := CapRound;
JoinStyle := JoinRound;
DashOffset := 0;
ListLength := 2;
FillChar(Values, SizeOf(Values), 0);
GC := XCreateGC(Display, Win, ValueMask, @Values);
XSetFont(Display, GC, FontInfo^.fid);
XSetForeground(Display, GC, XBlackPixel(Display, ScreenNum));
XSetLineAttributes(Display, GC, LineWidth, LineStyle, CapStyle, JoinStyle);
XSetDashes(Display, GC, DashOffSet, @DashList, ListLength);
end;
procedure LoadFont(var FontInfo: PXFontStruct);
const
FontName: PChar = '9x15';
begin
Writeln('Font Struct:', SizeOf(TXFontStruct));
FontInfo := XLoadQueryFont(Display, FontName);
if FontInfo = nil then
begin
Writeln(Progname, ': Cannot open 9x15 font.');
Halt(1);
end;
end;
procedure PlaceText(Win: TWindow; GC: TGC; FontInfo: PXFontStruct;
WinWidth, WinHeight: Cardinal);
const
String1: PChar = 'Hi! I''m a window, who are you?';
String2: PChar = 'To terminate program; Press any key';
String3: PChar = 'or button while in this window.';
String4: PChar = 'Screen dimensions:';
var
Len1, Len2, Len3, Len4: Integer;
Width1, Width2, Width3: Integer;
CDHeight, CDWidth, CDDepth: PChar; // array[0..49] of Char;
FontHeight: Integer;
InitialYOffset, XOffset: Integer;
Top, Left: Integer;
begin
Writeln('#1');
Len1 := StrLen(String1);
Len2 := StrLen(String2);
Len3 := StrLen(String3);
Writeln('#2');
Width1 := XTextWidth(FontInfo, String1, Len1);
Width2 := XTextWidth(FontInfo, String2, Len2);
Width3 := XTextWidth(FontInfo, String3, Len3);
FontHeight := FontInfo^.Ascent + FontInfo^.Descent;
XDrawString(Display, Win, GC, (WinWidth - Width1) div 2, FontHeight, String1,
Len1);
Writeln('#2.2 ', Len2, ' ', String2);
Left := (WinWidth - Width2);
Writeln('#2.2.5 Here');
Left := Left div 2;
Top := WinHeight - FontHeight * 2;
Writeln('#2.3 Top:', Top, ' Left:', Left);
XDrawString(Display, Win, GC, Left, Top, String2, Len2);
Writeln('#2.3');
XDrawString(Display, Win, GC, (WinWidth - Width3) div 2,
WinHeight - FontHeight, String3, Len3);
Writeln('#3');
CDHeight := PChar(Format(' Height = %d pixels', [XDisplayHeight(Display,
ScreenNum)]));
CDWidth := PChar(Format(' Width = %d pixels', [XDisplayWidth(Display,
ScreenNum)]));
CDDepth := PChar(Format(' Depth = %d plane(s)', [XDefaultDepth(Display,
ScreenNum)]));
Len4 := StrLen(String4);
Len1 := StrLen(CDHeight);
Len2 := StrLen(CDWidth);
Len3 := StrLen(CDDepth);
Writeln('#4');
InitialYOffset := WinHeight div 2 - FontHeight - FontInfo^.descent;
XOffset := WinWidth div 4;
XDrawString(Display, Win, GC, XOffset, InitialYOffset, String4, Len4);
XDrawString(Display, Win, GC, XOffset, InitialYOffset + FontHeight,
CDHeight, Len1);
XDrawString(Display, Win, GC, XOffset, InitialYOffset + 2 * FontHeight,
CDWidth, Len2);
XDrawString(Display, Win, GC, XOffset, InitialYOffset + 3 * FontHeight,
CDDepth, Len3);
Writeln('#5');
end;
procedure PlaceGraphics(Win: TWindow; GC: TGC;
WindowWidth, WindowHeight: Cardinal);
var
X, Y: Integer;
Width, Height: Integer;
begin
Writeln('Window: ', Integer(Win));
Writeln('GC: ', INteger(GC));
Height := WindowHeight div 2;
Width := 3 * WindowWidth div 4;
X := WindowWidth div 2 - Width div 2;
Y := WindowHeight div 2 - Height div 2;
XDrawRectangle(Display, Win, GC, X, Y, Width, Height);
end;
procedure TooSmall(Win: TWindow; GC: TGC; FontInfo: PXFontStruct);
const
String1: PChar = 'Too Small';
var
YOffset, XOffset: Integer;
begin
YOffset := FontInfo^.Ascent + 2;
XOffset := 2;
XDrawString(Display, Win, GC, XOffset, YOffset, String1, StrLen(String1));
end;
var
Win: TWindow;
Width, Height: Word;
Left, Top: Integer;
BorderWidth: Word = 4;
DisplayWidth, DisplayHeight: Word;
// IconWidth, IconHeight: Word;
WindowNameStr: PChar = 'Basic Window Program';
IconNameStr: PChar = 'basicWin';
IconPixmap: TPixmap;
SizeHints: PXSizeHints;
SizeList: PXIconSize;
WMHints: PXWMHints;
ClassHints: PXClassHint;
WindowName, IconName: TXTextProperty;
Count: Integer;
Report: TXEvent;
GC: TGC;
FontInfo: PXFontStruct;
DisplayName: PChar = nil;
WindowSize: Integer = 0;
begin
ProgName := ParamStr(0);
// ProgName := 'BasicWin'; //JJS Remove when 80999 is fixed.
SizeHints := XAllocSizeHints;
CheckMemory(SizeHints);
WMHints := XAllocWMHints;
CheckMemory(WMHints);
ClassHints := XAllocClassHint;
CheckMemory(ClassHints);
Display := XOpenDisplay(DisplayName);
if Display = nil then
begin
Writeln(ProgName,': cannot connect to XServer',
XDisplayName(DisplayName));
Halt(1);
end;
ScreenNum := XDefaultScreen(Display);
DisplayWidth := XDisplayWidth(Display, ScreenNum);
DisplayHeight := XDisplayHeight(Display, ScreenNum);
Left := 0; Top := 0;
Width := DisplayWidth div 4; Height := DisplayHeight div 4;
Win := XCreateSimpleWindow(Display, XRootWindow(Display, ScreenNum),
Left, Top, Width, Height, BorderWidth, XBlackPixel(Display, ScreenNum),
XWhitePixel(Display, ScreenNum));
if XGetIconSizes(Display, XRootWindow(Display, ScreenNum), @SizeList,
@Count) = 0
then
Writeln('Window Manager didn''t set icon sizes - using default')
else
begin
end;
IconPixMap := XCreateBitmapFromData(Display, Win, @IconBitmapBits,
IconBitmapWidth, IconBitmapHeight);
SizeHints^.flags := PPosition or PSize or PMinSize;
SizeHints^.min_width := 300;
SizeHints^.min_height:= 200;
if XStringListToTextProperty(@WindowNameStr, 1, @WindowName) = 0 then
begin
Writeln(Progname, ': structure allocation for window name failed.');
Halt(1);
end;
if XStringListToTextProperty(@IconNameStr, 1, @IconName) = 0 then
begin
Writeln(Progname, ': structure allocqation for icon name failed.');
Halt(1);
end;
WMHints^.initial_state := NormalState;
WMHints^.input := True;
WMHints^.icon_pixmap := IconPixmap;
WMHints^.flags := StateHint or IconPixmapHint or InputHint;
ClassHints^.res_name := PChar(ProgName);
ClassHints^.res_class := 'BasicWin';
XSetWMProperties(Display, Win, @WindowName, @IconName, nil, 0, SizeHints,
WMHints, ClassHints);
XSelectInput(Display, Win, ExposureMask or KeyPressMask or ButtonPressMask
or StructureNotifyMask);
LoadFont(FontInfo);
GetDC(win, GC, FontInfo);
XMapWindow(Display, Win);
while True do
begin
XNextEvent(Display, @Report);
case Report._type of
Expose:
begin
Writeln('Expose');
if Report.xexpose.count = 0 then
begin
if WindowSize = TOO_SMALL then
TooSmall(Win, GC, FontInfo)
else
begin
PlaceText(Win, GC, FontInfo, Width, Height); //*** Fails
PlaceGraphics(Win, GC, Width, Height);
end;
end;
end;
ConfigureNotify:
begin
Writeln('Configure Notify');
Width := Report.xconfigure.Width;
Height := Report.xconfigure.Height;
Writeln(' Width: ', Width);
Writeln(' Height: ', Height);
if (width < SizeHints^.min_width) or
(Height < SizeHints^.min_height)
then
WindowSize := TOO_SMALL
else
WindowSize := BIG_ENOUGH;
end;
ButtonPress:
begin
Writeln('ButtonPress');
end;
KeyPress:
begin
Writeln('KeyProcess');
XUnloadFont(Display, FontInfo^.fid);
XFreeGC(Display, GC);
XCloseDisplay(Display);
halt(0);
end;
else
end;
end;
Writeln('End.');
end.
----------------------[ end ]------------------------
Regards,
- Graeme -
_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/
More information about the fpc-pascal
mailing list