MODULE WMInputMethods;
IMPORT
Streams, Strings, Configuration, Texts, TextUtilities, Commands, Modules;
CONST
CR = 0DX; LF = 0AX;
TYPE
IMEInterface* = RECORD
AcquireText*, ReleaseText* : PROCEDURE {DELEGATE};
InsertUCS32* : PROCEDURE {DELEGATE} (atPosition : LONGINT; CONST string : Texts.UCS32String);
GetCursorPosition* : PROCEDURE {DELEGATE} () : LONGINT;
GetCursorScreenPosition* : PROCEDURE {DELEGATE} (VAR x, y : LONGINT);
SetCursorInfo* : PROCEDURE {DELEGATE} (position : LONGINT);
END;
IME* = OBJECT
VAR
interface : IMEInterface;
valid : BOOLEAN;
PROCEDURE &Init*;
BEGIN
interface := None;
valid := FALSE;
END Init;
PROCEDURE GetName*() : Strings.String;
BEGIN
RETURN NIL
END GetName;
PROCEDURE SetInterface*(i : IMEInterface);
BEGIN {EXCLUSIVE}
ASSERT(
((i.AcquireText # NIL) & (i.ReleaseText # NIL) & (i.InsertUCS32 # NIL) &
(i.GetCursorPosition # NIL) & (i.GetCursorScreenPosition # NIL) & (i.SetCursorInfo # NIL))
OR
((i.AcquireText = NIL) & (i.ReleaseText = NIL) & (i.InsertUCS32 = NIL) &
(i.GetCursorPosition = NIL) & (i.GetCursorScreenPosition = NIL) & (i.SetCursorInfo = NIL))
);
SELF.interface := i;
valid := interface.AcquireText # NIL;
END SetInterface;
PROCEDURE InsertChar*(ucs : LONGINT);
VAR buf : ARRAY 2 OF Texts.Char32;
BEGIN {EXCLUSIVE}
IF valid THEN
interface.AcquireText;
interface.SetCursorInfo(1);
buf[0] := ucs; buf[1] := 0;
interface.InsertUCS32(interface.GetCursorPosition(), buf);
interface.ReleaseText;
END;
END InsertChar;
PROCEDURE InsertMultiChar*(CONST ucs : ARRAY OF LONGINT);
VAR buf : ARRAY 2 OF Texts.Char32; pos, i : LONGINT;
BEGIN {EXCLUSIVE}
IF valid THEN
interface.AcquireText;
pos := interface.GetCursorPosition();
interface.SetCursorInfo(LEN(ucs));
buf[1] := 0;
FOR i := 0 TO LEN(ucs) - 1 DO
buf[0] := ucs[i];
interface.InsertUCS32(pos, buf);
END;
interface.ReleaseText;
END;
END InsertMultiChar;
PROCEDURE InsertUTF8String*(CONST string : ARRAY OF CHAR);
VAR r : Streams.StringReader;
pos, i, m: LONGINT;
tempUCS32 : ARRAY 1024 OF Texts.Char32;
ch, last : Texts.Char32;
BEGIN {EXCLUSIVE}
IF valid THEN
interface.AcquireText;
pos := interface.GetCursorPosition();
NEW(r, LEN(string));
m := LEN(tempUCS32) - 1;
r.Set(string);
i := 0;
REPEAT
IF TextUtilities.GetUTF8Char(r, ch) THEN
IF i = m THEN tempUCS32[i] := 0; interface.InsertUCS32(pos, tempUCS32); INC(pos, m); i := 0 END;
IF (last # ORD(CR)) OR (ch # ORD(LF)) THEN
IF ch = ORD(CR) THEN tempUCS32[i] := ORD(LF)
ELSE tempUCS32[i] := ch
END;
INC(i)
END;
last := ch
END
UNTIL (r.res # Streams.Ok);
tempUCS32[i] := 0; interface.InsertUCS32(pos, tempUCS32);
interface.ReleaseText;
END;
END InsertUTF8String;
PROCEDURE GetCursorScreenPosition*(VAR x, y : LONGINT);
BEGIN {EXCLUSIVE}
IF valid THEN
interface.GetCursorScreenPosition(x, y);
ELSE
x := 0; y := 0;
END;
END GetCursorScreenPosition;
PROCEDURE KeyEvent*(ucs : LONGINT; flags : SET; keysym : LONGINT);
END KeyEvent;
PROCEDURE Hide*;
END Hide;
PROCEDURE Finalize*;
BEGIN
SetInterface(None);
END Finalize;
END IME;
IMEInstaller* = PROCEDURE;
IMToolSwitchCallback* = PROCEDURE;
VAR
defaultIME- : IME;
activeIME- : IME;
toolSwitch* : IMToolSwitchCallback;
None- : IMEInterface;
PROCEDURE GetIME*(CONST name : ARRAY OF CHAR; VAR res : LONGINT) : IMEInstaller;
VAR
config, installerName, msg : ARRAY 128 OF CHAR;
moduleName, procedureName : Modules.Name;
installer : IMEInstaller;
BEGIN
res := -1;
config := "IME."; Strings.Append(config,name);
Configuration.Get(config,installerName,res);
IF (res = 0) THEN
Commands.Split(installerName, moduleName, procedureName, res, msg);
END;
IF (res = 0) THEN
GETPROCEDURE(moduleName,procedureName,installer);
END;
RETURN installer;
END GetIME;
PROCEDURE SwitchIME*() : IME;
BEGIN
IF activeIME = NIL THEN
activeIME := defaultIME;
ELSE
activeIME := NIL;
END;
IF toolSwitch # NIL THEN
toolSwitch;
END;
RETURN activeIME
END SwitchIME;
PROCEDURE InstallIME*(newIME : IME);
BEGIN
defaultIME := newIME;
IF (activeIME # NIL) THEN
activeIME := newIME;
END;
END InstallIME;
BEGIN
None.AcquireText := NIL; None.ReleaseText := NIL; None.InsertUCS32 := NIL;
None.GetCursorPosition := NIL; None.GetCursorScreenPosition := NIL;
END WMInputMethods.