MODULE VMWareTools;
IMPORT
SYSTEM, Strings, Modules, KernelLog, WMWindowManager, WMMessages, Texts, TextUtilities, HostClipboard, Kernel;
TYPE
MouseGrabber= OBJECT
VAR
timer : Kernel.Timer;
alive : BOOLEAN;
t : LONGINT;
BEGIN {ACTIVE}
NEW(timer);
alive := TRUE;
WHILE alive DO
timer.Sleep(10);
t := ReadMouse();
END;
END MouseGrabber;
VAR
manager : WMWindowManager.WindowManager;
viewPort : WMWindowManager.ViewPort;
w, h : LONGINT;
hw : LONGINT;
oldGUIBits : SET;
mouseGrabber : MouseGrabber;
textbuffer : Strings.String;
PROCEDURE -ReadMouse() : LONGINT;
CODE {SYSTEM.i386}
MOV EAX, 564D5868H
MOV ECX, 4
MOV DX, 5658H
IN EAX, DX;
END ReadMouse;
PROCEDURE -WriteMouse(pos : LONGINT);
CODE {SYSTEM.i386}
MOV EAX, 564D5868H
POP EBX
MOV ECX, 5
MOV DX, 5658H
OUT DX, EAX;
END WriteMouse;
PROCEDURE -SendLength(l : LONGINT);
CODE {SYSTEM.i386}
MOV EAX, 564D5868H
POP EBX
MOV ECX, 8
MOV DX, 5658H
OUT DX, EAX;
END SendLength;
PROCEDURE -Send4Chars(chars : LONGINT);
CODE {SYSTEM.i386}
MOV EAX, 564D5868H
POP EBX
MOV ECX, 9
MOV DX, 5658H
OUT DX, EAX;
END Send4Chars;
PROCEDURE -ReceiveLength() : LONGINT;
CODE {SYSTEM.i386}
MOV EAX, 564D5868H
MOV ECX, 6
MOV DX, 5658H
IN EAX, DX;
END ReceiveLength;
PROCEDURE -Receive4Chars() : LONGINT;
CODE {SYSTEM.i386}
MOV EAX, 564D5868H
MOV ECX, 7
MOV DX, 5658H
IN EAX, DX
END Receive4Chars;
PROCEDURE -GetVirtualHWVersion() : LONGINT;
CODE {SYSTEM.i386}
MOV EAX, 564D5868H
MOV ECX, 11H
MOV DX, 5658H
IN EAX, DX
END GetVirtualHWVersion;
PROCEDURE -GetVMWareVersion() : LONGINT;
CODE {SYSTEM.i386}
MOV EAX, 564D5868H
MOV ECX, 0AH
MOV DX, 5658H
IN EAX, DX
MOV EAX, ECX
END GetVMWareVersion;
PROCEDURE -SetGUIOptions(options: SET);
CODE {SYSTEM.i386}
MOV EAX, 564D5868H
POP EBX
MOV ECX, 0EX
MOV DX, 5658H
OUT DX, EAX;
END SetGUIOptions;
PROCEDURE -GetGUIOptions(): SET;
CODE {SYSTEM.i386}
MOV EAX, 564D5868H
MOV ECX, 0DX
MOV DX, 5658H
IN EAX, DX;
END GetGUIOptions;
PROCEDURE SetMousePos(x, y : LONGINT);
VAR t : LONGINT;
BEGIN
WriteMouse(x * 10000H + y);
t := ReadMouse();
END SetMousePos;
PROCEDURE SetTextToClipBoard(CONST text : ARRAY OF CHAR);
VAR l, t, i: LONGINT;
BEGIN
l := Strings.Length(text);
SendLength(l);
t := 0;
FOR i := 0 TO (l - 1) DIV 4 DO
t := SYSTEM.GET32(SYSTEM.ADR(text[i * 4]));
Send4Chars(t);
END;
END SetTextToClipBoard;
PROCEDURE GetTextFromClipBoard(VAR s : Strings.String);
VAR l, t, i, f : LONGINT;
BEGIN
l := ReceiveLength();
IF (l > 0) & (l < 10000H) THEN
NEW(s, l + 5);
f := SYSTEM.ADR(s[0]);
FOR i := 0 TO (l - 1) DIV 4 DO
t := Receive4Chars();
SYSTEM.PUT32(f + i * 4, t);
END;
END
END GetTextFromClipBoard;
PROCEDURE GetFromClipboard(text : Texts.Text);
VAR s : Strings.String;
BEGIN
ASSERT((text # NIL) & (text.HasWriteLock()));
GetTextFromClipBoard(s);
IF (text.GetLength() > 0) THEN text.Delete(0, text.GetLength()); END;
TextUtilities.StrToText(text, 0, s^);
END GetFromClipboard;
PROCEDURE PutToClipboard(text : Texts.Text);
VAR buffer : Strings.String;
BEGIN
ASSERT((text # NIL) & (text.HasReadLock()));
TextUtilities.TextToStr(text, buffer^);
SetTextToClipBoard(buffer^);
END PutToClipboard;
PROCEDURE GetHostClipboard*;
VAR s : Strings.String;
BEGIN
GetTextFromClipBoard(s);
Texts.clipboard.AcquireWrite;
IF Texts.clipboard.GetLength() > 0 THEN Texts.clipboard.Delete(0, Texts.clipboard.GetLength()) END;
TextUtilities.StrToText(Texts.clipboard, 0, s^);
Texts.clipboard.ReleaseWrite;
KernelLog.String("Copied host clipboard context"); KernelLog.Ln;
END GetHostClipboard;
PROCEDURE ClipboardChanged(sender, data : ANY);
BEGIN
TextUtilities.TextToStr(Texts.clipboard, textbuffer^);
SetTextToClipBoard(textbuffer^);
END ClipboardChanged;
PROCEDURE MessagePreview(VAR m : WMMessages.Message; VAR discard : BOOLEAN);
BEGIN
IF m.msgType = WMMessages.MsgPointer THEN
SetMousePos(ENTIER((m.x - viewPort.range.l) * w / (viewPort.range.r - viewPort.range.l)) ,
ENTIER((m.y - viewPort.range.t) * h / (viewPort.range.b - viewPort.range.t)));
END
END MessagePreview;
PROCEDURE Install*;
END Install;
PROCEDURE Cleanup;
BEGIN
mouseGrabber.alive := FALSE;
mouseGrabber.timer.Wakeup;
SetGUIOptions({});
manager.RemoveMessagePreview(MessagePreview);
Texts.clipboard.onTextChanged.Remove(ClipboardChanged);
HostClipboard.SetHandlers(NIL, NIL);
END Cleanup;
BEGIN
KernelLog.String("Bimbo-VMWare Tools Installed"); KernelLog.Ln;
hw := GetVirtualHWVersion();
KernelLog.String("VMVare Version : "); KernelLog.Int(GetVMWareVersion(), 0); KernelLog.Ln;
KernelLog.String("Virtual Hardware Version : "); KernelLog.Int(hw, 0); KernelLog.Ln;
KernelLog.String("VMWare GUI Bits :");
oldGUIBits := GetGUIOptions();
KernelLog.Bits(oldGUIBits, 0, 32); KernelLog.Ln;
SetGUIOptions({0, 1, 2, 3, 4});
NEW(textbuffer, 65536 + 5);
Texts.clipboard.onTextChanged.Add(ClipboardChanged);
HostClipboard.SetHandlers(GetFromClipboard, PutToClipboard);
manager := WMWindowManager.GetDefaultManager();
viewPort := WMWindowManager.GetDefaultView();
w := viewPort.width0;
h := viewPort.height0;
manager.InstallMessagePreview(MessagePreview);
NEW(mouseGrabber);
Modules.InstallTermHandler(Cleanup);
END VMWareTools.
VMWareTools.Install ~
VMWareTools.GetHostClipboard ~
SystemTools.Free VMWareTools ~