unit X11_Displays; {$M+} interface uses X11_Objects, X11, type_fixes, X11_Screens, xlib; type // that really shouldn't be. TDisplay = class(system.TObject) private fScreens : TScreenArray; fHandle : PDisplay; fBOwnsDisplay : Boolean; protected function GetScreen(aIndex : TCardinal) : X11_Screens.TScreen; function GetScreenCount : TCardinal; //function ISHMExtension.GetPixmapFormat = GetSHMPixmapFormat : ?; function GetSHM : ISHMExtension; function GetDefaultScreen : TCardinal; procedure DeleteUnderlyingObject; // override; function GetHandle() : PDisplay; public destructor Destroy(); override; published constructor Open; public property Screens[index : TCardinal] : X11_Screens.TScreen read GetScreen; published property ScreenCount : TCardinal read GetScreenCount; property DefaultScreen : TCardinal read GetDefaultScreen; // index into Screens[]. // TODO externalize this? //property SHMPixmapFormat : ?; procedure Flush; // eew... property SHM : ISHMExtension read GetSHM; class function Default : TDisplay; // argh. public property Handle : PDisplay read GetHandle; end; implementation uses sysutils, X11_SHM_Extension; var fDefaultDisplay : TDisplay = nil; class function TDisplay.Default : TDisplay; // argh. begin if not Assigned(fDefaultDisplay) then fDefaultDisplay := TDisplay.Open(); Result := fDefaultDisplay; end; constructor TDisplay.Open; begin //SetLength(fScreens, 0); inherited Create; fBOwnsDisplay := True; fHandle := XOpenDisplay(nil); end; procedure TDisplay.DeleteUnderlyingObject; begin if Assigned(fHandle) and fBOwnsDisplay then begin XCloseDisplay(fHandle); fHandle := nil; end; end; function TDisplay.GetHandle() : PDisplay; begin Result := fHandle; end; destructor TDisplay.Destroy(); begin DeleteUnderlyingObject(); inherited Destroy(); end; function TDisplay.GetDefaultScreen : TCardinal; begin Result := xlib.DefaultScreen(fHandle); end; function TDisplay.GetScreen(aIndex : TCardinal) : X11_Screens.TScreen; var XScreen : xlib.PScreen; begin if Length(fScreens) < GetScreenCount then SetLength(fScreens, GetScreenCount); // FIXME zero the area? if not Assigned(fScreens[aIndex]) then begin XScreen := xlib.ScreenOfDisplay(fHandle, aIndex); fScreens[aIndex] := X11_Screens.TScreen.Reuse(Handle, XScreen, False); end; Result := fScreens[aIndex]; end; function TDisplay.GetScreenCount : TCardinal; begin Result := xlib.ScreenCount(Handle); end; procedure TDisplay.Flush; // eew... begin end; function TDisplay.GetSHM : ISHMExtension; begin Result := TSHMExtension.Open(Handle); end; finalization FreeAndNil(fDefaultDisplay); end.