1
0
mirror of https://github.com/moparisthebest/Simba synced 2024-11-23 17:52:16 -05:00

MML/Core: Clean up os_linux.

This commit is contained in:
Merlijn Wajer 2011-07-30 11:32:58 +02:00
parent da0de6e4b9
commit 880072d723

View File

@ -20,15 +20,21 @@
Linux OS specific implementation for Mufasa Macro Library Linux OS specific implementation for Mufasa Macro Library
} }
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
unit os_linux; unit os_linux;
{
TODO's:
- Allow selecting a different X display
- Fix keyboard layout / SendString
}
interface interface
uses uses
Classes, SysUtils, mufasatypes, xlib, x, xutil, IOManager, XKeyInput, ctypes, xtest, Classes, SysUtils, mufasatypes, xlib, x, xutil, IOManager, XKeyInput, ctypes, xtest,
syncobjs, mufasabase; syncobjs, mufasabase;
type type
TNativeWindow = x.TWindow; TNativeWindow = x.TWindow;
@ -43,7 +49,7 @@ interface
TWindow = class(TWindow_Abstract) TWindow = class(TWindow_Abstract)
public public
constructor Create(display: PDisplay; screennum: integer; window: x.TWindow); constructor Create(display: PDisplay; screennum: integer; window: x.TWindow);
destructor Destroy; override; destructor Destroy; override;
procedure GetTargetDimensions(out w, h: integer); override; procedure GetTargetDimensions(out w, h: integer); override;
procedure GetTargetPosition(out left, top: integer); override; procedure GetTargetPosition(out left, top: integer); override;
@ -89,7 +95,7 @@ interface
{ X Error Handler } { X Error Handler }
oldXHandler: TXErrorHandler; oldXHandler: TXErrorHandler;
end; end;
TIOManager = class(TIOManager_Abstract) TIOManager = class(TIOManager_Abstract)
public public
constructor Create; constructor Create;
@ -109,7 +115,7 @@ interface
end; end;
function MufasaXErrorHandler(para1:PDisplay; para2:PXErrorEvent):cint; cdecl; function MufasaXErrorHandler(para1:PDisplay; para2:PXErrorEvent):cint; cdecl;
implementation implementation
uses GraphType, interfacebase, lcltype; uses GraphType, interfacebase, lcltype;
@ -126,7 +132,7 @@ implementation
{ {
This is extremely hacky, but also very useful. This is extremely hacky, but also very useful.
We have to install a X error handler, because otherwise X We have to install a X error handler, because otherwise X
will terminate out entire app on error. will terminate our entire app on error.
Since we want the right thread to recieve the right error, we have to Since we want the right thread to recieve the right error, we have to
fiddle a bit with threadvars, mutexes / semaphores. fiddle a bit with threadvars, mutexes / semaphores.
@ -207,8 +213,8 @@ implementation
end; end;
{ See if the semaphores / CS are initialised } { See if the semaphores / CS are initialised }
constructor TWindow.Create(display: PDisplay; screennum: integer; window: x.TWindow); constructor TWindow.Create(display: PDisplay; screennum: integer; window: x.TWindow);
begin begin
inherited Create; inherited Create;
self.display:= display; self.display:= display;
self.screennum:= screennum; self.screennum:= screennum;
@ -227,8 +233,8 @@ implementation
finally finally
ErrorCS.Leave; ErrorCS.Leave;
end; end;
end; end;
destructor TWindow.Destroy; destructor TWindow.Destroy;
var var
erh: TXErrorHandler; erh: TXErrorHandler;
@ -304,8 +310,8 @@ implementation
if ReceivedError then if ReceivedError then
raise Exception.Create('Error: ActivateClient: ' + GetError); raise Exception.Create('Error: ActivateClient: ' + GetError);
end; end;
function TWindow.ReturnData(xs, ys, width, height: Integer): TRetData; function TWindow.ReturnData(xs, ys, width, height: Integer): TRetData;
var var
w,h: integer; w,h: integer;
begin begin
@ -334,8 +340,8 @@ implementation
dirty:= true; dirty:= true;
//XSetErrorHandler(Old_Handler); //XSetErrorHandler(Old_Handler);
end; end;
procedure TWindow.FreeReturnData; procedure TWindow.FreeReturnData;
begin begin
if dirty then if dirty then
begin begin
@ -413,40 +419,41 @@ implementation
result := xmask and ButtonP > 0; result := xmask and ButtonP > 0;
end; end;
procedure TWindow.SendString(str: string); { TODO: Check if this supports multiple keyboard layouts, probably not }
var procedure TWindow.SendString(str: string);
I, L: Integer; var
K: Byte; I, L: Integer;
HoldShift: Boolean; K: Byte;
begin HoldShift: Boolean;
HoldShift := False;
L := Length(str);
for I := 1 to L do
begin begin
if (((str[I] >= 'A') and (str[I] <= 'Z')) or HoldShift := False;
((str[I] >= '!') and (str[I] <= '&')) or L := Length(str);
((str[I] >= '(') and (str[I] <= '+')) or for I := 1 to L do
(str[I] = ':') or
((str[I] >= '<') and (str[I] <= '@')) or
((str[I] >= '^') and (str[I] <= '_')) or
((str[I] >= '{') and (str[I] <= '~'))) then
begin begin
HoldKey(VK_SHIFT); if (((str[I] >= 'A') and (str[I] <= 'Z')) or
HoldShift := True; ((str[I] >= '!') and (str[I] <= '&')) or
end; ((str[I] >= '(') and (str[I] <= '+')) or
(str[I] = ':') or
K := GetKeyCode(str[I]); ((str[I] >= '<') and (str[I] <= '@')) or
HoldKey(K); ((str[I] >= '^') and (str[I] <= '_')) or
Sleep(20); ((str[I] >= '{') and (str[I] <= '~'))) then
ReleaseKey(K); begin
HoldKey(VK_SHIFT);
if (HoldShift) then HoldShift := True;
begin end;
HoldShift := False;
ReleaseKey(VK_SHIFT); K := GetKeyCode(str[I]);
HoldKey(K);
Sleep(20);
ReleaseKey(K);
if (HoldShift) then
begin
HoldShift := False;
ReleaseKey(VK_SHIFT);
end;
end; end;
end; end;
end;
procedure TWindow.HoldKey(key: integer); procedure TWindow.HoldKey(key: integer);
begin begin
@ -474,7 +481,7 @@ end;
Raise Exception.CreateFMT('GetSimpleKeyCode - char (%s) is not in A..z',[c]); Raise Exception.CreateFMT('GetSimpleKeyCode - char (%s) is not in A..z',[c]);
end end
end; end;
{ ***implementation*** IOManager } { ***implementation*** IOManager }
constructor TIOManager.Create; constructor TIOManager.Create;
@ -499,17 +506,17 @@ end;
{ Get the Desktop Window } { Get the Desktop Window }
desktop:= RootWindow(display,screennum) desktop:= RootWindow(display,screennum)
end; end;
procedure TIOManager.NativeFree; procedure TIOManager.NativeFree;
begin begin
XCloseDisplay(display); XCloseDisplay(display);
end; end;
procedure TIOManager.SetDesktop; procedure TIOManager.SetDesktop;
begin begin
SetBothTargets(TWindow.Create(display, screennum, desktop)); SetBothTargets(TWindow.Create(display, screennum, desktop));
end; end;
function TIOManager.SetTarget(target: x.TWindow): integer; function TIOManager.SetTarget(target: x.TWindow): integer;
begin begin
result := SetBothTargets(TWindow.Create(display, screennum, target)) result := SetBothTargets(TWindow.Create(display, screennum, target))