diff --git a/branches/iomanager/Projects/SAMufasaGUI/project1.lpi b/branches/iomanager/Projects/SAMufasaGUI/project1.lpi
index 7150c9d..12a6d28 100644
--- a/branches/iomanager/Projects/SAMufasaGUI/project1.lpi
+++ b/branches/iomanager/Projects/SAMufasaGUI/project1.lpi
@@ -10,7 +10,7 @@
-
+
@@ -43,7 +43,7 @@
-
+
@@ -139,9 +139,10 @@
-
-
-
+
+
+
+
@@ -189,8 +190,8 @@
-
-
+
+
@@ -201,7 +202,7 @@
-
+
@@ -268,9 +269,11 @@
-
-
+
+
+
+
@@ -489,8 +492,8 @@
-
-
+
+
@@ -535,9 +538,9 @@
-
-
-
+
+
+
@@ -626,7 +629,7 @@
-
+
@@ -1196,10 +1199,9 @@
-
-
+
@@ -1370,8 +1372,8 @@
-
-
+
+
@@ -1486,7 +1488,7 @@
-
+
@@ -1596,7 +1598,7 @@
-
+
@@ -1651,7 +1653,7 @@
-
+
@@ -1726,7 +1728,7 @@
-
+
@@ -1737,7 +1739,7 @@
-
+
@@ -1858,7 +1860,7 @@
-
+
@@ -1903,7 +1905,7 @@
-
+
@@ -1960,7 +1962,7 @@
-
+
@@ -2006,10 +2008,10 @@
-
-
-
-
+
+
+
+
@@ -2017,8 +2019,8 @@
-
-
+
+
@@ -2033,8 +2035,8 @@
-
-
+
+
@@ -2052,99 +2054,127 @@
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2155,7 +2185,7 @@
-
+
@@ -2180,6 +2210,12 @@
+
+
+
+
+
+
diff --git a/branches/iomanager/Units/MMLAddon/plugins.pas b/branches/iomanager/Units/MMLAddon/plugins.pas
index 0d48c52..35bdaf7 100644
--- a/branches/iomanager/Units/MMLAddon/plugins.pas
+++ b/branches/iomanager/Units/MMLAddon/plugins.pas
@@ -34,7 +34,7 @@ unit plugins;
interface
uses
- Classes, SysUtils,dynlibs;
+ Classes, SysUtils, dynlibs;
type
TMPluginMethod = record
@@ -44,31 +44,45 @@ type
TMPlugin = record
Methods : Array of TMPluginMethod;
- dllHandle : TLibHandle;
- filename : string;
MethodLen : integer;
end;
TMPluginArray = array of TMPlugin;
- { TMPlugins }
+ TGenericLib = record
+ filename: string;
+ handle: TLibHandle;
+ end;
+ TGenericLibArray = array of TGenericLib;
- TMPlugins = class (TObject)
- private
- Plugins : TMPluginArray;
- PluginLen : integer;
- procedure FreePlugins;
- public
- PluginDirs : TStringList;
- procedure ValidateDirs;
- procedure LoadPluginsDir( DirIndex : integer);
- function LoadPlugin(PluginName : string) : integer;
- property Count : integer read PluginLen;
- property MPlugins : TMPluginArray read Plugins;
- constructor Create;
- destructor Destroy;override;
+ TGenericLoader = class(TObject)
+ private
+ PluginLen : integer;
+ Loaded: TGenericLibArray;
+ procedure FreePlugins;
+ protected
+ function InitPlugin(plugin: TLibHandle): boolean; virtual; abstract;
+ public
+ PluginDirs : TStringList;
+ constructor Create;
+ destructor Destroy; override;
+ procedure ValidateDirs;
+ procedure LoadPluginsDir(DirIndex : integer);
+ function LoadPlugin(PluginName : string) : integer;
end;
+ { TMPlugins }
+
+ TMPlugins = class (TGenericLoader)
+ private
+ Plugins : TMPluginArray;
+ NumPlugins : integer;
+ protected
+ function InitPlugin(plugin: TLibHandle): boolean; override;
+ public
+ property MPlugins : TMPluginArray read Plugins;
+ property Count : integer read NumPlugins;
+ end;
implementation
@@ -77,24 +91,24 @@ uses
{ TMPlugins }
-procedure TMPlugins.FreePlugins;
+procedure TGenericLoader.FreePlugins;
var
I : integer;
begin
for i := 0 to PluginLen - 1 do
begin;
- if (Plugins[i].dllHandle > 0) then
+ if (Loaded[i].handle > 0) then
try
Writeln(inttostr(I));
- FreeLibrary(Plugins[i].dllHandle);
+ FreeLibrary(Loaded[i].handle);
except
end;
end;
- SetLength(Plugins,0);
+ SetLength(Loaded,0);
PluginLen:= 0;
end;
-procedure TMPlugins.ValidateDirs;
+procedure TGenericLoader.ValidateDirs;
var
i : integer;
TempStr : string;
@@ -115,7 +129,7 @@ begin
end;
end;
-procedure TMPlugins.LoadPluginsDir(DirIndex: integer);
+procedure TGenericLoader.LoadPluginsDir(DirIndex: integer);
var
PlugExt: String = {$IFDEF LINUX}'*.so';{$ELSE}'*.dll';{$ENDIF}
FileSearcher : TSearchRec;
@@ -133,16 +147,10 @@ begin
FindClose(FileSearcher);
end;
-function TMPlugins.LoadPlugin(PluginName: string): Integer;
+
+function TGenericLoader.LoadPlugin(PluginName: string): Integer;
var
i, ii : integer;
- pntrArrc : function : integer; stdcall;
- GetFuncInfo : function (x: Integer; var ProcAddr: Pointer; var ProcDef: PChar) : Integer; stdcall;
- GetTypeCount : function : Integer; stdcall;
- GetTypeInfo : function (x: Integer; var sType, sTypeDef: string): Integer; stdcall;
- PD : PChar;
- pntr : Pointer;
- arrc : integer;
Status : LongInt;
PlugExt: String = {$IFDEF LINUX}'.so';{$ELSE}'.dll';{$ENDIF}
begin
@@ -162,51 +170,66 @@ begin
if ii = -1 then
raise Exception.CreateFMT('Plugins(%s) has not been found',[PluginName]);
for i := 0 to PluginLen - 1 do
- if Plugins[i].filename = (PluginDirs.Strings[ii] + PluginName + PlugExt) then
+ if Loaded[i].filename = (PluginDirs.Strings[ii] + PluginName + PlugExt) then
Exit(i);
- pd := StrAlloc(255);
- SetLength(Plugins,PluginLen + 1);
+ SetLength(Loaded,PluginLen + 1);
Writeln(Format('Loading plugin %s at %s',[PluginName,PluginDirs.Strings[ii]]));
- Plugins[PluginLen].filename:= PluginDirs.Strings[ii] + Pluginname + PlugExt;
- Plugins[PluginLen].dllHandle:= LoadLibrary(PChar(Plugins[PluginLen].filename));
- if Plugins[PluginLen].dllHandle = 0 then
- Raise Exception.CreateFMT('Error loading plugin %s',[Plugins[PluginLen].filename]);
- Pointer(pntrArrc) := GetProcAddress(Plugins[PluginLen].dllHandle, PChar('GetFunctionCount'));
- if @pntrArrc = nil then
- Raise Exception.CreateFMT('Error loading plugin %s',[Plugins[PluginLen].filename]);
- arrc := pntrArrc();
- SetLength(Plugins[PluginLen].Methods, ArrC);
- Pointer(GetFuncInfo) := GetProcAddress(Plugins[PluginLen].dllHandle, PChar('GetFunctionInfo'));
- if @GetFuncInfo = nil then
- Raise Exception.CreateFMT('Error loading plugin %s',[Plugins[PluginLen].filename]);
- Plugins[PluginLen].MethodLen := Arrc;
- for ii := 0 to ArrC-1 do
- begin;
- if (GetFuncInfo(ii, pntr, pd) < 0) then
- Continue;
- Plugins[Pluginlen].Methods[ii].FuncPtr := pntr;
- Plugins[Pluginlen].Methods[ii].FuncStr := pd;
- end;
+ Loaded[PluginLen].filename:= PluginDirs.Strings[ii] + Pluginname + PlugExt;
+ Loaded[PluginLen].handle:= LoadLibrary(PChar(Loaded[PluginLen].filename));
+ if Loaded[PluginLen].handle = 0 then
+ Raise Exception.CreateFMT('Error loading plugin %s',[Loaded[PluginLen].filename]);
+ if InitPlugin(Loaded[PluginLen].handle) then
+ inc(PluginLen)
+ else
+ FreeLibrary(Loaded[PluginLen].handle);
Result := PluginLen;
- inc(PluginLen);
- StrDispose(pd);
-
end;
-constructor TMPlugins.Create;
+constructor TGenericLoader.Create;
begin
inherited Create;
PluginLen := 0;
PluginDirs := TStringList.Create;
end;
-destructor TMPlugins.Destroy;
+destructor TGenericLoader.Destroy;
begin
FreePlugins;
PluginDirs.Free;
inherited Destroy;
end;
+function TMPlugins.InitPlugin(plugin: TLibHandle): boolean;
+var
+ pntrArrc : function : integer; stdcall;
+ GetFuncInfo : function (x: Integer; var ProcAddr: Pointer; var ProcDef: PChar) : Integer; stdcall;
+ GetTypeCount : function : Integer; stdcall;
+ GetTypeInfo : function (x: Integer; var sType, sTypeDef: string): Integer; stdcall;
+ PD : PChar;
+ pntr : Pointer;
+ arrc, ii : integer;
+begin
+ Pointer(pntrArrc) := GetProcAddress(plugin, PChar('GetFunctionCount'));
+ if @pntrArrc = nil then begin result:= false; exit; end;
+ Pointer(GetFuncInfo) := GetProcAddress(plugin, PChar('GetFunctionInfo'));
+ if @GetFuncInfo = nil then begin result:= false; exit; end;
+ arrc := pntrArrc();
+ SetLength(Plugins,NumPlugins+1);
+ Plugins[NumPlugins].MethodLen := Arrc;
+ SetLength(Plugins[NumPlugins].Methods, ArrC);
+ pd := StrAlloc(255);
+ for ii := 0 to ArrC-1 do
+ begin;
+ if (GetFuncInfo(ii, pntr, pd) < 0) then
+ Continue;
+ Plugins[NumPlugins].Methods[ii].FuncPtr := pntr;
+ Plugins[NumPlugins].Methods[ii].FuncStr := pd;
+ end;
+ StrDispose(pd);
+ inc(NumPlugins);
+ result:= true;
+end;
+
end.
diff --git a/branches/iomanager/Units/MMLCore/iomanager.pas b/branches/iomanager/Units/MMLCore/iomanager.pas
index 45ab2cd..e0debbe 100644
--- a/branches/iomanager/Units/MMLCore/iomanager.pas
+++ b/branches/iomanager/Units/MMLCore/iomanager.pas
@@ -26,7 +26,7 @@ unit IOManager;
interface
uses
- Classes, SysUtils, mufasatypes, graphics, LCLType, bitmaps, LCLIntf;
+ Classes, SysUtils, mufasatypes, graphics, LCLType, bitmaps, LCLIntf, plugins, dynlibs;
type
@@ -115,9 +115,6 @@ interface
HoldKey: procedure(target: pointer; key: integer); stdcall;
ReleaseKey: procedure(target: pointer; key: integer); stdcall;
IsKeyHeld: function(target: pointer; key: integer): boolean; stdcall;
-
- Initialize: procedure; stdcall;
- Finalize: procedure; stdcall;
end;
{ Implements a EIOS target. This is, for all intensive purposes, a TRawTarget with added
@@ -155,7 +152,6 @@ interface
| a TEIOS_Client with the method pointers set. }
type TEIOS_LoadedPlugin = record
name: string;
- plugin: pointer;
client: TEIOS_Client;
end;
@@ -167,14 +163,16 @@ interface
| would be the single call....
| SetTarget('SMART',SmartSetupRecord);
| Sexy, right? ;}
- TEIOS_Controller = class(TObject)
+ TEIOS_Controller = class(TGenericLoader)
public
constructor Create(plugin_dir: string);
destructor Destroy; override;
function ClientExists(name: string): boolean;
function GetClient(name: string): TEIOS_Client;
-
+
+ protected
+ function InitPlugin(plugin: TLibHandle): boolean; override;
private
plugs: array of TEIOS_LoadedPlugin;
function FindClient(name:string): integer;
@@ -237,7 +235,7 @@ interface
implementation
- uses
+ uses FileUtil,
{$IFDEF MSWINDOWS} os_windows {$ENDIF}
{$IFDEF LINUX} os_linux {$ENDIF};
@@ -246,7 +244,7 @@ implementation
constructor TIOManager_Abstract.Create(plugin_dir: string);
begin
inherited Create;
- controller:= nil;
+ controller:= TEIOS_Controller.Create(plugin_dir);
keymouse:= nil;
image:= nil;
frozen:= nil;
@@ -392,9 +390,13 @@ implementation
constructor TEIOS_Target.Create(client: TEIOS_Client; initval: pointer); begin
inherited Create;
self.client:= client;
- self.target:= client.RequestTarget(initval);
- self.buffer:= client.GetImageBuffer(target);
- client.GetTargetDimensions(target,self.width,self.height);
+ if Pointer(client.RequestTarget) <> nil then
+ self.target:= client.RequestTarget(initval);
+ if Pointer(client.GetImageBuffer) <> nil then
+ self.buffer:= client.GetImageBuffer(target)
+ else
+ self.buffer:= nil;
+ GetTargetDimensions(self.width,self.height);
end;
destructor TEIOS_Target.Destroy; begin
@@ -402,39 +404,95 @@ implementation
inherited Destroy;
end;
- procedure TEIOS_Target.GetTargetDimensions(var w, h: integer); begin client.GetTargetDimensions(target,w,h); end;
+ procedure TEIOS_Target.GetTargetDimensions(var w, h: integer);
+ begin
+ if Pointer(client.GetTargetDimensions) <> nil then
+ client.GetTargetDimensions(target,w,h)
+ else
+ inherited GetTargetDimensions(w,h);
+ end;
function TEIOS_Target.ReturnData(xs, ys, width, height: Integer): TRetData;
begin
- client.UpdateImageBufferBounds(target,xs,ys,xs+width,ys+height);
+ if Pointer(client.UpdateImageBufferBounds) <> nil then
+ client.UpdateImageBufferBounds(target,xs,ys,xs+width,ys+height)
+ else if Pointer(client.UpdateImageBuffer) <> nil then
+ client.UpdateImageBuffer(target)
+ else begin
+ {no update command exported}
+ end;
result.Ptr := buffer;
result.RowLen:= self.width;
result.IncPtrWith:= result.RowLen - width;
Inc(result.Ptr, ys * result.RowLen + xs);
end;
- procedure TEIOS_Target.GetMousePosition(var x,y: integer); begin client.GetMousePosition(target,x,y); end;
- procedure TEIOS_Target.MoveMouse(x,y: integer); begin client.MoveMouse(target,x,y); end;
+ procedure TEIOS_Target.GetMousePosition(var x,y: integer);
+ begin
+ if Pointer(client.GetMousePosition) <> nil then
+ client.GetMousePosition(target,x,y)
+ else
+ inherited GetMousePosition(x,y);
+ end;
+ procedure TEIOS_Target.MoveMouse(x,y: integer);
+ begin
+ if Pointer(client.MoveMouse) <> nil then
+ client.MoveMouse(target,x,y)
+ else
+ inherited MoveMouse(x,y);
+ end;
procedure TEIOS_Target.HoldMouse(x,y: integer; button: TClickType);
begin
- case button of
- mouse_Left: client.HoldMouse(target,x,y,true);
- mouse_Middle: raise Exception.Create('EIOS does not implement the middle mouse button.');
- mouse_Right: client.HoldMouse(target,x,y,false);
- end;
+ if Pointer(client.HoldMouse) <> nil then
+ begin
+ case button of
+ mouse_Left: client.HoldMouse(target,x,y,true);
+ mouse_Middle: raise Exception.Create('EIOS does not implement the middle mouse button.');
+ mouse_Right: client.HoldMouse(target,x,y,false);
+ end;
+ end else
+ inherited HoldMouse(x,y,button);
end;
procedure TEIOS_Target.ReleaseMouse(x,y: integer; button: TClickType);
begin
- case button of
- mouse_Left: client.ReleaseMouse(target,x,y,true);
- mouse_Middle: raise Exception.Create('EIOS does not implement the middle mouse button.');
- mouse_Right: client.ReleaseMouse(target,x,y,false);
- end;
+ if Pointer(client.ReleaseMouse) <> nil then
+ begin
+ case button of
+ mouse_Left: client.ReleaseMouse(target,x,y,true);
+ mouse_Middle: raise Exception.Create('EIOS does not implement the middle mouse button.');
+ mouse_Right: client.ReleaseMouse(target,x,y,false);
+ end;
+ end else
+ inherited ReleaseMouse(x,y,button);
end;
- procedure TEIOS_Target.SendString(str: string); begin client.SendString(target,PChar(@str[1])); end;
- procedure TEIOS_Target.HoldKey(key: integer); begin client.HoldKey(target,key); end;
- procedure TEIOS_Target.ReleaseKey(key: integer); begin client.ReleaseKey(target,key); end;
- function TEIOS_Target.IsKeyHeld(key: integer): boolean; begin result:= client.IsKeyHeld(target,key); end;
+ procedure TEIOS_Target.SendString(str: string);
+ begin
+ if Pointer(client.SendString) <> nil then
+ client.SendString(target,PChar(@str[1]))
+ else
+ inherited SendString(str);
+ end;
+ procedure TEIOS_Target.HoldKey(key: integer);
+ begin
+ if Pointer(client.HoldKey) <> nil then
+ client.HoldKey(target,key)
+ else
+ inherited HoldKey(key);
+ end;
+ procedure TEIOS_Target.ReleaseKey(key: integer);
+ begin
+ if Pointer(client.ReleaseKey) <> nil then
+ client.ReleaseKey(target,key)
+ else
+ inherited ReleaseKey(key);
+ end;
+ function TEIOS_Target.IsKeyHeld(key: integer): boolean;
+ begin
+ if Pointer(client.IsKeyHeld) <> nil then
+ result:= client.IsKeyHeld(target,key)
+ else
+ result:= inherited IsKeyHeld(key);
+ end;
//***implementation*** TRawTarget
@@ -471,22 +529,57 @@ implementation
constructor TEIOS_Controller.Create(plugin_dir: string);
begin
inherited Create;
- SetLength(Plugs, 0);
- //Load plugins from plugins folder
+ PluginDirs.Add(plugin_dir);
+ LoadPluginsDir(0);
end;
destructor TEIOS_Controller.Destroy;
var
i: integer;
begin
- for i:= 0 to length(plugs) - 1 do
- if plugs[i].plugin <> nil then
- begin
- //Unload plugin that was loaded
- end;
+ SetLength(plugs,0);
inherited Destroy;
end;
-
+
+ function TEIOS_Controller.InitPlugin(plugin: TLibHandle): boolean;
+ var
+ GetName: procedure(name: pchar); stdcall;
+ buffer: pchar;
+ idx: integer;
+ begin
+ Pointer(GetName) := GetProcAddress(plugin, PChar('EIOS_GetName'));
+ if Pointer(GetName) = nil then begin result:= false; exit; end;
+ idx:= Length(plugs);
+ SetLength(plugs,idx+1);
+ buffer:= stralloc(255);
+ GetName(buffer);
+ plugs[idx].name:= buffer;
+ strdispose(buffer);
+ {link in all eios methods that *might* exist}
+ with plugs[idx].client do
+ begin
+ Pointer(RequestTarget):= GetProcAddress(plugin, PChar('EIOS_RequestTarget'));
+ Pointer(ReleaseTarget):= GetProcAddress(plugin, PChar('EIOS_ReleaseTarget'));
+
+ Pointer(GetTargetDimensions):= GetProcAddress(plugin, PChar('EIOS_GetTargetDimensions'));
+ Pointer(GetImageBuffer):= GetProcAddress(plugin, PChar('EIOS_GetImageBuffer'));
+ Pointer(UpdateImageBuffer):= GetProcAddress(plugin, PChar('EIOS_UpdateImageBuffer'));
+ Pointer(UpdateImageBufferBounds):= GetProcAddress(plugin, PChar('EIOS_UpdateImageBufferBounds'));
+
+ Pointer(GetMousePosition):= GetProcAddress(plugin, PChar('EIOS_GetMousePosition'));
+ Pointer(MoveMouse):= GetProcAddress(plugin, PChar('EIOS_MoveMouse'));
+ Pointer(HoldMouse):= GetProcAddress(plugin, PChar('EIOS_HoldMouse'));
+ Pointer(ReleaseMouse):= GetProcAddress(plugin, PChar('EIOS_ReleaseMouse'));
+
+ Pointer(SendString):= GetProcAddress(plugin, PChar('EIOS_SendString'));
+ Pointer(HoldKey):= GetProcAddress(plugin, PChar('EIOS_HoldKey'));
+ Pointer(ReleaseKey):= GetProcAddress(plugin, PChar('EIOS_ReleaseKey'));
+ Pointer(IsKeyHeld):= GetProcAddress(plugin, PChar('EIOS_IsKeyHeld'));
+ end;
+ {done linking in methods}
+ result:= true;
+ end;
+
function TEIOS_Controller.FindClient(name: string): integer;
var
i: integer;