Browse Source

* updated ptc and ptcgraph to the latest trunk (future 0.99.15 release) from sourceforge

git-svn-id: trunk@36507 -
nickysn 8 years ago
parent
commit
f2587b6061
49 changed files with 7424 additions and 1699 deletions
  1. 4 1
      .gitattributes
  2. 226 8
      packages/graph/src/ptcgraph/ptcgraph.pp
  3. 88 0
      packages/ptc/docs/CHANGES.txt
  4. 7 4
      packages/ptc/docs/INSTALL.txt
  5. 1 1
      packages/ptc/docs/README.txt
  6. 135 3
      packages/ptc/examples/keyboard3.pp
  7. 0 1
      packages/ptc/fpmake.pp
  8. 4 1
      packages/ptc/src/core/baseconsoled.inc
  9. 10 1
      packages/ptc/src/core/baseconsolei.inc
  10. 8 1
      packages/ptc/src/core/consolei.inc
  11. 1 1
      packages/ptc/src/core/errori.inc
  12. 7 2
      packages/ptc/src/core/keyeventd.inc
  13. 32 6
      packages/ptc/src/core/mouseeventd.inc
  14. 0 1299
      packages/ptc/src/dos/base/go32fix.pp
  15. 1 1
      packages/ptc/src/dos/timeunit/timeunit.pp
  16. 5 2
      packages/ptc/src/ptc.pp
  17. 240 0
      packages/ptc/src/ptclaz.lpi
  18. 6 0
      packages/ptc/src/ptclaz.lpr
  19. 6 0
      packages/ptc/src/ptcpas.cfg
  20. 13 4
      packages/ptc/src/win32/base/win32hook.inc
  21. 90 43
      packages/ptc/src/win32/base/win32kbd.inc
  22. 1 6
      packages/ptc/src/win32/base/win32kbdd.inc
  23. 2 1
      packages/ptc/src/win32/base/win32moused.inc
  24. 85 13
      packages/ptc/src/win32/base/win32mousei.inc
  25. 160 52
      packages/ptc/src/win32/base/win32window.inc
  26. 3 1
      packages/ptc/src/win32/base/win32windowd.inc
  27. 1 1
      packages/ptc/src/win32/directx/p_ddraw.pp
  28. 4829 0
      packages/ptc/src/win32/directx/p_dinput.pp
  29. 2 1
      packages/ptc/src/win32/directx/win32directxconsoled.inc
  30. 8 2
      packages/ptc/src/win32/directx/win32directxconsolei.inc
  31. 3 3
      packages/ptc/src/win32/directx/win32directxdisplay.inc
  32. 12 12
      packages/ptc/src/win32/directx/win32directxhook.inc
  33. 5 3
      packages/ptc/src/win32/gdi/win32gdiconsoled.inc
  34. 9 3
      packages/ptc/src/win32/gdi/win32gdiconsolei.inc
  35. 2 2
      packages/ptc/src/win32/gdi/win32openglwindowd.inc
  36. 2 2
      packages/ptc/src/win32/gdi/win32openglwindowi.inc
  37. 4 1
      packages/ptc/src/x11/x11consoled.inc
  38. 51 2
      packages/ptc/src/x11/x11consolei.inc
  39. 2 1
      packages/ptc/src/x11/x11dga1displayd.inc
  40. 7 1
      packages/ptc/src/x11/x11dga1displayi.inc
  41. 2 1
      packages/ptc/src/x11/x11dga2displayd.inc
  42. 7 1
      packages/ptc/src/x11/x11dga2displayi.inc
  43. 11 1
      packages/ptc/src/x11/x11displayd.inc
  44. 56 6
      packages/ptc/src/x11/x11displayi.inc
  45. 1 0
      packages/ptc/src/x11/x11extensions.inc
  46. 734 197
      packages/ptc/src/x11/x11unikey.inc
  47. 11 1
      packages/ptc/src/x11/x11windowdisplayd.inc
  48. 408 6
      packages/ptc/src/x11/x11windowdisplayi.inc
  49. 122 0
      packages/ptc/tests/event.pp

+ 4 - 1
.gitattributes

@@ -6923,7 +6923,6 @@ packages/ptc/src/core/surfaced.inc svneol=native#text/plain
 packages/ptc/src/core/surfacei.inc svneol=native#text/plain
 packages/ptc/src/core/surfacei.inc svneol=native#text/plain
 packages/ptc/src/core/timerd.inc svneol=native#text/plain
 packages/ptc/src/core/timerd.inc svneol=native#text/plain
 packages/ptc/src/core/timeri.inc svneol=native#text/plain
 packages/ptc/src/core/timeri.inc svneol=native#text/plain
-packages/ptc/src/dos/base/go32fix.pp svneol=native#text/plain
 packages/ptc/src/dos/base/kbd.inc svneol=native#text/plain
 packages/ptc/src/dos/base/kbd.inc svneol=native#text/plain
 packages/ptc/src/dos/base/kbdd.inc svneol=native#text/plain
 packages/ptc/src/dos/base/kbdd.inc svneol=native#text/plain
 packages/ptc/src/dos/base/mouse33h.pp svneol=native#text/plain
 packages/ptc/src/dos/base/mouse33h.pp svneol=native#text/plain
@@ -6944,6 +6943,8 @@ packages/ptc/src/dos/vga/vga.pp svneol=native#text/plain
 packages/ptc/src/dos/vga/vgaconsoled.inc svneol=native#text/plain
 packages/ptc/src/dos/vga/vgaconsoled.inc svneol=native#text/plain
 packages/ptc/src/dos/vga/vgaconsolei.inc svneol=native#text/plain
 packages/ptc/src/dos/vga/vgaconsolei.inc svneol=native#text/plain
 packages/ptc/src/ptc.pp svneol=native#text/plain
 packages/ptc/src/ptc.pp svneol=native#text/plain
+packages/ptc/src/ptclaz.lpi svneol=native#text/plain
+packages/ptc/src/ptclaz.lpr svneol=native#text/plain
 packages/ptc/src/ptcpas.cfg svneol=native#text/plain
 packages/ptc/src/ptcpas.cfg svneol=native#text/plain
 packages/ptc/src/ptcwrapper/ptceventqueue.pp svneol=native#text/plain
 packages/ptc/src/ptcwrapper/ptceventqueue.pp svneol=native#text/plain
 packages/ptc/src/ptcwrapper/ptcwrapper.pp svneol=native#text/plain
 packages/ptc/src/ptcwrapper/ptcwrapper.pp svneol=native#text/plain
@@ -6969,6 +6970,7 @@ packages/ptc/src/win32/base/win32window.inc svneol=native#text/plain
 packages/ptc/src/win32/base/win32windowd.inc svneol=native#text/plain
 packages/ptc/src/win32/base/win32windowd.inc svneol=native#text/plain
 packages/ptc/src/win32/base/windows.ico -text
 packages/ptc/src/win32/base/windows.ico -text
 packages/ptc/src/win32/directx/p_ddraw.pp svneol=native#text/plain
 packages/ptc/src/win32/directx/p_ddraw.pp svneol=native#text/plain
+packages/ptc/src/win32/directx/p_dinput.pp svneol=native#text/plain
 packages/ptc/src/win32/directx/win32directxcheck.inc svneol=native#text/plain
 packages/ptc/src/win32/directx/win32directxcheck.inc svneol=native#text/plain
 packages/ptc/src/win32/directx/win32directxconsoled.inc svneol=native#text/plain
 packages/ptc/src/win32/directx/win32directxconsoled.inc svneol=native#text/plain
 packages/ptc/src/win32/directx/win32directxconsolei.inc svneol=native#text/plain
 packages/ptc/src/win32/directx/win32directxconsolei.inc svneol=native#text/plain
@@ -7028,6 +7030,7 @@ packages/ptc/src/x11/x11windowdisplayd.inc svneol=native#text/plain
 packages/ptc/src/x11/x11windowdisplayi.inc svneol=native#text/plain
 packages/ptc/src/x11/x11windowdisplayi.inc svneol=native#text/plain
 packages/ptc/tests/convtest.pp svneol=native#text/plain
 packages/ptc/tests/convtest.pp svneol=native#text/plain
 packages/ptc/tests/endian.inc svneol=native#text/plain
 packages/ptc/tests/endian.inc svneol=native#text/plain
+packages/ptc/tests/event.pp svneol=native#text/plain
 packages/ptc/tests/view.pp svneol=native#text/plain
 packages/ptc/tests/view.pp svneol=native#text/plain
 packages/pthreads/Makefile svneol=native#text/plain
 packages/pthreads/Makefile svneol=native#text/plain
 packages/pthreads/Makefile.fpc svneol=native#text/plain
 packages/pthreads/Makefile.fpc svneol=native#text/plain

+ 226 - 8
packages/graph/src/ptcgraph/ptcgraph.pp

@@ -120,6 +120,7 @@ const
   FullscreenGraph: Boolean = False;
   FullscreenGraph: Boolean = False;
 
 
 var
 var
+  WindowTitle: AnsiString;
   PTCWrapperObject: TPTCWrapperThread;
   PTCWrapperObject: TPTCWrapperThread;
 
 
 {******************************************************************************}
 {******************************************************************************}
@@ -128,6 +129,8 @@ var
 
 
 const
 const
   InternalDriverName = 'PTCPas';
   InternalDriverName = 'PTCPas';
+  FirstNonStandardModeNumber = $200;
+  NonStandardModeNumberMaxLimit = $7FFF;
 
 
 var
 var
   Has320x200: Boolean;
   Has320x200: Boolean;
@@ -617,7 +620,7 @@ begin
   LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 16 colours');
   LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 16 colours');
 {$ENDIF logging}
 {$ENDIF logging}
   { open the console }
   { open the console }
-  ptc_InternalOpen(ParamStr(0), XResolution, YResolution, PTCFormat8, Pages);
+  ptc_InternalOpen(WindowTitle, XResolution, YResolution, PTCFormat8, Pages);
   PTCWidth := XResolution;
   PTCWidth := XResolution;
   PTCHeight := YResolution;
   PTCHeight := YResolution;
   CurrentActivePage := 0;
   CurrentActivePage := 0;
@@ -642,7 +645,7 @@ begin
   LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 256 colours');
   LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 256 colours');
 {$ENDIF logging}
 {$ENDIF logging}
   { open the console }
   { open the console }
-  ptc_InternalOpen(ParamStr(0), XResolution, YResolution, PTCFormat8, Pages);
+  ptc_InternalOpen(WindowTitle, XResolution, YResolution, PTCFormat8, Pages);
   PTCWidth := XResolution;
   PTCWidth := XResolution;
   PTCHeight := YResolution;
   PTCHeight := YResolution;
   CurrentActivePage := 0;
   CurrentActivePage := 0;
@@ -657,7 +660,7 @@ begin
   LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 4 colours, palette ' + strf(CGAPalette));
   LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 4 colours, palette ' + strf(CGAPalette));
 {$ENDIF logging}
 {$ENDIF logging}
   { open the console }
   { open the console }
-  ptc_InternalOpen(ParamStr(0), XResolution, YResolution, PTCFormat8, 1);
+  ptc_InternalOpen(WindowTitle, XResolution, YResolution, PTCFormat8, 1);
   PTCWidth := XResolution;
   PTCWidth := XResolution;
   PTCHeight := YResolution;
   PTCHeight := YResolution;
   CurrentActivePage := 0;
   CurrentActivePage := 0;
@@ -672,7 +675,7 @@ begin
   LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 2 colours');
   LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 2 colours');
 {$ENDIF logging}
 {$ENDIF logging}
   { open the console }
   { open the console }
-  ptc_InternalOpen(ParamStr(0), XResolution, YResolution, PTCFormat8, Pages);
+  ptc_InternalOpen(WindowTitle, XResolution, YResolution, PTCFormat8, Pages);
   PTCWidth := XResolution;
   PTCWidth := XResolution;
   PTCHeight := YResolution;
   PTCHeight := YResolution;
   CurrentActivePage := 0;
   CurrentActivePage := 0;
@@ -687,7 +690,7 @@ begin
   LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 2 colours');
   LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 2 colours');
 {$ENDIF logging}
 {$ENDIF logging}
   { open the console }
   { open the console }
-  ptc_InternalOpen(ParamStr(0), XResolution, YResolution, PTCFormat8, Pages);
+  ptc_InternalOpen(WindowTitle, XResolution, YResolution, PTCFormat8, Pages);
   PTCWidth := XResolution;
   PTCWidth := XResolution;
   PTCHeight := YResolution;
   PTCHeight := YResolution;
   CurrentActivePage := 0;
   CurrentActivePage := 0;
@@ -702,7 +705,7 @@ begin
   LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 32768 colours');
   LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 32768 colours');
 {$ENDIF logging}
 {$ENDIF logging}
   { open the console }
   { open the console }
-  ptc_InternalOpen(ParamStr(0), XResolution, YResolution, PTCFormat15, Pages);
+  ptc_InternalOpen(WindowTitle, XResolution, YResolution, PTCFormat15, Pages);
   PTCWidth := XResolution;
   PTCWidth := XResolution;
   PTCHeight := YResolution;
   PTCHeight := YResolution;
   CurrentActivePage := 0;
   CurrentActivePage := 0;
@@ -715,7 +718,7 @@ begin
   LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 65536 colours');
   LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 65536 colours');
 {$ENDIF logging}
 {$ENDIF logging}
   { open the console }
   { open the console }
-  ptc_InternalOpen(ParamStr(0), XResolution, YResolution, PTCFormat16, Pages);
+  ptc_InternalOpen(WindowTitle, XResolution, YResolution, PTCFormat16, Pages);
   PTCWidth := XResolution;
   PTCWidth := XResolution;
   PTCHeight := YResolution;
   PTCHeight := YResolution;
   CurrentActivePage := 0;
   CurrentActivePage := 0;
@@ -869,6 +872,26 @@ begin
   ptc_InitMode64k(1280, 1024, 2);
   ptc_InitMode64k(1280, 1024, 2);
 end;
 end;
 
 
+procedure ptc_InitNonStandard16;
+begin
+  ptc_InitMode16(MaxX + 1, MaxY + 1, 2);
+end;
+
+procedure ptc_InitNonStandard256;
+begin
+  ptc_InitMode256(MaxX + 1, MaxY + 1, 2);
+end;
+
+procedure ptc_InitNonStandard32k;
+begin
+  ptc_InitMode32k(MaxX + 1, MaxY + 1, 2);
+end;
+
+procedure ptc_InitNonStandard64k;
+begin
+  ptc_InitMode64k(MaxX + 1, MaxY + 1, 2);
+end;
+
 procedure ptc_SetVisualPage(page: word);
 procedure ptc_SetVisualPage(page: word);
 begin
 begin
   if page > HardwarePages then
   if page > HardwarePages then
@@ -1409,8 +1432,64 @@ end;
       ContainsAtLeast := False;
       ContainsAtLeast := False;
     end;
     end;
 
 
+    function IsNonStandardResolution(AWidth, AHeight: Integer): Boolean;
+    begin
+      IsNonStandardResolution :=
+            not ((AWidth =  320) and (AHeight =  200))
+        and not ((AWidth =  640) and (AHeight =  200))
+        and not ((AWidth =  640) and (AHeight =  350))
+        and not ((AWidth =  640) and (AHeight =  400))
+        and not ((AWidth =  640) and (AHeight =  480))
+        and not ((AWidth =  720) and (AHeight =  348))
+        and not ((AWidth =  800) and (AHeight =  600))
+        and not ((AWidth = 1024) and (AHeight =  768))
+        and not ((AWidth = 1280) and (AHeight = 1024));
+    end;
+
+    function CompareModes(AMode1, AMode2: IPTCMode): Boolean;
+    begin
+      if AMode1.Width <> AMode2.Width then
+        CompareModes := AMode1.Width < AMode2.Width
+      else if AMode1.Height <> AMode2.Height then
+        CompareModes := AMode1.Height < AMode2.Height
+      else if AMode1.Format.Bits <> AMode2.Format.Bits then
+        CompareModes := AMode1.Format.Bits < AMode2.Format.Bits
+      else
+        CompareModes := PtrUInt(AMode1) < PtrUInt(AMode2);
+    end;
+
+    procedure SortModes(l,r: longint);
+      var
+         i,j: longint;
+         x,y: IPTCMode;
+      begin
+         i:=l;
+         j:=r;
+         x:=PTCModeList[(l+r) div 2];
+         repeat
+           while CompareModes(PTCModeList[i], x) do
+            inc(i);
+           while CompareModes(x, PTCModeList[j]) do
+            dec(j);
+           if not(i>j) then
+             begin
+                y:=PTCModeList[i];
+                PTCModeList[i]:=PTCModeList[j];
+                PTCModeList[j]:=y;
+                inc(i);
+                j:=j-1;
+             end;
+         until i>j;
+         if l<j then
+           SortModes(l,j);
+         if i<r then
+           SortModes(i,r);
+      end;
+
    var
    var
     graphmode:Tmodeinfo;
     graphmode:Tmodeinfo;
+    I: Integer;
+    NextNonStandardModeNumber: SmallInt;
    begin
    begin
      QueryAdapterInfo := ModeList;
      QueryAdapterInfo := ModeList;
      { If the mode listing already exists... }
      { If the mode listing already exists... }
@@ -1419,7 +1498,8 @@ end;
      if assigned(ModeList) then
      if assigned(ModeList) then
        exit;
        exit;
 
 
-     PTCModeList := PTCWrapperObject.Modes;
+     PTCModeList := Copy(PTCWrapperObject.Modes);
+     SortModes(Low(PTCModeList), High(PTCModeList));
 
 
      Has320x200 := ContainsExactResolution(320, 200);
      Has320x200 := ContainsExactResolution(320, 200);
      Has320x240 := ContainsExactResolution(320, 240);
      Has320x240 := ContainsExactResolution(320, 240);
@@ -2567,9 +2647,147 @@ end;
        end;
        end;
        AddMode(graphmode);
        AddMode(graphmode);
      end;
      end;
+
+     { finally, add all the non-standard (i.e. not VESA or classic PC) modes }
+     NextNonStandardModeNumber := FirstNonStandardModeNumber;
+     for I := Low(PTCModeList) to High(PTCModeList) do
+       with PTCModeList[I] do
+         if IsNonStandardResolution(Width, Height) and
+            ((I = Low(PTCModeList)) or ((Width <> PTCModeList[I-1].Width) or (Height <> PTCModeList[I-1].Height))) then
+         begin
+           InitMode(graphmode);
+           with graphmode do
+           begin
+             ModeNumber := NextNonStandardModeNumber;
+             DriverNumber := VESA;
+             HardwarePages := 1;
+             WriteStr(ModeName, Width, ' x ', Height, ' VESA');
+             MaxColor := 16;
+             DirectColor := FALSE;
+             PaletteSize := MaxColor;
+             MaxX := Width - 1;
+             MaxY := Height - 1;
+             InitMode       := @ptc_InitNonStandard16;
+             DirectPutPixel := @ptc_DirectPixelProc_8bpp;
+             PutPixel       := @ptc_PutPixelProc_8bpp;
+             GetPixel       := @ptc_GetPixelProc_8bpp;
+             SetRGBPalette  := @ptc_SetRGBPaletteProc;
+             GetRGBPalette  := @ptc_GetRGBPaletteProc;
+
+             HLine          := @ptc_HLineProc_8bpp;
+             VLine          := @ptc_VLineProc_8bpp;
+
+             SetVisualPage  := @ptc_SetVisualPage;
+             SetActivePage  := @ptc_SetActivePage;
+
+             XAspect := 10000;
+             YAspect := 10000;
+           end;
+           AddMode(graphmode);
+           Inc(NextNonStandardModeNumber);
+           if NextNonStandardModeNumber > NonStandardModeNumberMaxLimit then
+             break;
+
+           InitMode(graphmode);
+           with graphmode do
+           begin
+             ModeNumber := NextNonStandardModeNumber;
+             DriverNumber := VESA;
+             HardwarePages := 1;
+             WriteStr(ModeName, Width, ' x ', Height, ' VESA');
+             MaxColor := 256;
+             DirectColor := FALSE;
+             PaletteSize := MaxColor;
+             MaxX := Width - 1;
+             MaxY := Height - 1;
+             InitMode       := @ptc_InitNonStandard256;
+             DirectPutPixel := @ptc_DirectPixelProc_8bpp;
+             PutPixel       := @ptc_PutPixelProc_8bpp;
+             GetPixel       := @ptc_GetPixelProc_8bpp;
+             SetRGBPalette  := @ptc_SetRGBPaletteProc;
+             GetRGBPalette  := @ptc_GetRGBPaletteProc;
+             //SetAllPalette  := @ptc_SetRGBAllPaletteProc;
+
+             HLine          := @ptc_HLineProc_8bpp;
+             VLine          := @ptc_VLineProc_8bpp;
+
+             SetVisualPage  := @ptc_SetVisualPage;
+             SetActivePage  := @ptc_SetActivePage;
+
+             XAspect := 10000;
+             YAspect := 10000;
+           end;
+           AddMode(graphmode);
+           Inc(NextNonStandardModeNumber);
+           if NextNonStandardModeNumber > NonStandardModeNumberMaxLimit then
+             break;
+
+           InitMode(graphmode);
+           with graphmode do
+           begin
+             ModeNumber := NextNonStandardModeNumber;
+             DriverNumber := VESA;
+             HardwarePages := 1;
+             WriteStr(ModeName, Width, ' x ', Height, ' VESA');
+             MaxColor := 32768;
+             DirectColor := TRUE;
+             PaletteSize := MaxColor;
+             MaxX := Width - 1;
+             MaxY := Height - 1;
+             InitMode       := @ptc_InitNonStandard32k;
+             DirectPutPixel := @ptc_DirectPixelProc_16bpp;
+             PutPixel       := @ptc_PutPixelProc_16bpp;
+             GetPixel       := @ptc_GetPixelProc_16bpp;
+             SetRGBPalette  := @ptc_SetRGBPaletteProc;
+             GetRGBPalette  := @ptc_GetRGBPaletteProc;
+             HLine          := @ptc_HLineProc_16bpp;
+             VLine          := @ptc_VLineProc_16bpp;
+             SetVisualPage  := @ptc_SetVisualPage;
+             SetActivePage  := @ptc_SetActivePage;
+
+             XAspect := 10000;
+             YAspect := 10000;
+           end;
+           AddMode(graphmode);
+           Inc(NextNonStandardModeNumber);
+           if NextNonStandardModeNumber > NonStandardModeNumberMaxLimit then
+             break;
+
+           InitMode(graphmode);
+           with graphmode do
+           begin
+             ModeNumber := NextNonStandardModeNumber;
+             DriverNumber := VESA;
+             HardwarePages := 1;
+             WriteStr(ModeName, Width, ' x ', Height, ' VESA');
+             MaxColor := 65536;
+             DirectColor := TRUE;
+             PaletteSize := MaxColor;
+             MaxX := Width - 1;
+             MaxY := Height - 1;
+             InitMode       := @ptc_InitNonStandard64k;
+             DirectPutPixel := @ptc_DirectPixelProc_16bpp;
+             PutPixel       := @ptc_PutPixelProc_16bpp;
+             GetPixel       := @ptc_GetPixelProc_16bpp;
+             SetRGBPalette  := @ptc_SetRGBPaletteProc;
+             GetRGBPalette  := @ptc_GetRGBPaletteProc;
+             HLine          := @ptc_HLineProc_16bpp;
+             VLine          := @ptc_VLineProc_16bpp;
+             SetVisualPage  := @ptc_SetVisualPage;
+             SetActivePage  := @ptc_SetActivePage;
+
+             XAspect := 10000;
+             YAspect := 10000;
+           end;
+           AddMode(graphmode);
+           Inc(NextNonStandardModeNumber);
+           if NextNonStandardModeNumber > NonStandardModeNumberMaxLimit then
+             break;
+         end;
   end;
   end;
 
 
 initialization
 initialization
+  WindowTitle := ParamStr(0);
   PTCFormat8 := TPTCFormatFactory.CreateNew(8);
   PTCFormat8 := TPTCFormatFactory.CreateNew(8);
   PTCFormat15 := TPTCFormatFactory.CreateNew(16, $7C00, $03E0, $001F);
   PTCFormat15 := TPTCFormatFactory.CreateNew(16, $7C00, $03E0, $001F);
   PTCFormat16 := TPTCFormatFactory.CreateNew(16, $F800, $07E0, $001F);
   PTCFormat16 := TPTCFormatFactory.CreateNew(16, $F800, $07E0, $001F);

+ 88 - 0
packages/ptc/docs/CHANGES.txt

@@ -1,3 +1,91 @@
+0.99.15
+ - dead key support under Windows and X11 (via XIM)
+ - more character scripts (Latin 2, Latin 3, Latin 4, Latin 9, Katakana,
+   Arabic, Greek with diacritics, Technical, Special, Publishing, APL, Hebrew,
+   Thai, Currency signs - Korean Won sign and Euro sign) are now recognized and
+   converted to Unicode in the X11 console. Previously only Latin 1, Greek
+   without diacritics and Cyrillic were supported, but even they didn't work in
+   recent ptcpas versions, due to regressions, which are now fixed as well.
+ - use an alternative method (via GetKeyState) for obtaining the Alt, Shift and
+   Control key modifier status under Windows; This eliminates a problem, where
+   the alt key appears "stuck", after alt-tabbing away from the application,
+   then focusing back to it with a mouse click.
+ - new key modifiers added for distinguishing between left and right shift,
+   control and alt, the status of num lock, caps lock and scroll lock and for
+   distinguishing numpad keys and dead keys. All of them are implemented as
+   elements in the ModifierKeys set, which was added to IPTCKeyEvent. They can
+   be checked, for example, with:
+     if pmkNumLockActive in key_event.ModifierKeys then
+       ...
+   The following modifiers are available:
+     pmkAlt, pmkShift, pmkControl, pmkLeftAlt, pmkRightAlt, pmkLeftShift,
+     pmkRightShift, pmkLeftControl, pmkRightControl, pmkNumLockActive,
+     pmkNumLockPressed, pmkCapsLockActive, pmkCapsLockPressed,
+     pmkScrollLockActive, pmkScrollLockPressed, pmkNumPadKey, pmkDeadKey
+ - there is now a MoveMouseTo method, added to the console. It can be used to
+   warp the mouse cursor to a different location.
+ - added support for a relative mouse mode. It supports continuous mouse
+   motion, not limited within the boundaries of the current window. It is
+   usually used with an invisible cursor. It is activated with the
+   'relative mouse on' console option, and turned off with the option
+   'relative mouse off'.
+ - the number of mouse buttons supported has been increased to 31. There is now
+   support for a horizontal and a vertical mouse wheel, which are treated as
+   buttons. Overall, this is the default button arrangement:
+     PTCMouseButton1  - left mouse button
+     PTCMouseButton2  - right mouse button
+     PTCMouseButton3  - middle mouse button
+     PTCMouseButton4  - mouse wheel rotated forward (scroll up)
+     PTCMouseButton5  - mouse wheel rotated backward (scroll down)
+     PTCMouseButton6  - mouse horizontal scroll wheel rotated left
+     PTCMouseButton7  - mouse horizontal scroll wheel rotated right
+     PTCMouseButton8  - "back" button ("X button 1")
+     PTCMouseButton9  - "forward" button ("X button 2")
+   The remaining mouse buttons are hardware specific and will vary, depending
+   on the actual mouse (provided it has that many buttons at all).
+ - ptcgraph now has a global string variable WindowTitle, which allows you to
+   set the window title, before calling InitGraph
+ - ptcgraph was extended to also support resolutions, different than the ones,
+   defined by VESA. This means that you can now use ptcgraph with resolutions,
+   higher than 1280x1024 and widescreen (e.g. 16:9 or 16:10) aspect ratios, as
+   long as they are supported by the display. For this, you need to call
+   QueryAdapterInfo and walk through the linked list of modes, to choose a
+   mode, then pass its DriverNumber and ModeNumber to InitGraph. Here's an
+   example:
+
+uses
+  ptcgraph, ptccrt;
+var
+  m: PModeInfo;
+  gd, gm: Integer;
+begin
+  Writeln('List of all modes:');
+  m := QueryAdapterInfo;
+  while m <> nil do
+  begin
+    Writeln(m^.MaxX+1, ' x ', m^.MaxY+1, ' x ', m^.MaxColor);
+    m := m^.next;
+  end;
+
+  Writeln('Now let''s find 1920x1080 with 16-bit colour...');
+  m := QueryAdapterInfo;
+  while m <> nil do
+  begin
+    if (m^.MaxX = (1920-1)) and (m^.MaxY = (1080-1)) and (m^.MaxColor = 65536) then
+    begin
+      InitGraph(m^.DriverNumber, m^.ModeNumber, '');
+      SetColor($FFFF);
+      OutTextXY(0, 0, 'Hurrah! Full HD 1920x1080 mode is available!');
+      ReadKey;
+      CloseGraph;
+      Halt;
+    end;
+    m := m^.next;
+  end;
+
+  Writeln('Mode not found in list!');
+end.
+
 0.99.14.1
 0.99.14.1
  - fixed X11 middle and right mouse button mapping. Previously, the right mouse
  - fixed X11 middle and right mouse button mapping. Previously, the right mouse
    button and the middle mouse button were swapped, compared to Windows and DOS
    button and the middle mouse button were swapped, compared to Windows and DOS

+ 7 - 4
packages/ptc/docs/INSTALL.txt

@@ -1,13 +1,16 @@
-The supported platforms are Linux, FreeBSD, Windows, Windows Mobile and DOS.
+The supported platforms are Linux, FreeBSD, Windows, Windows Mobile and 32-bit
+DOS (go32v2).
 
 
 Generally you need the latest stable version of the Free Pascal Compiler, which
 Generally you need the latest stable version of the Free Pascal Compiler, which
-currently means version 2.6.2.
+currently means version 3.0.4. Note that Windows 95/98/ME and NT 4.0 are still
+supported, when this library is compiled with FPC 2.6.4. However, using
+FPC 2.6.4 isn't guaranteed to work for any other platforms, besides Windows.
 
 
  - Compiling the library:
  - Compiling the library:
 Before starting make sure the FPCDIR environment variable is set correctly.
 Before starting make sure the FPCDIR environment variable is set correctly.
-For example: (windows, fpc version 2.6.2, default install dir)
+For example: (windows, fpc version 3.0.4, default install dir)
 
 
-  set FPCDIR=c:\fpc\2.6.2
+  set FPCDIR=c:\fpc\3.0.4
 
 
 To compile the library type:
 To compile the library type:
 
 

+ 1 - 1
packages/ptc/docs/README.txt

@@ -1,4 +1,4 @@
-PTCPas 0.99.14.1
+PTCPas 0.99.15
 Nikolay Nikolov ([email protected])
 Nikolay Nikolov ([email protected])
 
 
 PTCPas is a free, portable framebuffer library, written in Free Pascal. It is
 PTCPas is a free, portable framebuffer library, written in Free Pascal. It is

+ 135 - 3
packages/ptc/examples/keyboard3.pp

@@ -10,11 +10,143 @@ program KeyboardExample3;
 uses
 uses
   ptc;
   ptc;
 
 
+function KeyCode2String(ACode: Integer): string;
+begin
+  case ACode of
+    PTCKEY_UNDEFINED    : Result := 'PTCKEY_UNDEFINED';
+    PTCKEY_CANCEL       : Result := 'PTCKEY_CANCEL';
+    PTCKEY_BACKSPACE    : Result := 'PTCKEY_BACKSPACE';
+    PTCKEY_TAB          : Result := 'PTCKEY_TAB';
+    PTCKEY_ENTER        : Result := 'PTCKEY_ENTER';
+    PTCKEY_CLEAR        : Result := 'PTCKEY_CLEAR';
+    PTCKEY_SHIFT        : Result := 'PTCKEY_SHIFT';
+    PTCKEY_CONTROL      : Result := 'PTCKEY_CONTROL';
+    PTCKEY_ALT          : Result := 'PTCKEY_ALT';
+    PTCKEY_PAUSE        : Result := 'PTCKEY_PAUSE';
+    PTCKEY_CAPSLOCK     : Result := 'PTCKEY_CAPSLOCK';
+    PTCKEY_KANA         : Result := 'PTCKEY_KANA';
+    PTCKEY_FINAL        : Result := 'PTCKEY_FINAL';
+    PTCKEY_KANJI        : Result := 'PTCKEY_KANJI';
+    PTCKEY_ESCAPE       : Result := 'PTCKEY_ESCAPE';
+    PTCKEY_CONVERT      : Result := 'PTCKEY_CONVERT';
+    PTCKEY_NONCONVERT   : Result := 'PTCKEY_NONCONVERT';
+    PTCKEY_ACCEPT       : Result := 'PTCKEY_ACCEPT';
+    PTCKEY_MODECHANGE   : Result := 'PTCKEY_MODECHANGE';
+    PTCKEY_SPACE        : Result := 'PTCKEY_SPACE';
+    PTCKEY_PAGEUP       : Result := 'PTCKEY_PAGEUP';
+    PTCKEY_PAGEDOWN     : Result := 'PTCKEY_PAGEDOWN';
+    PTCKEY_END          : Result := 'PTCKEY_END';
+    PTCKEY_HOME         : Result := 'PTCKEY_HOME';
+    PTCKEY_LEFT         : Result := 'PTCKEY_LEFT';
+    PTCKEY_UP           : Result := 'PTCKEY_UP';
+    PTCKEY_RIGHT        : Result := 'PTCKEY_RIGHT';
+    PTCKEY_DOWN         : Result := 'PTCKEY_DOWN';
+    PTCKEY_COMMA        : Result := 'PTCKEY_COMMA';
+    PTCKEY_PERIOD       : Result := 'PTCKEY_PERIOD';
+    PTCKEY_SLASH        : Result := 'PTCKEY_SLASH';
+    PTCKEY_ZERO         : Result := 'PTCKEY_ZERO';
+    PTCKEY_ONE          : Result := 'PTCKEY_ONE';
+    PTCKEY_TWO          : Result := 'PTCKEY_TWO';
+    PTCKEY_THREE        : Result := 'PTCKEY_THREE';
+    PTCKEY_FOUR         : Result := 'PTCKEY_FOUR';
+    PTCKEY_FIVE         : Result := 'PTCKEY_FIVE';
+    PTCKEY_SIX          : Result := 'PTCKEY_SIX';
+    PTCKEY_SEVEN        : Result := 'PTCKEY_SEVEN';
+    PTCKEY_EIGHT        : Result := 'PTCKEY_EIGHT';
+    PTCKEY_NINE         : Result := 'PTCKEY_NINE';
+    PTCKEY_SEMICOLON    : Result := 'PTCKEY_SEMICOLON';
+    PTCKEY_EQUALS       : Result := 'PTCKEY_EQUALS';
+    PTCKEY_A            : Result := 'PTCKEY_A';
+    PTCKEY_B            : Result := 'PTCKEY_B';
+    PTCKEY_C            : Result := 'PTCKEY_C';
+    PTCKEY_D            : Result := 'PTCKEY_D';
+    PTCKEY_E            : Result := 'PTCKEY_E';
+    PTCKEY_F            : Result := 'PTCKEY_F';
+    PTCKEY_G            : Result := 'PTCKEY_G';
+    PTCKEY_H            : Result := 'PTCKEY_H';
+    PTCKEY_I            : Result := 'PTCKEY_I';
+    PTCKEY_J            : Result := 'PTCKEY_J';
+    PTCKEY_K            : Result := 'PTCKEY_K';
+    PTCKEY_L            : Result := 'PTCKEY_L';
+    PTCKEY_M            : Result := 'PTCKEY_M';
+    PTCKEY_N            : Result := 'PTCKEY_N';
+    PTCKEY_O            : Result := 'PTCKEY_O';
+    PTCKEY_P            : Result := 'PTCKEY_P';
+    PTCKEY_Q            : Result := 'PTCKEY_Q';
+    PTCKEY_R            : Result := 'PTCKEY_R';
+    PTCKEY_S            : Result := 'PTCKEY_S';
+    PTCKEY_T            : Result := 'PTCKEY_T';
+    PTCKEY_U            : Result := 'PTCKEY_U';
+    PTCKEY_V            : Result := 'PTCKEY_V';
+    PTCKEY_W            : Result := 'PTCKEY_W';
+    PTCKEY_X            : Result := 'PTCKEY_X';
+    PTCKEY_Y            : Result := 'PTCKEY_Y';
+    PTCKEY_Z            : Result := 'PTCKEY_Z';
+    PTCKEY_OPENBRACKET  : Result := 'PTCKEY_OPENBRACKET';
+    PTCKEY_BACKSLASH    : Result := 'PTCKEY_BACKSLASH';
+    PTCKEY_CLOSEBRACKET : Result := 'PTCKEY_CLOSEBRACKET';
+    PTCKEY_NUMPAD0      : Result := 'PTCKEY_NUMPAD0';
+    PTCKEY_NUMPAD1      : Result := 'PTCKEY_NUMPAD1';
+    PTCKEY_NUMPAD2      : Result := 'PTCKEY_NUMPAD2';
+    PTCKEY_NUMPAD3      : Result := 'PTCKEY_NUMPAD3';
+    PTCKEY_NUMPAD4      : Result := 'PTCKEY_NUMPAD4';
+    PTCKEY_NUMPAD5      : Result := 'PTCKEY_NUMPAD5';
+    PTCKEY_NUMPAD6      : Result := 'PTCKEY_NUMPAD6';
+    PTCKEY_NUMPAD7      : Result := 'PTCKEY_NUMPAD7';
+    PTCKEY_NUMPAD8      : Result := 'PTCKEY_NUMPAD8';
+    PTCKEY_NUMPAD9      : Result := 'PTCKEY_NUMPAD9';
+    PTCKEY_MULTIPLY     : Result := 'PTCKEY_MULTIPLY';
+    PTCKEY_ADD          : Result := 'PTCKEY_ADD';
+    PTCKEY_SEPARATOR    : Result := 'PTCKEY_SEPARATOR';
+    PTCKEY_SUBTRACT     : Result := 'PTCKEY_SUBTRACT';
+    PTCKEY_DECIMAL      : Result := 'PTCKEY_DECIMAL';
+    PTCKEY_DIVIDE       : Result := 'PTCKEY_DIVIDE';
+    PTCKEY_F1           : Result := 'PTCKEY_F1';
+    PTCKEY_F2           : Result := 'PTCKEY_F2';
+    PTCKEY_F3           : Result := 'PTCKEY_F3';
+    PTCKEY_F4           : Result := 'PTCKEY_F4';
+    PTCKEY_F5           : Result := 'PTCKEY_F5';
+    PTCKEY_F6           : Result := 'PTCKEY_F6';
+    PTCKEY_F7           : Result := 'PTCKEY_F7';
+    PTCKEY_F8           : Result := 'PTCKEY_F8';
+    PTCKEY_F9           : Result := 'PTCKEY_F9';
+    PTCKEY_F10          : Result := 'PTCKEY_F10';
+    PTCKEY_F11          : Result := 'PTCKEY_F11';
+    PTCKEY_F12          : Result := 'PTCKEY_F12';
+    PTCKEY_DELETE       : Result := 'PTCKEY_DELETE';
+    PTCKEY_NUMLOCK      : Result := 'PTCKEY_NUMLOCK';
+    PTCKEY_SCROLLLOCK   : Result := 'PTCKEY_SCROLLLOCK';
+    PTCKEY_PRINTSCREEN  : Result := 'PTCKEY_PRINTSCREEN';
+    PTCKEY_INSERT       : Result := 'PTCKEY_INSERT';
+    PTCKEY_HELP         : Result := 'PTCKEY_HELP';
+    PTCKEY_META         : Result := 'PTCKEY_META';
+    PTCKEY_MINUS        : Result := 'PTCKEY_MINUS';
+    PTCKEY_BACKQUOTE    : Result := 'PTCKEY_BACKQUOTE';
+    PTCKEY_QUOTE        : Result := 'PTCKEY_QUOTE';
+    else
+      Result := '';
+  end;
+end;
+
 procedure DumpKey(AKey: IPTCKeyEvent);
 procedure DumpKey(AKey: IPTCKeyEvent);
+var
+  mk: TPTCModifierKey;
+  first: Boolean;
 begin
 begin
-  Writeln('Code=', AKey.Code:3, ', Unicode=$', HexStr(AKey.Unicode, 4),
-    ', Press=', AKey.Press:5, ', Shift=', AKey.Shift:5, ', Alt=', AKey.Alt:5,
-    ', Control=', AKey.Control:5);
+  Write('Code=', AKey.Code:3, ' (', KeyCode2String(AKey.Code):19,
+    '), Unicode=$', HexStr(AKey.Unicode, 4), ', Press=', AKey.Press:5,
+    ', Shift=', AKey.Shift:5, ', Alt=', AKey.Alt:5, ', Control=',
+    AKey.Control:5, ', ModifierKeys=[');
+  first := True;
+  for mk in TPTCModifierKey do
+    if mk in AKey.ModifierKeys then
+    begin
+      if not first then
+        Write(',');
+      first := False;
+      Write(mk);
+    end;
+  Writeln(']');
 end;
 end;
 
 
 var
 var

+ 0 - 1
packages/ptc/fpmake.pp

@@ -186,7 +186,6 @@ begin
       AddInclude('vgaconsoled.inc', [go32v2]);
       AddInclude('vgaconsoled.inc', [go32v2]);
       AddInclude('vgaconsolei.inc', [go32v2]);
       AddInclude('vgaconsolei.inc', [go32v2]);
       AddUnit('p_gx',[Wince]);
       AddUnit('p_gx',[Wince]);
-      AddUnit('go32fix',[go32v2]);
       AddUnit('mouse33h',[go32v2]);
       AddUnit('mouse33h',[go32v2]);
       AddUnit('textfx2',[go32v2]);
       AddUnit('textfx2',[go32v2]);
       AddUnit('cga',[go32v2]);
       AddUnit('cga',[go32v2]);

+ 4 - 1
packages/ptc/src/core/baseconsoled.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2003, 2006, 2007, 2009-2013  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2003, 2006, 2007, 2009-2013, 2016  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -70,6 +70,9 @@ type
     function GetKeyReleaseEnabled: Boolean;
     function GetKeyReleaseEnabled: Boolean;
     property KeyReleaseEnabled: Boolean read GetKeyReleaseEnabled write SetKeyReleaseEnabled;
     property KeyReleaseEnabled: Boolean read GetKeyReleaseEnabled write SetKeyReleaseEnabled;
 
 
+    { mouse handling }
+    function MoveMouseTo(X, Y: Integer): Boolean;
+
     property Pages: Integer read GetPages;
     property Pages: Integer read GetPages;
     property Name: string read GetName;
     property Name: string read GetName;
     property Title: string read GetTitle;
     property Title: string read GetTitle;

+ 10 - 1
packages/ptc/src/core/baseconsolei.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2003, 2006, 2007, 2009-2013  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2003, 2006, 2007, 2009-2013, 2016, 2017  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -117,6 +117,9 @@ type
     procedure ReadKey;
     procedure ReadKey;
     property KeyReleaseEnabled: Boolean read GetKeyReleaseEnabled write SetKeyReleaseEnabled;
     property KeyReleaseEnabled: Boolean read GetKeyReleaseEnabled write SetKeyReleaseEnabled;
 
 
+    { mouse handling }
+    function MoveMouseTo(X, Y: Integer): Boolean; virtual;
+
     property Pages: Integer read GetPages;
     property Pages: Integer read GetPages;
     property Name: string read GetName;
     property Name: string read GetName;
     property Title: string read GetTitle;
     property Title: string read GetTitle;
@@ -212,6 +215,12 @@ begin
   Result := FReleaseEnabled;
   Result := FReleaseEnabled;
 end;
 end;
 
 
+{ must be overriden in consoles, that support moving the mouse cursor }
+function TPTCBaseConsole.MoveMouseTo(X, Y: Integer): Boolean;
+begin
+  Result := False;
+end;
+
 function TPTCOpenGLLessConsole.GetOpenGL_Enabled: Boolean;
 function TPTCOpenGLLessConsole.GetOpenGL_Enabled: Boolean;
 begin
 begin
   Result := False;
   Result := False;

+ 8 - 1
packages/ptc/src/core/consolei.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2003, 2006, 2007, 2009-2013, 2015  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2003, 2006, 2007, 2009-2013, 2015, 2016  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -114,6 +114,7 @@ type
     function GetInformation: string; override;
     function GetInformation: string; override;
     function NextEvent(out AEvent: IPTCEvent; AWait: Boolean; const AEventMask: TPTCEventMask): Boolean; override;
     function NextEvent(out AEvent: IPTCEvent; AWait: Boolean; const AEventMask: TPTCEventMask): Boolean; override;
     function PeekEvent(AWait: Boolean; const AEventMask: TPTCEventMask): IPTCEvent; override;
     function PeekEvent(AWait: Boolean; const AEventMask: TPTCEventMask): IPTCEvent; override;
+    function MoveMouseTo(X, Y: Integer): Boolean; override;
     procedure OpenGL_SwapBuffers; override;
     procedure OpenGL_SwapBuffers; override;
     procedure OpenGL_SetSwapInterval(AInterval: Integer); override;
     procedure OpenGL_SetSwapInterval(AInterval: Integer); override;
     function OpenGL_GetSwapInterval: Integer; override;
     function OpenGL_GetSwapInterval: Integer; override;
@@ -839,6 +840,12 @@ begin
     raise TPTCError.Create('console is not open (core)');
     raise TPTCError.Create('console is not open (core)');
 end;
 end;
 
 
+function TPTCConsole.MoveMouseTo(X, Y: Integer): Boolean;
+begin
+  Check;
+  Result := FConsole.MoveMouseTo(X, Y);
+end;
+
 procedure TPTCConsole.PassOpenGLOptionsToInnerConsole;
 procedure TPTCConsole.PassOpenGLOptionsToInnerConsole;
 begin
 begin
   FConsole.OpenGL_Enabled := FUseOpenGL;
   FConsole.OpenGL_Enabled := FUseOpenGL;

+ 1 - 1
packages/ptc/src/core/errori.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2007, 2009, 2010, 2012  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2007, 2009, 2010, 2012, 2013  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or

+ 7 - 2
packages/ptc/src/core/keyeventd.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2003, 2006, 2007, 2009-2011, 2015  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2003, 2006, 2007, 2009-2011, 2015, 2017  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -31,7 +31,12 @@
 }
 }
 
 
 type
 type
-  TPTCModifierKey = (pmkAlt, pmkShift, pmkControl);
+  TPTCModifierKey = (pmkAlt, pmkShift, pmkControl, pmkLeftAlt, pmkRightAlt,
+    pmkLeftShift, pmkRightShift, pmkLeftControl, pmkRightControl,
+    pmkNumLockActive, pmkNumLockPressed,
+    pmkCapsLockActive, pmkCapsLockPressed,
+    pmkScrollLockActive, pmkScrollLockPressed,
+    pmkNumPadKey,pmkDeadKey);
   TPTCModifierKeys = set of TPTCModifierKey;
   TPTCModifierKeys = set of TPTCModifierKey;
   IPTCKeyEvent = interface(IPTCEvent)
   IPTCKeyEvent = interface(IPTCEvent)
     ['{9BD1CD41-1DF6-4392-99DC-885EADB6D85A}']
     ['{9BD1CD41-1DF6-4392-99DC-885EADB6D85A}']

+ 32 - 6
packages/ptc/src/core/mouseeventd.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2007, 2009-2011  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2007, 2009-2011, 2016  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -34,11 +34,37 @@ type
 {todo  TPTCMouseCursor = (PTCMouseCursorDefault,
 {todo  TPTCMouseCursor = (PTCMouseCursorDefault,
                      PTCMouseCursorAlwaysVisible,
                      PTCMouseCursorAlwaysVisible,
                      PTCMouseCursorAlwaysInvisible);}
                      PTCMouseCursorAlwaysInvisible);}
-  TPTCMouseButton = (PTCMouseButton1, { left mouse button }
-                     PTCMouseButton2, { right mouse button }
-                     PTCMouseButton3, { middle mouse button }
-                     PTCMouseButton4,
-                     PTCMouseButton5);
+  TPTCMouseButton = (PTCMouseButton1,  { left mouse button }
+                     PTCMouseButton2,  { right mouse button }
+                     PTCMouseButton3,  { middle mouse button }
+                     PTCMouseButton4,  { mouse wheel rotated forward (scroll up) }
+                     PTCMouseButton5,  { mouse wheel rotated backward (scroll down) }
+                     PTCMouseButton6,  { mouse horizontal scroll wheel rotated left }
+                     PTCMouseButton7,  { mouse horizontal scroll wheel rotated right }
+                     PTCMouseButton8,  { "back" button ("X button 1") }
+                     PTCMouseButton9,  { "forward" button ("X button 2") }
+                     PTCMouseButton10,
+                     PTCMouseButton11,
+                     PTCMouseButton12,
+                     PTCMouseButton13,
+                     PTCMouseButton14,
+                     PTCMouseButton15,
+                     PTCMouseButton16,
+                     PTCMouseButton17,
+                     PTCMouseButton18,
+                     PTCMouseButton19,
+                     PTCMouseButton20,
+                     PTCMouseButton21,
+                     PTCMouseButton22,
+                     PTCMouseButton23,
+                     PTCMouseButton24,
+                     PTCMouseButton25,
+                     PTCMouseButton26,
+                     PTCMouseButton27,
+                     PTCMouseButton28,
+                     PTCMouseButton29,
+                     PTCMouseButton30,
+                     PTCMouseButton31);
   TPTCMouseButtonState = set of TPTCMouseButton;
   TPTCMouseButtonState = set of TPTCMouseButton;
   IPTCMouseEvent = interface(IPTCEvent)
   IPTCMouseEvent = interface(IPTCEvent)
     ['{4D093608-6F27-4578-B41E-3492A4C7FEED}']
     ['{4D093608-6F27-4578-B41E-3492A4C7FEED}']

+ 0 - 1299
packages/ptc/src/dos/base/go32fix.pp

@@ -1,1299 +0,0 @@
-{
-    This file is part of the Free Pascal run time library.
-    and implements some stuff for protected mode programming
-    Copyright (c) 1999-2000 by the Free Pascal development team.
-
-    See the file COPYING.FPC, included in this distribution,
-    for details about the copyright.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- **********************************************************************}
-
-unit go32fix;
-
-{$S-,R-,I-,Q-} {no stack check, used by DPMIEXCP !! }
-
-interface
-
-    const
-    { contants for the run modes returned by get_run_mode }
-       rm_unknown = 0;
-       rm_raw     = 1;     { raw (without HIMEM) }
-       rm_xms     = 2;     { XMS (for example with HIMEM, without EMM386) }
-       rm_vcpi    = 3;     { VCPI (for example HIMEM and EMM386) }
-       rm_dpmi    = 4;     { DPMI (for example DOS box or 386Max) }
-
-    { flags }
-       carryflag     = $001;
-       parityflag    = $004;
-       auxcarryflag  = $010;
-       zeroflag      = $040;
-       signflag      = $080;
-       trapflag      = $100;
-       interruptflag = $200;
-       directionflag = $400;
-       overflowflag  = $800;
-
-    type
-       tmeminfo = record
-          available_memory,
-          available_pages,
-          available_lockable_pages,
-          linear_space,
-          unlocked_pages,
-          available_physical_pages,
-          total_physical_pages,
-          free_linear_space,
-          max_pages_in_paging_file,
-          reserved0,
-          reserved1,
-          reserved2: longint;
-       end;
-
-       tseginfo = record
-          offset: pointer;
-          segment: word;
-       end;
-
-       trealregs = record
-         case integer of
-          1: { 32-bit } (EDI, ESI, EBP, Res, EBX, EDX, ECX, EAX: longint;
-                         Flags, ES, DS, FS, GS, IP, CS, SP, SS: word);
-          2: { 16-bit } (DI, DI2, SI, SI2, BP, BP2, R1, R2: word;
-                         BX, BX2, DX, DX2, CX, CX2, AX, AX2: word);
-          3: { 8-bit }  (stuff: array[1..4] of longint;
-                         BL, BH, BL2, BH2, DL, DH, DL2, DH2,
-                         CL, CH, CL2, CH2, AL, AH, AL2, AH2: byte);
-          4: { Compat } (RealEDI, RealESI, RealEBP, RealRES,
-                         RealEBX, RealEDX, RealECX, RealEAX: longint;
-                         RealFlags,
-                         RealES, RealDS, RealFS, RealGS,
-                         RealIP, RealCS, RealSP, RealSS: word);
-       end;
-
-      registers = trealregs;
-
-      tdpmiversioninfo = record
-        major, minor: byte;
-	flags: word;
-	cpu: byte;
-	master_pic, slave_pic: byte;
-      end;
-
-    { this works only with real DPMI }
-    function allocate_ldt_descriptors(count: word): word;
-    function free_ldt_descriptor(d: word): boolean;
-    function segment_to_descriptor(seg: word): word;
-    function get_next_selector_increment_value: word;
-    function get_segment_base_address(d: word): longint;
-    function set_segment_base_address(d: word;s: dword): boolean;
-    function set_segment_limit(d: word;s: dword): boolean;
-    function set_descriptor_access_right(d: word;w: word): boolean;
-    function create_code_segment_alias_descriptor(seg: word): word;
-    function get_linear_addr(phys_addr: dword;size: longint): dword;
-    function free_linear_addr_mapping(linear_addr: dword): boolean;
-    function get_segment_limit(d: word): dword;
-    function get_descriptor_access_right(d: word): longint;
-    function get_page_size:longint;
-    function map_device_in_memory_block(handle,offset,pagecount,device:dword):boolean;
-    function get_page_attributes(handle, offset, pagecount: dword; buf: pointer): boolean;
-    function set_page_attributes(handle, offset, pagecount: dword; buf: pointer): boolean;
-    function realintr(intnr: word;var regs: trealregs): boolean;
-    function get_dpmi_version(var version: tdpmiversioninfo): boolean;
-
-    { is needed for functions which need a real mode buffer }
-    function global_dos_alloc(bytes: longint): longint;
-    function global_dos_free(selector: word): boolean;
-
-    var
-       { selector for the DOS memory (only usable if in DPMI mode) }
-       dosmemselector: word;
-       { result of dpmi call }
-       int31error: word;
-
-    { this procedure copies data where the source and destination }
-    { are specified by 48 bit pointers                            }
-    { Note: the procedure checks only for overlapping if          }
-    { source selector=destination selector                        }
-    procedure seg_move(sseg: word;source: longint;dseg: word;dest: longint;count: longint);
-
-    { fills a memory area specified by a 48 bit pointer with c }
-    procedure seg_fillchar(seg: word;ofs: longint;count: longint;c: char);
-    procedure seg_fillword(seg: word;ofs: longint;count: longint;w: word);
-
-    {************************************}
-    { this works with all PM interfaces: }
-    {************************************}
-
-    function get_meminfo(var meminfo: tmeminfo): boolean;
-    function get_pm_interrupt(vector: byte;var intaddr: tseginfo): boolean;
-    function set_pm_interrupt(vector: byte;const intaddr: tseginfo): boolean;
-    function get_rm_interrupt(vector: byte;var intaddr: tseginfo): boolean;
-    function set_rm_interrupt(vector: byte;const intaddr: tseginfo): boolean;
-    function get_exception_handler(e: byte;var intaddr: tseginfo): boolean;
-    function set_exception_handler(e: byte;const intaddr: tseginfo): boolean;
-    function get_pm_exception_handler(e: byte;var intaddr: tseginfo): boolean;
-    function set_pm_exception_handler(e: byte;const intaddr: tseginfo): boolean;
-    function free_rm_callback(var intaddr: tseginfo): boolean;
-    function get_rm_callback(pm_func: pointer;const reg: trealregs;var rmcb: tseginfo): boolean;
-    function get_cs: word;
-    function get_ds: word;
-    function get_ss: word;
-
-    { locking functions }
-    function allocate_memory_block(size:longint):longint;
-    function free_memory_block(blockhandle: longint): boolean;
-    function request_linear_region(linearaddr, size: longint;
-                                   var blockhandle: longint): boolean;
-    function lock_linear_region(linearaddr, size: longint): boolean;
-    function lock_data(var data;size: longint): boolean;
-    function lock_code(functionaddr: pointer;size: longint): boolean;
-    function unlock_linear_region(linearaddr, size: longint): boolean;
-    function unlock_data(var data;size: longint): boolean;
-    function unlock_code(functionaddr: pointer;size: longint): boolean;
-
-    { disables and enables interrupts }
-    procedure disable;
-    procedure enable;
-
-    function inportb(port: word): byte;
-    function inportw(port: word): word;
-    function inportl(port: word): longint;
-
-    procedure outportb(port: word;data: byte);
-    procedure outportw(port: word;data: word);
-    procedure outportl(port: word;data: longint);
-    function get_run_mode: word;
-
-    function transfer_buffer: longint;
-    function tb_segment: longint;
-    function tb_offset: longint;
-    function tb_size: longint;
-    procedure copytodos(var addr; len: longint);
-    procedure copyfromdos(var addr; len: longint);
-
-    procedure dpmi_dosmemput(seg: word;ofs: word;var data;count: longint);
-    procedure dpmi_dosmemget(seg: word;ofs: word;var data;count: longint);
-    procedure dpmi_dosmemmove(sseg,sofs,dseg,dofs: word;count: longint);
-    procedure dpmi_dosmemfillchar(seg,ofs: word;count: longint;c: char);
-    procedure dpmi_dosmemfillword(seg,ofs: word;count: longint;w: word);
-
-
-
-    const
-       { this procedures are assigned to the procedure which are needed }
-       { for the current mode to access DOS memory                      }
-       { It's strongly recommended to use this procedures!              }
-       dosmemput: procedure(seg: word;ofs: word;var data;count: longint)=@dpmi_dosmemput;
-       dosmemget: procedure(seg: word;ofs: word;var data;count: longint)=@dpmi_dosmemget;
-       dosmemmove: procedure(sseg,sofs,dseg,dofs: word;count: longint)=@dpmi_dosmemmove;
-       dosmemfillchar: procedure(seg,ofs: word;count: longint;c: char)=@dpmi_dosmemfillchar;
-       dosmemfillword: procedure(seg,ofs: word;count: longint;w: word)=@dpmi_dosmemfillword;
-
-  implementation
-
-{$asmmode ATT}
-
-
-    { the following procedures copy from and to DOS memory using DPMI }
-    procedure dpmi_dosmemput(seg: word;ofs: word;var data;count: longint);
-
-      begin
-         seg_move(get_ds,longint(@data),dosmemselector,seg*16+ofs,count);
-      end;
-
-    procedure dpmi_dosmemget(seg: word;ofs: word;var data;count: longint);
-
-      begin
-         seg_move(dosmemselector,seg*16+ofs,get_ds,longint(@data),count);
-      end;
-
-    procedure dpmi_dosmemmove(sseg,sofs,dseg,dofs: word;count: longint);
-
-      begin
-         seg_move(dosmemselector,sseg*16+sofs,dosmemselector,dseg*16+dofs,count);
-      end;
-
-    procedure dpmi_dosmemfillchar(seg,ofs: word;count: longint;c: char);
-
-      begin
-         seg_fillchar(dosmemselector,seg*16+ofs,count,c);
-      end;
-
-    procedure dpmi_dosmemfillword(seg,ofs: word;count: longint;w: word);
-
-      begin
-         seg_fillword(dosmemselector,seg*16+ofs,count,w);
-      end;
-
-
-    procedure test_int31(flag: longint); stdcall; { stack-args! }
-      begin
-         asm
-            pushl %ebx
-            movw  $0,INT31ERROR
-            movl  flag,%ebx
-            testb $1,%bl
-            jz    .Lti31_1
-            movw  %ax,INT31ERROR
-            xorl  %eax,%eax
-            jmp   .Lti31_2
-            .Lti31_1:
-            movl  $1,%eax
-            .Lti31_2:
-            popl  %ebx
-         end;
-      end;
-
-    function global_dos_alloc(bytes: longint): longint;
-
-      begin
-         asm
-            pushl %ebx
-            movl bytes,%ebx
-            addl $0xf,%ebx              // round up
-            shrl $0x4,%ebx              // convert to Paragraphs
-            movl $0x100,%eax            // function 0x100
-            int  $0x31
-            jnc  .LDos_OK
-            movw %ax,INT31ERROR
-            xorl %eax,%eax
-            jmp  .LDos_end
-          .LDos_OK:
-            shll $0x10,%eax             // return Segment in hi(Result)
-            movw %dx,%ax                // return Selector in lo(Result)
-          .LDos_end:
-            movl %eax,__result
-            popl %ebx
-         end;
-      end;
-
-    function  global_dos_free(selector: word): boolean;
-
-      begin
-         asm
-            movw Selector,%dx
-            movl $0x101,%eax
-            int  $0x31
-            setnc %al
-            movb %al,__RESULT
-         end;
-      end;
-
-    function realintr(intnr: word;var regs: trealregs): boolean;
-
-      begin
-         regs.realsp:=0;
-         regs.realss:=0;
-         regs.realres:=0; { play it safe }
-         asm
-            { save all used registers to avoid crash under NTVDM }
-            { when spawning a 32-bit DPMI application            }
-            pushl %edi
-            pushl %ebx
-            pushw %fs
-            movw  intnr,%bx
-            xorl  %ecx,%ecx
-            movl  regs,%edi
-            { es is always equal ds }
-            movl  $0x300,%eax
-            int   $0x31
-            popw  %fs
-            setnc %al
-            movb  %al,__RESULT
-            popl  %ebx
-            popl  %edi
-         end;
-      end;
-
-    procedure seg_fillchar(seg: word;ofs: longint;count: longint;c: char);
-
-      begin
-         asm
-            pushl %edi
-            movl ofs,%edi
-            movl count,%ecx
-            movb c,%dl
-            { load es with selector }
-            pushw %es
-            movw seg,%ax
-            movw %ax,%es
-            { fill eax with duplicated c }
-            { so we can use stosl        }
-            movb %dl,%dh
-            movw %dx,%ax
-            shll $16,%eax
-            movw %dx,%ax
-            movl %ecx,%edx
-            shrl $2,%ecx
-            cld
-            rep
-            stosl
-            movl %edx,%ecx
-            andl $3,%ecx
-            rep
-            stosb
-            popw %es
-            popl %edi
-         end;
-      end;
-
-    procedure seg_fillword(seg: word;ofs: longint;count: longint;w: word);
-
-      begin
-         asm
-            pushl %edi
-            movl ofs,%edi
-            movl count,%ecx
-            movw w,%dx
-            { load segment }
-            pushw %es
-            movw seg,%ax
-            movw %ax,%es
-            { fill eax }
-            movw %dx,%ax
-            shll $16,%eax
-            movw %dx,%ax
-            movl %ecx,%edx
-            shrl $1,%ecx
-            cld
-            rep
-            stosl
-            movl %edx,%ecx
-            andl $1,%ecx
-            rep
-            stosw
-            popw %es
-            popl %edi
-         end;
-      end;
-
-    procedure seg_move(sseg: word;source: longint;dseg: word;dest: longint;count: longint);
-
-      begin
-         if count=0 then
-           exit;
-         if (sseg<>dseg) or ((sseg=dseg) and (source>dest)) then
-           asm
-              pushl %esi
-              pushl %edi
-              pushw %es
-              pushw %ds
-              cld
-              movl count,%ecx
-              movl source,%esi
-              movl dest,%edi
-              movw dseg,%ax
-              movw %ax,%es
-              movw sseg,%ax
-              movw %ax,%ds
-              movl %ecx,%eax
-              shrl $2,%ecx
-              rep
-              movsl
-              movl %eax,%ecx
-              andl $3,%ecx
-              rep
-              movsb
-              popw %ds
-              popw %es
-              popl %edi
-              popl %esi
-           end ['ECX','EAX']
-         else if (source<dest) then
-           { copy backward for overlapping }
-           asm
-              pushl %esi
-              pushl %edi
-              pushw %es
-              pushw %ds
-              std
-              movl count,%ecx
-              movl source,%esi
-              movl dest,%edi
-              movw dseg,%ax
-              movw %ax,%es
-              movw sseg,%ax
-              movw %ax,%ds
-              addl %ecx,%esi
-              addl %ecx,%edi
-              movl %ecx,%eax
-              andl $3,%ecx
-              orl %ecx,%ecx
-              jz .LSEG_MOVE1
-
-              { calculate esi and edi}
-              decl %esi
-              decl %edi
-              rep
-              movsb
-              incl %esi
-              incl %edi
-           .LSEG_MOVE1:
-              subl $4,%esi
-              subl $4,%edi
-              movl %eax,%ecx
-              shrl $2,%ecx
-              rep
-              movsl
-              cld
-              popw %ds
-              popw %es
-              popl %edi
-              popl %esi
-           end ['ECX','EAX'];
-      end;
-
-    procedure outportb(port: word;data: byte);
-
-      begin
-         asm
-            movw port,%dx
-            movb data,%al
-            outb %al,%dx
-         end ['EAX','EDX'];
-      end;
-
-    procedure outportw(port: word;data: word);
-
-      begin
-         asm
-            movw port,%dx
-            movw data,%ax
-            outw %ax,%dx
-         end ['EAX','EDX'];
-      end;
-
-    procedure outportl(port: word;data: longint);
-
-      begin
-         asm
-            movw port,%dx
-            movl data,%eax
-            outl %eax,%dx
-         end ['EAX','EDX'];
-      end;
-
-    function inportb(port: word): byte;
-
-      begin
-         asm
-            movw port,%dx
-            inb %dx,%al
-            movb %al,__RESULT
-         end ['EAX','EDX'];
-      end;
-
-    function inportw(port: word): word;
-
-      begin
-         asm
-            movw port,%dx
-            inw %dx,%ax
-            movw %ax,__RESULT
-         end ['EAX','EDX'];
-      end;
-
-    function inportl(port: word): longint;
-
-      begin
-         asm
-            movw port,%dx
-            inl %dx,%eax
-            movl %eax,__RESULT
-         end ['EAX','EDX'];
-      end;
-
-
-
-    function get_cs: word;assembler;
-      asm
-            movw %cs,%ax
-      end;
-
-
-    function get_ss: word;assembler;
-      asm
-            movw %ss,%ax
-      end;
-
-
-    function get_ds: word;assembler;
-      asm
-            movw %ds,%ax
-      end;
-
-
-    function set_pm_interrupt(vector: byte;const intaddr: tseginfo): boolean;
-
-      begin
-         asm
-            pushl %ebx
-            movl intaddr,%eax
-            movl (%eax),%edx
-            movw 4(%eax),%cx
-            movl $0x205,%eax
-            movb vector,%bl
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            popl %ebx
-         end;
-      end;
-
-    function set_rm_interrupt(vector: byte;const intaddr: tseginfo): boolean;
-
-      begin
-         asm
-            pushl %ebx
-            movl intaddr,%eax
-            movw (%eax),%dx
-            movw 4(%eax),%cx
-            movl $0x201,%eax
-            movb vector,%bl
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            popl %ebx
-         end;
-      end;
-
-    function set_pm_exception_handler(e: byte;const intaddr: tseginfo): boolean;
-
-      begin
-         asm
-            pushl %ebx
-            movl intaddr,%eax
-            movl (%eax),%edx
-            movw 4(%eax),%cx
-            movl $0x212,%eax
-            movb e,%bl
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            popl %ebx
-         end;
-      end;
-
-    function set_exception_handler(e: byte;const intaddr: tseginfo): boolean;
-
-      begin
-         asm
-            pushl %ebx
-            movl intaddr,%eax
-            movl (%eax),%edx
-            movw 4(%eax),%cx
-            movl $0x203,%eax
-            movb e,%bl
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            popl %ebx
-         end;
-      end;
-
-    function get_pm_exception_handler(e: byte;var intaddr: tseginfo): boolean;
-
-      begin
-         asm
-            pushl %ebx
-            movl $0x210,%eax
-            movb e,%bl
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            movl intaddr,%eax
-            movl %edx,(%eax)
-            movw %cx,4(%eax)
-            popl %ebx
-         end;
-      end;
-
-    function get_exception_handler(e: byte;var intaddr: tseginfo): boolean;
-
-      begin
-         asm
-            pushl %ebx
-            movl $0x202,%eax
-            movb e,%bl
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            movl intaddr,%eax
-            movl %edx,(%eax)
-            movw %cx,4(%eax)
-            popl %ebx
-         end;
-      end;
-
-    function get_pm_interrupt(vector: byte;var intaddr: tseginfo): boolean;
-
-      begin
-         asm
-            pushl %ebx
-            movb vector,%bl
-            movl $0x204,%eax
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            movl intaddr,%eax
-            movl %edx,(%eax)
-            movw %cx,4(%eax)
-            popl %ebx
-         end;
-      end;
-
-    function get_rm_interrupt(vector: byte;var intaddr: tseginfo): boolean;
-
-      begin
-         asm
-            pushl %ebx
-            movb vector,%bl
-            movl $0x200,%eax
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            movl intaddr,%eax
-            movzwl %dx,%edx
-            movl %edx,(%eax)
-            movw %cx,4(%eax)
-            popl %ebx
-         end;
-      end;
-
-    function free_rm_callback(var intaddr: tseginfo): boolean;
-      begin
-         asm
-            movl intaddr,%eax
-            movw (%eax),%dx
-            movw 4(%eax),%cx
-            movl $0x304,%eax
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-         end;
-      end;
-
-    { here we must use ___v2prt0_ds_alias instead of from v2prt0.s
-    because the exception processor sets the ds limit to $fff
-    at hardware exceptions }
-
-    var
-       ___v2prt0_ds_alias: word; external name '___v2prt0_ds_alias';
-
-    function get_rm_callback(pm_func: pointer;const reg: trealregs;var rmcb: tseginfo): boolean;
-      begin
-         asm
-            pushl %esi
-            pushl %edi
-            movl  pm_func,%esi
-            movl  reg,%edi
-            pushw %es
-            movw  ___v2prt0_ds_alias,%ax
-            movw  %ax,%es
-            pushw %ds
-            movw  %cs,%ax
-            movw  %ax,%ds
-            movl  $0x303,%eax
-            int   $0x31
-            popw  %ds
-            popw  %es
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            movl  rmcb,%eax
-            movzwl %dx,%edx
-            movl  %edx,(%eax)
-            movw  %cx,4(%eax)
-            popl %edi
-            popl %esi
-         end;
-      end;
-
-    function allocate_ldt_descriptors(count: word): word;
-
-      begin
-         asm
-            movw count,%cx
-            xorl %eax,%eax
-            int $0x31
-            movw %ax,__RESULT
-         end;
-      end;
-
-    function free_ldt_descriptor(d: word): boolean;
-
-      begin
-         asm
-            pushl %ebx
-            movw d,%bx
-            movl $1,%eax
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            popl %ebx
-         end;
-      end;
-
-    function segment_to_descriptor(seg: word): word;
-
-      begin
-         asm
-            pushl %ebx
-            movw seg,%bx
-            movl $2,%eax
-            int $0x31
-            movw %ax,__RESULT
-            popl %ebx
-         end;
-      end;
-
-    function get_next_selector_increment_value: word;
-
-      begin
-         asm
-            movl $3,%eax
-            int $0x31
-            movw %ax,__RESULT
-         end;
-      end;
-
-    function get_segment_base_address(d: word): longint;
-
-      begin
-         asm
-            pushl %ebx
-            movw d,%bx
-            movl $6,%eax
-            int $0x31
-            xorl %eax,%eax
-            movw %dx,%ax
-            shll $16,%ecx
-            orl %ecx,%eax
-            movl %eax,__RESULT
-            popl %ebx
-         end;
-      end;
-
-    function get_page_size:longint;
-      begin
-        asm
-           pushl %ebx
-           movl $0x604,%eax
-           int $0x31
-           shll $16,%ebx
-           movw %cx,%bx
-           movl %ebx,__RESULT
-           popl %ebx
-        end;
-      end;
-
-    function request_linear_region(linearaddr, size: longint;
-                                   var blockhandle: longint): boolean;
-      var
-         pageofs: longint;
-
-      begin
-         pageofs:=linearaddr and $3ff;
-         linearaddr:=linearaddr-pageofs;
-         size:=size+pageofs;
-         asm
-            pushl %ebx
-            pushl %esi
-            movl $0x504,%eax
-            movl linearaddr,%ebx
-            movl size,%ecx
-            movl $1,%edx
-            xorl %esi,%esi
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            movl blockhandle,%eax
-            movl %esi,(%eax)
-            movl %ebx,pageofs
-            popl %esi
-            popl %ebx
-         end;
-         if pageofs<>linearaddr then
-           request_linear_region:=false;
-      end;
-
-    function allocate_memory_block(size:longint):longint;
-      begin
-        asm
-          pushl %ebx
-          pushl %esi
-          movl  $0x501,%eax
-          movl  size,%ecx
-          movl  %ecx,%ebx
-          shrl  $16,%ebx
-          andl  $65535,%ecx
-          int   $0x31
-          jnc   .Lallocate_mem_block_err
-          xorl  %ebx,%ebx
-          xorl  %ecx,%ecx
-       .Lallocate_mem_block_err:
-          shll  $16,%ebx
-          movw  %cx,%bx
-          shll  $16,%esi
-          movw  %di,%si
-          movl  %ebx,__RESULT
-          popl %esi
-          popl %ebx
-        end;
-     end;
-
-    function free_memory_block(blockhandle: longint): boolean;
-      begin
-         asm
-            pushl %edi
-            pushl %esi
-            movl blockhandle,%esi
-            movl %esi,%edi
-            shll $16,%esi
-            movl $0x502,%eax
-            int  $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            popl %esi
-            popl %edi
-         end;
-      end;
-
-    function lock_linear_region(linearaddr, size: longint): boolean;
-
-      begin
-          asm
-            pushl %ebx
-            pushl %edi
-            pushl %esi
-            movl  $0x600,%eax
-            movl  linearaddr,%ecx
-            movl  %ecx,%ebx
-            shrl  $16,%ebx
-            movl  size,%esi
-            movl  %esi,%edi
-            shrl  $16,%esi
-            int   $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            popl %esi
-            popl %edi
-            popl %ebx
-          end;
-      end;
-
-    function lock_data(var data;size: longint): boolean;
-
-      var
-         linearaddr: longint;
-
-      begin
-         if get_run_mode<>rm_dpmi then
-           exit;
-         linearaddr:=longint(@data)+get_segment_base_address(get_ds);
-         lock_data:=lock_linear_region(linearaddr,size);
-      end;
-
-    function lock_code(functionaddr: pointer;size: longint): boolean;
-
-      var
-         linearaddr: longint;
-
-      begin
-         if get_run_mode<>rm_dpmi then
-           exit;
-         linearaddr:=longint(functionaddr)+get_segment_base_address(get_cs);
-         lock_code:=lock_linear_region(linearaddr,size);
-      end;
-
-    function unlock_linear_region(linearaddr,size: longint): boolean;
-
-      begin
-         asm
-            pushl %ebx
-            pushl %edi
-            pushl %esi
-            movl  $0x601,%eax
-            movl  linearaddr,%ecx
-            movl  %ecx,%ebx
-            shrl  $16,%ebx
-            movl  size,%esi
-            movl  %esi,%edi
-            shrl  $16,%esi
-            int   $0x31
-            pushf
-            call  test_int31
-            movb  %al,__RESULT
-            popl %esi
-            popl %edi
-            popl %ebx
-         end;
-      end;
-
-    function unlock_data(var data;size: longint): boolean;
-
-      var
-         linearaddr: longint;
-      begin
-         if get_run_mode<>rm_dpmi then
-           exit;
-         linearaddr:=longint(@data)+get_segment_base_address(get_ds);
-         unlock_data:=unlock_linear_region(linearaddr,size);
-      end;
-
-    function unlock_code(functionaddr: pointer;size: longint): boolean;
-
-      var
-         linearaddr: longint;
-      begin
-         if get_run_mode<>rm_dpmi then
-           exit;
-         linearaddr:=longint(functionaddr)+get_segment_base_address(get_cs);
-         unlock_code:=unlock_linear_region(linearaddr,size);
-      end;
-
-    function set_segment_base_address(d: word;s: dword): boolean;
-
-      begin
-         asm
-            pushl %ebx
-            movw d,%bx
-            leal s,%eax
-            movw (%eax),%dx
-            movw 2(%eax),%cx
-            movl $7,%eax
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            popl %ebx
-         end;
-      end;
-
-    function set_descriptor_access_right(d: word;w: word): boolean;
-
-      begin
-         asm
-            pushl %ebx
-            movw d,%bx
-            movw w,%cx
-            movl $9,%eax
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            popl %ebx
-         end;
-      end;
-
-    function set_segment_limit(d: word;s: dword): boolean;
-
-      begin
-         asm
-            pushl %ebx
-            movw d,%bx
-            leal s,%eax
-            movw (%eax),%dx
-            movw 2(%eax),%cx
-            movl $8,%eax
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-            popl %ebx
-         end;
-      end;
-
-    function get_descriptor_access_right(d: word): longint;
-
-      begin
-         asm
-            movzwl d,%eax
-            lar %eax,%eax
-            jz .L_ok
-            xorl %eax,%eax
-         .L_ok:
-            movl %eax,__RESULT
-         end;
-      end;
-    function get_segment_limit(d: word): dword;
-
-      begin
-         asm
-            movzwl d,%eax
-            lsl %eax,%eax
-            jz .L_ok2
-            xorl %eax,%eax
-         .L_ok2:
-            movl %eax,__RESULT
-         end;
-      end;
-
-    function create_code_segment_alias_descriptor(seg: word): word;
-
-      begin
-         asm
-            pushl %ebx
-            movw seg,%bx
-            movl $0xa,%eax
-            int $0x31
-            pushf
-            call test_int31
-            movw %ax,__RESULT
-            popl %ebx
-         end;
-      end;
-
-    function get_meminfo(var meminfo: tmeminfo): boolean;
-
-      begin
-         asm
-            pushl %edi
-            movl meminfo,%edi
-            movl $0x500,%eax
-            int $0x31
-            pushf
-            movb %al,__RESULT
-            call test_int31
-            popl %edi
-         end;
-      end;
-
-    function get_linear_addr(phys_addr: dword;size: longint): dword;
-
-      begin
-         asm
-            pushl %ebx
-            pushl %edi
-            pushl %esi
-            movl phys_addr,%ebx
-            movl %ebx,%ecx
-            shrl $16,%ebx
-            movl size,%esi
-            movl %esi,%edi
-            shrl $16,%esi
-            movl $0x800,%eax
-            int $0x31
-            pushf
-            call test_int31
-            shll $16,%ebx
-            movw %cx,%bx
-            movl %ebx,__RESULT
-            popl %esi
-            popl %edi
-            popl %ebx
-         end;
-      end;
-
-    function free_linear_addr_mapping(linear_addr: dword): boolean;
-
-      begin
-         asm
-            pushl %ebx
-            pushl %ecx
-            movl linear_addr,%ebx
-            movl %ebx,%ecx
-            shrl $16,%ebx
-            movl $0x801,%eax
-            int $0x31
-            pushf
-            call test_int31
-            movb %al,__RESULT
-	    popl %ecx
-            popl %ebx
-         end;
-      end;
-
-    procedure disable;assembler;
-
-      asm
-         cli
-      end;
-
-    procedure enable;assembler;
-
-      asm
-         sti
-      end;
-
-
-    var
-      _run_mode: word;external name '_run_mode';
-
-    function get_run_mode: word;
-
-      begin
-         get_run_mode:=_run_mode;
-      end;
-
-    function map_device_in_memory_block(handle,offset,pagecount,device:dword):boolean;
-      begin
-         asm
-           pushl %ebx
-           pushl %edi
-           pushl %esi
-           movl device,%edx
-           movl handle,%esi
-           movl offset,%ebx
-           movl pagecount,%ecx
-           movl $0x0508,%eax
-           int $0x31
-           pushf
-           call test_int31
-           movb %al,__RESULT
-           popl %esi
-           popl %edi
-           popl %ebx
-         end;
-      end;
-
-    function get_page_attributes(handle, offset, pagecount: dword; buf: pointer): boolean;
-      begin
-         asm
-           pushl %ebx
-           pushl %ecx
-           pushl %edx
-           pushl %esi
-           pushw %es
-	   pushw %ds
-	   popw %es
-           movl buf,%edx
-           movl handle,%esi
-           movl offset,%ebx
-           movl pagecount,%ecx
-           movl $0x0506,%eax
-           int $0x31
-           pushf
-           call test_int31
-           movb %al,__RESULT
-	   popw %es
-           popl %esi
-           popl %edx
-           popl %ecx
-           popl %ebx
-	 end;
-      end;
-
-    function set_page_attributes(handle, offset, pagecount: dword; buf: pointer): boolean;
-      begin
-         asm
-           pushl %ebx
-           pushl %ecx
-           pushl %edx
-           pushl %esi
-           pushw %es
-	   pushw %ds
-	   popw %es
-           movl buf,%edx
-           movl handle,%esi
-           movl offset,%ebx
-           movl pagecount,%ecx
-           movl $0x0507,%eax
-           int $0x31
-           pushf
-           call test_int31
-           movb %al,__RESULT
-	   popw %es
-           popl %esi
-           popl %edx
-           popl %ecx
-           popl %ebx
-	 end;
-      end;
-
-    function get_dpmi_version(var version: tdpmiversioninfo): boolean;
-      var
-        _version, _flags, _cpu, _pic: word;
-      begin
-         asm
-           movl $0x0400,%eax
-           int $0x31
-           pushf
-	   movw %ax,_version
-	   movw %bx,_flags
-	   movw %cx,_cpu
-	   movw %dx,_pic
-           call test_int31
-           movb %al,__RESULT
-	 end ['EAX','EBX','ECX','EDX'];
-
-	 if get_dpmi_version then
-	 begin
-	   FillChar(version, SizeOf(version), 0);
-	   version.major := _version shr 8;
-	   version.minor := _version and $ff;
-	   version.flags := _flags;
-	   version.cpu := _cpu and $ff;
-	   version.master_pic := _pic shr 8;
-	   version.slave_pic := _pic and $ff;
-	 end;
-      end;
-
-{*****************************************************************************
-                              Transfer Buffer
-*****************************************************************************}
-
-    function transfer_buffer: longint;
-      begin
-         transfer_buffer := go32_info_block.linear_address_of_transfer_buffer;
-      end;
-
-
-    function tb_segment: longint;
-      begin
-        tb_segment:=go32_info_block.linear_address_of_transfer_buffer shr 4;
-      end;
-
-
-    function tb_offset: longint;
-      begin
-        tb_offset:=go32_info_block.linear_address_of_transfer_buffer and $f;
-      end;
-
-
-    function tb_size: longint;
-      begin
-         tb_size := go32_info_block.size_of_transfer_buffer;
-      end;
-
-
-    procedure copytodos(var addr; len: longint);
-       begin
-          if len>tb_size then
-            runerror(217);
-          seg_move(get_ds,longint(@addr),dosmemselector,transfer_buffer,len);
-       end;
-
-
-    procedure copyfromdos(var addr; len: longint);
-       begin
-          if len>tb_size then
-            runerror(217);
-          seg_move(dosmemselector,transfer_buffer,get_ds,longint(@addr),len);
-       end;
-
-
-    var
-      _core_selector: word;external name '_core_selector';
-
-begin
-   int31error:=0;
-   dosmemselector:=_core_selector;
-end.

+ 1 - 1
packages/ptc/src/dos/timeunit/timeunit.pp

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the PTCPas framebuffer library
     This file is part of the PTCPas framebuffer library
-    Copyright (C) 2001-2010 Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2010, 2017 Nikolay Nikolov ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     modify it under the terms of the GNU Lesser General Public

+ 5 - 2
packages/ptc/src/ptc.pp

@@ -69,7 +69,7 @@ uses
 {$ENDIF FPDOC}
 {$ENDIF FPDOC}
 
 
 const
 const
-  PTCPAS_VERSION = 'PTCPas 0.99.14.1';
+  PTCPAS_VERSION = 'PTCPas 0.99.15';
 
 
 type
 type
   PUint8  = ^Uint8;
   PUint8  = ^Uint8;
@@ -117,7 +117,7 @@ implementation
 
 
 {$IFDEF GO32V2}
 {$IFDEF GO32V2}
 uses
 uses
-  textfx2, vesa, vga, cga, timeunit, crt, go32fix, mouse33h;
+  textfx2, vesa, vga, cga, timeunit, crt, go32, mouse33h;
 {$ENDIF GO32V2}
 {$ENDIF GO32V2}
 
 
 {$IF defined(WIN32) OR defined(WIN64)}
 {$IF defined(WIN32) OR defined(WIN64)}
@@ -150,6 +150,9 @@ uses
     {$IFDEF ENABLE_X11_EXTENSION_GLX}
     {$IFDEF ENABLE_X11_EXTENSION_GLX}
     , glx
     , glx
     {$ENDIF ENABLE_X11_EXTENSION_GLX}
     {$ENDIF ENABLE_X11_EXTENSION_GLX}
+    {$IFDEF ENABLE_X11_EXTENSION_XINPUT2}
+    , XI2, XInput2
+    {$ENDIF ENABLE_X11_EXTENSION_XINPUT2}
   {$ENDIF X11}
   {$ENDIF X11}
   {$IFDEF COCOA}
   {$IFDEF COCOA}
     , CocoaAll
     , CocoaAll

+ 240 - 0
packages/ptc/src/ptclaz.lpi

@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <General>
+      <Flags>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <MainUnitHasTitleStatement Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <Title Value="ptclaz"/>
+      <UseAppBundle Value="False"/>
+      <ResourceType Value="res"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+      </local>
+    </RunParams>
+    <Units Count="45">
+      <Unit0>
+        <Filename Value="ptclaz.lpr"/>
+        <IsPartOfProject Value="True"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="ptc.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="ptc"/>
+      </Unit1>
+      <Unit2>
+        <Filename Value="core/aread.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit2>
+      <Unit3>
+        <Filename Value="core/areai.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit3>
+      <Unit4>
+        <Filename Value="core/baseconsoled.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit4>
+      <Unit5>
+        <Filename Value="core/baseconsolei.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit5>
+      <Unit6>
+        <Filename Value="core/basesurfaced.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit6>
+      <Unit7>
+        <Filename Value="core/basesurfacei.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit7>
+      <Unit8>
+        <Filename Value="core/cleard.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit8>
+      <Unit9>
+        <Filename Value="core/cleari.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit9>
+      <Unit10>
+        <Filename Value="core/clipperd.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit10>
+      <Unit11>
+        <Filename Value="core/clipperi.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit11>
+      <Unit12>
+        <Filename Value="core/closeeventd.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit12>
+      <Unit13>
+        <Filename Value="core/closeeventi.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit13>
+      <Unit14>
+        <Filename Value="core/colord.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit14>
+      <Unit15>
+        <Filename Value="core/colori.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit15>
+      <Unit16>
+        <Filename Value="core/consoled.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit16>
+      <Unit17>
+        <Filename Value="core/consolei.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit17>
+      <Unit18>
+        <Filename Value="core/copyd.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit18>
+      <Unit19>
+        <Filename Value="core/copyi.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit19>
+      <Unit20>
+        <Filename Value="core/coreimplementation.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit20>
+      <Unit21>
+        <Filename Value="core/coreinterface.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit21>
+      <Unit22>
+        <Filename Value="core/errord.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit22>
+      <Unit23>
+        <Filename Value="core/errori.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit23>
+      <Unit24>
+        <Filename Value="core/eventd.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit24>
+      <Unit25>
+        <Filename Value="core/eventi.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit25>
+      <Unit26>
+        <Filename Value="core/formatd.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit26>
+      <Unit27>
+        <Filename Value="core/formati.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit27>
+      <Unit28>
+        <Filename Value="core/keyeventd.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit28>
+      <Unit29>
+        <Filename Value="core/keyeventi.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit29>
+      <Unit30>
+        <Filename Value="core/log.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit30>
+      <Unit31>
+        <Filename Value="core/moded.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit31>
+      <Unit32>
+        <Filename Value="core/modei.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit32>
+      <Unit33>
+        <Filename Value="core/mouseeventd.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit33>
+      <Unit34>
+        <Filename Value="core/mouseeventi.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit34>
+      <Unit35>
+        <Filename Value="core/openglattributesd.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit35>
+      <Unit36>
+        <Filename Value="core/openglattributesi.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit36>
+      <Unit37>
+        <Filename Value="core/paletted.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit37>
+      <Unit38>
+        <Filename Value="core/palettei.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit38>
+      <Unit39>
+        <Filename Value="core/resizeeventd.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit39>
+      <Unit40>
+        <Filename Value="core/resizeeventi.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit40>
+      <Unit41>
+        <Filename Value="core/surfaced.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit41>
+      <Unit42>
+        <Filename Value="core/surfacei.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit42>
+      <Unit43>
+        <Filename Value="core/timerd.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit43>
+      <Unit44>
+        <Filename Value="core/timeri.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit44>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <Target>
+      <Filename Value="ptclaz"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+      <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
+    </SearchPaths>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 6 - 0
packages/ptc/src/ptclaz.lpr

@@ -0,0 +1,6 @@
+program ptclaz;
+uses
+  ptc;
+begin
+end.
+

+ 6 - 0
packages/ptc/src/ptcpas.cfg

@@ -122,3 +122,9 @@
 #dga2
 #dga2
 #dga2 on
 #dga2 on
 #dga2 off
 #dga2 off
+#xinput2
+#xinput2 on
+#xinput2 off
+#xshm
+#xshm on
+#xshm off

+ 13 - 4
packages/ptc/src/win32/base/win32hook.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2003, 2006, 2007, 2009, 2010, 2012  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2003, 2006, 2007, 2009, 2010, 2012, 2017  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -104,7 +104,10 @@ begin
   if result = 0 then
   if result = 0 then
   begin
   begin
     { call original window procedure }
     { call original window procedure }
-    Result := CallWindowProc(WNDPROC(lookup^.wndproc), hwnd, msg, wParam, lParam);
+    if IsWindowUnicode(hwnd) then
+      Result := CallWindowProcW(WNDPROC(lookup^.wndproc), hwnd, msg, wParam, lParam)
+    else
+      Result := CallWindowProcA(WNDPROC(lookup^.wndproc), hwnd, msg, wParam, lParam);
   end;
   end;
 
 
   { leave monitor }
   { leave monitor }
@@ -189,7 +192,10 @@ begin
 {$ENDIF}
 {$ENDIF}
 
 
     { set window procedure to hook procedure }
     { set window procedure to hook procedure }
-    SetWindowLongPtr(AWindow, GWLP_WNDPROC, PtrInt(@TWin32Hook_hook));
+    if IsWindowUnicode(AWindow) then
+      SetWindowLongPtrW(AWindow, GWLP_WNDPROC, PtrInt(@TWin32Hook_hook))
+    else
+      SetWindowLongPtrA(AWindow, GWLP_WNDPROC, PtrInt(@TWin32Hook_hook));
   end;
   end;
 
 
   { leave monitor }
   { leave monitor }
@@ -236,7 +242,10 @@ begin
       if TWin32Hook_m_registry[index].count = 0 then
       if TWin32Hook_m_registry[index].count = 0 then
       begin
       begin
         { restore original window procedure }
         { restore original window procedure }
-        SetWindowLongPtr(AWindow, GWLP_WNDPROC, TWin32Hook_m_registry[i].wndproc);
+        if IsWindowUnicode(AWindow) then
+          SetWindowLongPtrW(AWindow, GWLP_WNDPROC, TWin32Hook_m_registry[i].wndproc)
+        else
+          SetWindowLongPtrA(AWindow, GWLP_WNDPROC, TWin32Hook_m_registry[i].wndproc);
 
 
         { remove this lookup (quite inefficient for high count...) }
         { remove this lookup (quite inefficient for high count...) }
         for i := index to TWin32Hook_Count - 2 do
         for i := index to TWin32Hook_Count - 2 do

+ 90 - 43
packages/ptc/src/win32/base/win32kbd.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2003, 2006, 2007, 2009-2012  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2003, 2006, 2007, 2009-2012, 2017  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -38,11 +38,6 @@ begin
   FMonitor := TWin32Monitor.Create;
   FMonitor := TWin32Monitor.Create;
   FEvent := TWin32Event.Create;
   FEvent := TWin32Event.Create;
 
 
-  { setup defaults }
-  FAlt := False;
-  FShift := False;
-  FControl := False;
-
   { setup data }
   { setup data }
   FEventQueue := AEventQueue;
   FEventQueue := AEventQueue;
   FMultithreaded := AMultithreaded;
   FMultithreaded := AMultithreaded;
@@ -71,9 +66,15 @@ begin
 end;
 end;
 
 
 function TWin32Keyboard.WndProc(hWnd: HWND; message: DWord; wParam: WPARAM; lParam: LPARAM): LRESULT;
 function TWin32Keyboard.WndProc(hWnd: HWND; message: DWord; wParam: WPARAM; lParam: LPARAM): LRESULT;
+const
+  {$warning move this to the windows unit! }
+  MAPVK_VK_TO_CHAR = 2;
+  MAPVK_VK_TO_VSC = 0;
+  MAPVK_VSC_TO_VK = 1;
+  MAPVK_VSC_TO_VK_EX = 3;
 var
 var
   i: Integer;
   i: Integer;
-  scancode: Integer;
+  scancode: UINT;
   KeyStateArray: array [0..255] of Byte;
   KeyStateArray: array [0..255] of Byte;
   AsciiBuf: Word;
   AsciiBuf: Word;
   press: Boolean;
   press: Boolean;
@@ -81,6 +82,8 @@ var
   TranslatedCharacters, TranslatedWideCharacters: Integer;
   TranslatedCharacters, TranslatedWideCharacters: Integer;
   WideStr: WideString;
   WideStr: WideString;
   KeyCode: Integer;
   KeyCode: Integer;
+  ExtendedKey, DeadKey: Boolean;
+  ModifierKeys: TPTCModifierKeys;
 begin
 begin
   Result := 0;
   Result := 0;
   { check enabled flag }
   { check enabled flag }
@@ -91,19 +94,54 @@ begin
   if (message = WM_KEYDOWN) or (message = WM_KEYUP) or (message = WM_SYSKEYDOWN) or (message = WM_SYSKEYUP) then
   if (message = WM_KEYDOWN) or (message = WM_KEYUP) or (message = WM_SYSKEYDOWN) or (message = WM_SYSKEYUP) then
   begin
   begin
     press := (message = WM_KEYDOWN) or (message = WM_SYSKEYDOWN);
     press := (message = WM_KEYDOWN) or (message = WM_SYSKEYDOWN);
+    ExtendedKey := (lParam and (1 shl 24)) <> 0;
+
+    ModifierKeys := [];
 
 
     { update modifiers }
     { update modifiers }
-    if wParam = VK_MENU then
-      { alt }
-      FAlt := press
-    else
-      if wParam = VK_SHIFT then
-        { shift }
-        FShift := press
-      else
-        if wParam = VK_CONTROL then
-          { control }
-          FControl := press;
+    { dead key? }
+    DeadKey := (MapVirtualKey(wParam, MAPVK_VK_TO_CHAR) and $80000000) <> 0;
+    if DeadKey then
+      Include(ModifierKeys, pmkDeadKey);
+    { alt }
+    if (GetKeyState(VK_MENU) and $8000) <> 0 then
+      Include(ModifierKeys, pmkAlt);
+    { shift }
+    if (GetKeyState(VK_SHIFT) and $8000) <> 0 then
+      Include(ModifierKeys, pmkShift);
+    { control }
+    if (GetKeyState(VK_CONTROL) and $8000) <> 0 then
+      Include(ModifierKeys, pmkControl);
+    { left/right alt }
+    if (GetKeyState(VK_LMENU) and $8000) <> 0 then
+      Include(ModifierKeys, pmkLeftAlt);
+    if (GetKeyState(VK_RMENU) and $8000) <> 0 then
+      Include(ModifierKeys, pmkRightAlt);
+    { left/right shift }
+    if (GetKeyState(VK_LSHIFT) and $8000) <> 0 then
+      Include(ModifierKeys, pmkLeftShift);
+    if (GetKeyState(VK_RSHIFT) and $8000) <> 0 then
+      Include(ModifierKeys, pmkRightShift);
+    { left/right control }
+    if (GetKeyState(VK_LCONTROL) and $8000) <> 0 then
+      Include(ModifierKeys, pmkLeftControl);
+    if (GetKeyState(VK_RCONTROL) and $8000) <> 0 then
+      Include(ModifierKeys, pmkRightControl);
+    { num lock }
+    if (GetKeyState(VK_NUMLOCK) and $8000) <> 0 then
+      Include(ModifierKeys, pmkNumLockPressed);
+    if (GetKeyState(VK_NUMLOCK) and 1) <> 0 then
+      Include(ModifierKeys, pmkNumLockActive);
+    { caps lock }
+    if (GetKeyState(VK_CAPITAL) and $8000) <> 0 then
+      Include(ModifierKeys, pmkCapsLockPressed);
+    if (GetKeyState(VK_CAPITAL) and 1) <> 0 then
+      Include(ModifierKeys, pmkCapsLockActive);
+    { scroll lock }
+    if (GetKeyState(VK_SCROLL) and $8000) <> 0 then
+      Include(ModifierKeys, pmkScrollLockPressed);
+    if (GetKeyState(VK_SCROLL) and 1) <> 0 then
+      Include(ModifierKeys, pmkScrollLockActive);
 
 
     { enter monitor if multithreaded }
     { enter monitor if multithreaded }
     if FMultithreaded then
     if FMultithreaded then
@@ -114,25 +152,48 @@ begin
     if GetKeyboardState(@KeyStateArray) then
     if GetKeyboardState(@KeyStateArray) then
     begin
     begin
       scancode := (lParam shr 16) and $FF;
       scancode := (lParam shr 16) and $FF;
-      {todo: ToUnicode (Windows NT)}
-      TranslatedCharacters := ToAscii(wParam, scancode, @KeyStateArray, @AsciiBuf, 0);
-      if (TranslatedCharacters = 1) or (TranslatedCharacters = 2) then
+      if not press then
+        scancode := scancode or $8000;
+      if IsWindowUnicode(hWnd) then
+      begin
+        SetLength(WideStr, 16);
+        TranslatedWideCharacters := ToUnicode(wParam, scancode, @KeyStateArray, @WideStr[1], Length(WideStr), 0);
+        if TranslatedWideCharacters <> -1 then
+          SetLength(WideStr, TranslatedWideCharacters)
+        else
+          WideStr := '';
+      end
+      else
       begin
       begin
-        TranslatedWideCharacters := MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, @AsciiBuf, TranslatedCharacters, nil, 0);
-        if TranslatedWideCharacters <> 0 then
+        TranslatedCharacters := ToAscii(wParam, scancode, @KeyStateArray, @AsciiBuf, 0);
+        if TranslatedCharacters > 0 then
         begin
         begin
+          TranslatedWideCharacters := MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, @AsciiBuf, TranslatedCharacters, nil, 0);
           SetLength(WideStr, TranslatedWideCharacters);
           SetLength(WideStr, TranslatedWideCharacters);
-          MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, @AsciiBuf, TranslatedCharacters, @WideStr[1], TranslatedWideCharacters);
-
-          if Length(WideStr) = 1 then
-            uni := Ord(WideStr[1]);
-        end;
+          if TranslatedWideCharacters <> 0 then
+            MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, @AsciiBuf, TranslatedCharacters, @WideStr[1], TranslatedWideCharacters);
+        end
+        else
+          WideStr := '';
       end;
       end;
+      if Length(WideStr) = 1 then
+        uni := Ord(WideStr[1]);
     end;
     end;
 
 
     KeyCode := wParam;
     KeyCode := wParam;
     if wParam = VK_RETURN then
     if wParam = VK_RETURN then
+    begin
       KeyCode := PTCKEY_ENTER;
       KeyCode := PTCKEY_ENTER;
+      if ExtendedKey then
+        Include(ModifierKeys, pmkNumPadKey);
+    end;
+    if not ExtendedKey and
+      (wParam in [VK_LEFT,VK_RIGHT,VK_UP,VK_DOWN,VK_INSERT,VK_DELETE,
+                  VK_HOME,VK_END,VK_PRIOR,VK_NEXT]) then
+      Include(ModifierKeys, pmkNumPadKey);
+    if wParam in [VK_CLEAR,VK_NUMPAD0..VK_NUMPAD9,VK_DECIMAL,VK_DIVIDE,
+                  VK_MULTIPLY,VK_SUBTRACT,VK_ADD,VK_NUMLOCK] then
+      Include(ModifierKeys, pmkNumPadKey);
     if wParam = VK_INSERT then
     if wParam = VK_INSERT then
       KeyCode := PTCKEY_INSERT;
       KeyCode := PTCKEY_INSERT;
     if wParam = VK_DELETE then
     if wParam = VK_DELETE then
@@ -145,7 +206,7 @@ begin
     { handle key repeat count }
     { handle key repeat count }
     for i := 1 to lParam and $FFFF do
     for i := 1 to lParam and $FFFF do
       { create and insert key object }
       { create and insert key object }
-      FEventQueue.AddEvent(TPTCKeyEvent.Create(KeyCode, uni, FAlt, FShift, FControl, press));
+      FEventQueue.AddEvent(TPTCKeyEvent.Create(KeyCode, uni, ModifierKeys, press));
 
 
     { check multithreaded flag }
     { check multithreaded flag }
     if FMultithreaded then
     if FMultithreaded then
@@ -157,18 +218,4 @@ begin
       FMonitor.Leave;
       FMonitor.Leave;
     end;
     end;
   end;
   end;
-(*  else
-    if message = WM_KEYUP then
-      { update modifiers }
-      if wParam = VK_MENU then
-        { alt up }
-        m_alt := False
-      else
-        if wParam = VK_SHIFT then
-          { shift up }
-          m_shift := False
-        else
-          if wParam = VK_CONTROL then
-            { control up }
-            m_control := False;*)
 end;
 end;

+ 1 - 6
packages/ptc/src/win32/base/win32kbdd.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2003, 2006, 2009, 2010  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2003, 2006, 2009, 2010, 2017  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -42,11 +42,6 @@ type
     { flag data }
     { flag data }
     FEnabled: Boolean;
     FEnabled: Boolean;
 
 
-    { modifiers }
-    FAlt: Boolean;
-    FShift: Boolean;
-    FControl: Boolean;
-
     { window procedure }
     { window procedure }
     function WndProc(hWnd: HWND; message: DWord; wParam: WPARAM; lParam: LPARAM): LRESULT; override;
     function WndProc(hWnd: HWND; message: DWord; wParam: WPARAM; lParam: LPARAM): LRESULT; override;
   public
   public

+ 2 - 1
packages/ptc/src/win32/base/win32moused.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2007, 2009, 2010, 2013  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2007, 2009, 2010, 2013, 2016  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -62,6 +62,7 @@ type
 
 
     procedure SetWindowArea(AWindowX1, AWindowY1, AWindowX2, AWindowY2: Integer);
     procedure SetWindowArea(AWindowX1, AWindowY1, AWindowX2, AWindowY2: Integer);
     procedure SetConsoleSize(AConsoleWidth, AConsoleHeight: Integer);
     procedure SetConsoleSize(AConsoleWidth, AConsoleHeight: Integer);
+    function MoveMouseTo(X, Y: Integer): Boolean;
 
 
     { control }
     { control }
     procedure Enable;
     procedure Enable;

+ 85 - 13
packages/ptc/src/win32/base/win32mousei.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2007, 2009, 2010, 2013  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2007, 2009, 2010, 2013, 2016  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -73,18 +73,48 @@ begin
   FEnabled := False;
   FEnabled := False;
 end;
 end;
 
 
+function TWin32Mouse.MoveMouseTo(X, Y: Integer): Boolean;
+var
+  WindowRect: RECT;
+  pt: TPOINT;
+begin
+  if (X < 0) or (X >= FConsoleWidth) or (Y <= 0) or (Y >= FConsoleHeight) then
+    exit(False);
+
+  if not FFullScreen then
+  begin
+    if not GetClientRect(FWindow, WindowRect) then
+      exit(False);
+
+    FWindowX1 := WindowRect.left;
+    FWindowY1 := WindowRect.top;
+    FWindowX2 := WindowRect.right - 1;
+    FWindowY2 := WindowRect.bottom - 1;
+  end;
+
+  pt.X := X * (FWindowX2 - FWindowX1) div (FConsoleWidth - 1) + FWindowX1;
+  pt.Y := Y * (FWindowY2 - FWindowY1) div (FConsoleHeight - 1) + FWindowY1;
+
+  if not ClientToScreen(FWindow, pt) then
+    exit(False);
+
+  Result := SetCursorPos(pt.X, pt.Y);
+end;
+
 function TWin32Mouse.WndProc(hWnd: HWND; message: DWord; wParam: WPARAM; lParam: LPARAM): LRESULT;
 function TWin32Mouse.WndProc(hWnd: HWND; message: DWord; wParam: WPARAM; lParam: LPARAM): LRESULT;
 var
 var
   fwKeys: Integer;
   fwKeys: Integer;
-  xPos, yPos: Integer;
-  LButton, MButton, RButton: Boolean;
+  CurPos: POINT;
+  LButton, MButton, RButton, XButton1, XButton2: Boolean;
   TranslatedXPos, TranslatedYPos: Integer;
   TranslatedXPos, TranslatedYPos: Integer;
   PTCMouseButtonState: TPTCMouseButtonState;
   PTCMouseButtonState: TPTCMouseButtonState;
   WindowRect: RECT;
   WindowRect: RECT;
+  ScrollAmount: Integer;
 
 
   button: TPTCMouseButton;
   button: TPTCMouseButton;
   before, after: Boolean;
   before, after: Boolean;
   cstate: TPTCMouseButtonState;
   cstate: TPTCMouseButtonState;
+  I: Integer;
 begin
 begin
   Result := 0;
   Result := 0;
   { check enabled flag }
   { check enabled flag }
@@ -94,15 +124,27 @@ begin
   if (message = WM_MOUSEMOVE) or
   if (message = WM_MOUSEMOVE) or
      (message = WM_LBUTTONDOWN) or (message = WM_LBUTTONUP) or (message = WM_LBUTTONDBLCLK) or
      (message = WM_LBUTTONDOWN) or (message = WM_LBUTTONUP) or (message = WM_LBUTTONDBLCLK) or
      (message = WM_MBUTTONDOWN) or (message = WM_MBUTTONUP) or (message = WM_MBUTTONDBLCLK) or
      (message = WM_MBUTTONDOWN) or (message = WM_MBUTTONUP) or (message = WM_MBUTTONDBLCLK) or
-     (message = WM_RBUTTONDOWN) or (message = WM_RBUTTONUP) or (message = WM_RBUTTONDBLCLK) then
+     (message = WM_RBUTTONDOWN) or (message = WM_RBUTTONUP) or (message = WM_RBUTTONDBLCLK) or
+     (message = WM_XBUTTONDOWN) or (message = WM_XBUTTONUP) or (message = WM_XBUTTONDBLCLK) or
+     (message = WM_MOUSEWHEEL) or (message = WM_MOUSEHWHEEL) then
   begin
   begin
-    fwKeys := wParam; {MK_LBUTTON or MK_MBUTTON or MK_RBUTTON or MK_CONTROL or MK_SHIFT}
-    xPos := lParam and $FFFF;
-    yPos := (lParam shr 16) and $FFFF;
+    fwKeys := Word(wParam); {MK_LBUTTON or MK_MBUTTON or MK_RBUTTON or MK_CONTROL or MK_SHIFT}
+    CurPos.x := GET_X_LPARAM(lParam);
+    CurPos.y := GET_Y_LPARAM(lParam);
+
+    if (message = WM_MOUSEWHEEL) or (message = WM_MOUSEHWHEEL) then
+    begin
+      ScrollAmount := SmallInt(wParam shr 16);
+      { for WM_MOUSEWHEEL and WM_MOUSEHWHEEL, windows returns cursor position in
+        screen coordinates, instead of client coordinates, so convert them }
+      ScreenToClient(hWnd, CurPos);
+    end;
 
 
     LButton := (fwKeys and MK_LBUTTON) <> 0;
     LButton := (fwKeys and MK_LBUTTON) <> 0;
     MButton := (fwKeys and MK_MBUTTON) <> 0;
     MButton := (fwKeys and MK_MBUTTON) <> 0;
     RButton := (fwKeys and MK_RBUTTON) <> 0;
     RButton := (fwKeys and MK_RBUTTON) <> 0;
+    XButton1 := (fwKeys and MK_XBUTTON1) <> 0;
+    XButton2 := (fwKeys and MK_XBUTTON2) <> 0;
 
 
     if not FFullScreen then
     if not FFullScreen then
     begin
     begin
@@ -114,16 +156,16 @@ begin
       FWindowY2 := WindowRect.bottom - 1;
       FWindowY2 := WindowRect.bottom - 1;
     end;
     end;
 
 
-    if (xPos >= FWindowX1) and (yPos >= FWindowY1) and
-       (xPos <= FWindowX2) and (yPos <= FWindowY2) then
+    if (CurPos.x >= FWindowX1) and (CurPos.y >= FWindowY1) and
+       (CurPos.x <= FWindowX2) and (CurPos.y <= FWindowY2) then
     begin
     begin
       if FWindowX2 <> FWindowX1 then
       if FWindowX2 <> FWindowX1 then
-        TranslatedXPos := (xPos - FWindowX1) * (FConsoleWidth  - 1) div (FWindowX2 - FWindowX1)
+        TranslatedXPos := (CurPos.x - FWindowX1) * (FConsoleWidth  - 1) div (FWindowX2 - FWindowX1)
       else { avoid div by zero }
       else { avoid div by zero }
         TranslatedXPos := 0;
         TranslatedXPos := 0;
 
 
       if FWindowY2 <> FWindowY1 then
       if FWindowY2 <> FWindowY1 then
-        TranslatedYPos := (yPos - FWindowY1) * (FConsoleHeight - 1) div (FWindowY2 - FWindowY1)
+        TranslatedYPos := (CurPos.y - FWindowY1) * (FConsoleHeight - 1) div (FWindowY2 - FWindowY1)
       else { avoid div by zero }
       else { avoid div by zero }
         TranslatedYPos := 0;
         TranslatedYPos := 0;
 
 
@@ -141,12 +183,14 @@ begin
         PTCMouseButtonState := []
         PTCMouseButtonState := []
       else
       else
         PTCMouseButtonState := [PTCMouseButton1];
         PTCMouseButtonState := [PTCMouseButton1];
-
       if RButton then
       if RButton then
         PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton2];
         PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton2];
-
       if MButton then
       if MButton then
         PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton3];
         PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton3];
+      if XButton1 then
+        PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton8];
+      if XButton2 then
+        PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton9];
 
 
       if not FPreviousMousePositionSaved then
       if not FPreviousMousePositionSaved then
       begin
       begin
@@ -180,6 +224,34 @@ begin
           end;
           end;
       end;
       end;
 
 
+      { scroll wheel? }
+      if (message = WM_MOUSEWHEEL) and (Abs(ScrollAmount) >= WHEEL_DELTA) then
+        if ScrollAmount > 0 then
+          for I := 1 to ScrollAmount div WHEEL_DELTA do
+          begin
+            FEventQueue.AddEvent(TPTCMouseButtonEvent.Create(TranslatedXPos, TranslatedYPos, 0, 0, cstate + [PTCMouseButton4], True, PTCMouseButton4));
+            FEventQueue.AddEvent(TPTCMouseButtonEvent.Create(TranslatedXPos, TranslatedYPos, 0, 0, cstate, False, PTCMouseButton4));
+          end
+        else
+          for I := 1 to Abs(ScrollAmount) div WHEEL_DELTA do
+          begin
+            FEventQueue.AddEvent(TPTCMouseButtonEvent.Create(TranslatedXPos, TranslatedYPos, 0, 0, cstate + [PTCMouseButton5], True, PTCMouseButton5));
+            FEventQueue.AddEvent(TPTCMouseButtonEvent.Create(TranslatedXPos, TranslatedYPos, 0, 0, cstate, False, PTCMouseButton5));
+          end;
+      if (message = WM_MOUSEHWHEEL) and (Abs(ScrollAmount) >= WHEEL_DELTA) then
+        if ScrollAmount > 0 then
+          for I := 1 to ScrollAmount div WHEEL_DELTA do
+          begin
+            FEventQueue.AddEvent(TPTCMouseButtonEvent.Create(TranslatedXPos, TranslatedYPos, 0, 0, cstate + [PTCMouseButton7], True, PTCMouseButton7));
+            FEventQueue.AddEvent(TPTCMouseButtonEvent.Create(TranslatedXPos, TranslatedYPos, 0, 0, cstate, False, PTCMouseButton7));
+          end
+        else
+          for I := 1 to Abs(ScrollAmount) div WHEEL_DELTA do
+          begin
+            FEventQueue.AddEvent(TPTCMouseButtonEvent.Create(TranslatedXPos, TranslatedYPos, 0, 0, cstate + [PTCMouseButton6], True, PTCMouseButton6));
+            FEventQueue.AddEvent(TPTCMouseButtonEvent.Create(TranslatedXPos, TranslatedYPos, 0, 0, cstate, False, PTCMouseButton6));
+          end;
+
       FPreviousMouseX := TranslatedXPos;
       FPreviousMouseX := TranslatedXPos;
       FPreviousMouseY := TranslatedYPos;
       FPreviousMouseY := TranslatedYPos;
       FPreviousMouseButtonState := PTCMouseButtonState;
       FPreviousMouseButtonState := PTCMouseButtonState;

+ 160 - 52
packages/ptc/src/win32/base/win32window.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2003, 2006, 2007, 2009-2012  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2003, 2006, 2007, 2009-2012, 2016, 2017  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -46,6 +46,8 @@ begin
   defaults;
   defaults;
   FWindow := window;
   FWindow := window;
   FManaged := False;
   FManaged := False;
+  FIsUnicode := IsWindowUnicode(window);
+  LOG('IsUnicode', IsUnicode);
 end;
 end;
 
 
 function WndProcSingleThreaded(hWnd: HWND; message: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; forward;
 function WndProcSingleThreaded(hWnd: HWND; message: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; forward;
@@ -59,33 +61,73 @@ var
   rectangle: RECT;
   rectangle: RECT;
   display_width, display_height: Integer;
   display_width, display_height: Integer;
   wc: WNDCLASSEXA;
   wc: WNDCLASSEXA;
+  wcw: WNDCLASSEXW;
+  WinVer: OSVERSIONINFO;
+  AWndClassW, ATitleW: WideString;
 begin
 begin
   LOG('creating managed window');
   LOG('creating managed window');
   Defaults;
   Defaults;
   FMultithreaded := AMultithreaded;
   FMultithreaded := AMultithreaded;
   try
   try
+    FillChar(WinVer, SizeOf(WinVer), 0);
+    WinVer.dwOSVersionInfoSize := SizeOf(WinVer);
+    if not GetVersionEx(WinVer) then
+      raise TPTCError.Create('GetVersionEx failed');
+    { Win32s on Windows 3.1 and Win32 on Windows 95/98/ME don't support unicode }
+    FIsUnicode := (WinVer.dwPlatformId <> VER_PLATFORM_WIN32s) and
+      (WinVer.dwPlatformId <> VER_PLATFORM_WIN32_WINDOWS);
+    LOG('IsUnicode', IsUnicode);
+
     FInterceptClose := AInterceptClose;
     FInterceptClose := AInterceptClose;
     program_instance := GetModuleHandle(nil);
     program_instance := GetModuleHandle(nil);
 {    library_instance := program_instance;}
 {    library_instance := program_instance;}
-    wc.cbSize := SizeOf(wc);
-    wc.hInstance := program_instance;
-    wc.lpszClassName := PChar(AWndClass);
-    wc.style := AClassStyle;
-    wc.hIcon := 0{LoadIcon(library_instance, 'IDI_PTC_ICON')};
-    wc.hIconSm := 0;
-    wc.lpszMenuName := nil;
-    wc.cbClsExtra := 0;
-    wc.cbWndExtra := 0;
-    wc.hbrBackground := 0;{(HBRUSH) GetStockObject(BLACK_BRUSH)}
-    if AMultithreaded then
-      wc.lpfnWndProc := @WndProcMultiThreaded
-    else
-      wc.lpfnWndProc := @WndProcSingleThreaded;
-    if ACursor then
-      wc.hCursor := LoadCursor(0, IDC_ARROW)
+    if IsUnicode then
+    begin
+      AWndClassW := AWndClass;
+      ATitleW := ATitle;
+
+      wcw.cbSize := SizeOf(wcw);
+      wcw.hInstance := program_instance;
+      wcw.lpszClassName := PWideChar(AWndClassW);
+      wcw.style := AClassStyle;
+      wcw.hIcon := 0{LoadIcon(library_instance, 'IDI_PTC_ICON')};
+      wcw.hIconSm := 0;
+      wcw.lpszMenuName := nil;
+      wcw.cbClsExtra := 0;
+      wcw.cbWndExtra := 0;
+      wcw.hbrBackground := 0;{(HBRUSH) GetStockObject(BLACK_BRUSH)}
+      if AMultithreaded then
+        wcw.lpfnWndProc := @WndProcMultiThreaded
+      else
+        wcw.lpfnWndProc := @WndProcSingleThreaded;
+      if ACursor then
+        wcw.hCursor := LoadCursorW(0, PWideChar(IDC_ARROW))
+      else
+        wcw.hCursor := 0;
+      RegisterClassExW(wcw);
+    end
     else
     else
-      wc.hCursor := 0;
-    RegisterClassExA(wc);
+    begin
+      wc.cbSize := SizeOf(wc);
+      wc.hInstance := program_instance;
+      wc.lpszClassName := PChar(AWndClass);
+      wc.style := AClassStyle;
+      wc.hIcon := 0{LoadIcon(library_instance, 'IDI_PTC_ICON')};
+      wc.hIconSm := 0;
+      wc.lpszMenuName := nil;
+      wc.cbClsExtra := 0;
+      wc.cbWndExtra := 0;
+      wc.hbrBackground := 0;{(HBRUSH) GetStockObject(BLACK_BRUSH)}
+      if AMultithreaded then
+        wc.lpfnWndProc := @WndProcMultiThreaded
+      else
+        wc.lpfnWndProc := @WndProcSingleThreaded;
+      if ACursor then
+        wc.hCursor := LoadCursorA(0, IDC_ARROW)
+      else
+        wc.hCursor := 0;
+      RegisterClassExA(wc);
+    end;
     with rectangle do
     with rectangle do
     begin
     begin
       left := 0;
       left := 0;
@@ -117,7 +159,10 @@ begin
     end
     end
     else
     else
     begin
     begin
-      FWindow := CreateWindowExA(FExtra, PChar(FName), PChar(FTitle), FStyle, FX, FY, FWidth, FHeight, 0, 0, 0, Self);
+      if IsUnicode then
+        FWindow := CreateWindowExW(FExtra, PWideChar(AWndClassW), PWideChar(ATitleW), FStyle, FX, FY, FWidth, FHeight, 0, 0, 0, Self)
+      else
+        FWindow := CreateWindowExA(FExtra, PChar(FName), PChar(FTitle), FStyle, FX, FY, FWidth, FHeight, 0, 0, 0, Self);
       if not IsWindow(FWindow) then
       if not IsWindow(FWindow) then
         raise TPTCError.Create('could not create window');
         raise TPTCError.Create('could not create window');
       ShowWindow(FWindow, FShow);
       ShowWindow(FWindow, FShow);
@@ -140,16 +185,20 @@ end;
 procedure TWin32Window.Cursor(AFlag: Boolean);
 procedure TWin32Window.Cursor(AFlag: Boolean);
 begin
 begin
   if AFlag then
   if AFlag then
-  begin
-//    SetClassLong(FWindow, GCL_HCURSOR, LoadCursor(0, IDC_ARROW));
-    SetClassLongPtr(FWindow, GCLP_HCURSOR, LoadCursor(0, IDC_ARROW));
-  end
+    if IsUnicode then
+      SetClassLongPtrW(FWindow, GCLP_HCURSOR, LoadCursorW(0, PWideChar(IDC_ARROW)))
+    else
+      SetClassLongPtrA(FWindow, GCLP_HCURSOR, LoadCursorA(0, IDC_ARROW))
   else
   else
-  begin
-//    SetClassLong(FWindow, GCL_HCURSOR, 0);
-    SetClassLongPtr(FWindow, GCLP_HCURSOR, 0);
-  end;
-  SendMessage(FWindow, WM_SETCURSOR, 0, 0);
+    if IsUnicode then
+      SetClassLongPtrW(FWindow, GCLP_HCURSOR, 0)
+    else
+      SetClassLongPtrA(FWindow, GCLP_HCURSOR, 0);
+
+  if IsUnicode then
+    SendMessageW(FWindow, WM_SETCURSOR, 0, 0)
+  else
+    SendMessageA(FWindow, WM_SETCURSOR, 0, 0);
 end;
 end;
 
 
 procedure TWin32Window.ConfineCursor(AFlag: Boolean);
 procedure TWin32Window.ConfineCursor(AFlag: Boolean);
@@ -216,18 +265,43 @@ begin
     { updated to pump all window messages, and not just for our FWindow;
     { updated to pump all window messages, and not just for our FWindow;
       this fixes keyboard layout switching and maybe other bugs and side effects...
       this fixes keyboard layout switching and maybe other bugs and side effects...
       Seems like Windows wants everything pumped :) }
       Seems like Windows wants everything pumped :) }
+
+    { TranslateMessage isn't called, because it's incompatible with the
+      ToAscii/ToUnicode functions, which we use for translating keys to
+      characters. Both ToAscii/ToUnicode and TranslateMessage modify the kernel
+      key state, in such a way, which assumes that only one of these functions
+      is called per key event, so when both are called, they kill the dead key
+      support (because the dead key pressed state is toggled twice or something
+      like that). TODO: maybe we should call TranslateMessage for windows, which
+      aren't managed by us? }
     if AWaitForMessage then
     if AWaitForMessage then
     begin
     begin
-      GetMessage(message, {FWindow}0, 0, 0);
-      TranslateMessage(message);
-      DispatchMessage(message);
-    end
-    else
-      while PeekMessage(message, {FWindow}0, 0, 0, PM_REMOVE) do
+      if IsUnicode then
       begin
       begin
-        TranslateMessage(message);
-        DispatchMessage(message);
+        GetMessageW(message, {FWindow}0, 0, 0);
+        //TranslateMessage(message);
+        DispatchMessageW(message);
+      end
+      else
+      begin
+        GetMessageA(message, {FWindow}0, 0, 0);
+        //TranslateMessage(message);
+        DispatchMessageA(message);
       end;
       end;
+    end
+    else
+      if IsUnicode then
+        while PeekMessageW(message, {FWindow}0, 0, 0, PM_REMOVE) do
+        begin
+          //TranslateMessage(message);
+          DispatchMessageW(message);
+        end
+      else
+        while PeekMessageA(message, {FWindow}0, 0, 0, PM_REMOVE) do
+        begin
+          //TranslateMessage(message);
+          DispatchMessageA(message);
+        end;
   end
   end
   else
   else
     Sleep(0);
     Sleep(0);
@@ -251,7 +325,10 @@ begin
       begin
       begin
         pCreate := PCREATESTRUCT(lParam);
         pCreate := PCREATESTRUCT(lParam);
         WindowObject := TWin32Window(pCreate^.lpCreateParams);
         WindowObject := TWin32Window(pCreate^.lpCreateParams);
-        SetWindowLongPtr(hWnd, GWLP_USERDATA, LONG_PTR(WindowObject));
+        if IsWindowUnicode(hWnd) then
+          SetWindowLongPtrW(hWnd, GWLP_USERDATA, LONG_PTR(WindowObject))
+        else
+          SetWindowLongPtrA(hWnd, GWLP_USERDATA, LONG_PTR(WindowObject));
         Result := WindowObject.WMCreate(hWnd, message, wParam, lParam);
         Result := WindowObject.WMCreate(hWnd, message, wParam, lParam);
       end;
       end;
     WM_DESTROY:
     WM_DESTROY:
@@ -259,22 +336,35 @@ begin
         WindowObject := TWin32Window(GetWindowLongPtr(hWnd, GWLP_USERDATA));
         WindowObject := TWin32Window(GetWindowLongPtr(hWnd, GWLP_USERDATA));
         Result := WindowObject.WMDestroy(hWnd, message, wParam, lParam);
         Result := WindowObject.WMDestroy(hWnd, message, wParam, lParam);
       end;
       end;
+    WM_MOUSEMOVE,
+    WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK,
+    WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MBUTTONDBLCLK,
+    WM_RBUTTONDOWN, WM_RBUTTONUP, WM_RBUTTONDBLCLK,
+    WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK,
+    WM_MOUSEWHEEL, WM_MOUSEHWHEEL:
+      Result := 0;
     WM_SYSCOMMAND:
     WM_SYSCOMMAND:
       begin
       begin
         { this fixes the pausing of the application when the Alt or F10 key is pressed }
         { this fixes the pausing of the application when the Alt or F10 key is pressed }
         if wParam = SC_KEYMENU then
         if wParam = SC_KEYMENU then
-	  Result := 0
-	else
-          Result := DefWindowProcA(hWnd, message, wParam, lParam);
+          Result := 0
+        else
+          if IsWindowUnicode(hWnd) then
+            Result := DefWindowProcW(hWnd, message, wParam, lParam)
+          else
+            Result := DefWindowProcA(hWnd, message, wParam, lParam);
       end;
       end;
     WM_SETCURSOR: begin
     WM_SETCURSOR: begin
       if (LOWORD(lParam) = HTCLIENT) and (GetClassLongPtr(hWnd, GCLP_HCURSOR) = 0) then
       if (LOWORD(lParam) = HTCLIENT) and (GetClassLongPtr(hWnd, GCLP_HCURSOR) = 0) then
       begin
       begin
         SetCursor(0);
         SetCursor(0);
-	Result := 1;
+        Result := 1;
       end
       end
       else
       else
-        Result := DefWindowProcA(hWnd, message, wParam, lParam);
+        if IsWindowUnicode(hWnd) then
+          Result := DefWindowProcW(hWnd, message, wParam, lParam)
+        else
+          Result := DefWindowProcA(hWnd, message, wParam, lParam);
     end;
     end;
     WM_CLOSE: begin
     WM_CLOSE: begin
       LOG('TWin32Window WM_CLOSE');
       LOG('TWin32Window WM_CLOSE');
@@ -285,7 +375,10 @@ begin
         Halt(0);
         Halt(0);
     end;
     end;
     else
     else
-      Result := DefWindowProcA(hWnd, message, wParam, lParam);
+      if IsWindowUnicode(hWnd) then
+        Result := DefWindowProcW(hWnd, message, wParam, lParam)
+      else
+        Result := DefWindowProcA(hWnd, message, wParam, lParam);
   end;
   end;
 end;
 end;
 
 
@@ -297,18 +390,24 @@ begin
       begin
       begin
         { this fixes the pausing of the application when the Alt or F10 key is pressed }
         { this fixes the pausing of the application when the Alt or F10 key is pressed }
         if wParam = SC_KEYMENU then
         if wParam = SC_KEYMENU then
-	  Result := 0
-	else
-          Result := DefWindowProcA(hWnd, message, wParam, lParam);
+          Result := 0
+        else
+          if IsWindowUnicode(hWnd) then
+            Result := DefWindowProcW(hWnd, message, wParam, lParam)
+          else
+            Result := DefWindowProcA(hWnd, message, wParam, lParam);
       end;
       end;
     WM_SETCURSOR: begin
     WM_SETCURSOR: begin
       if (LOWORD(lParam) = HTCLIENT) and (GetClassLongPtr(hWnd, GCLP_HCURSOR) = 0) then
       if (LOWORD(lParam) = HTCLIENT) and (GetClassLongPtr(hWnd, GCLP_HCURSOR) = 0) then
       begin
       begin
         SetCursor(0);
         SetCursor(0);
-	Result := 1;
+        Result := 1;
       end
       end
       else
       else
-        Result := DefWindowProcA(hWnd, message, wParam, lParam);
+        if IsWindowUnicode(hWnd) then
+          Result := DefWindowProcW(hWnd, message, wParam, lParam)
+        else
+          Result := DefWindowProcA(hWnd, message, wParam, lParam);
     end;
     end;
     WM_DESTROY: begin
     WM_DESTROY: begin
       LOG('TWin32Window WM_DESTROY');
       LOG('TWin32Window WM_DESTROY');
@@ -319,7 +418,10 @@ begin
       Halt(0);
       Halt(0);
     end;
     end;
     else
     else
-      Result := DefWindowProcA(hWnd, message, wParam, lParam);
+      if IsWindowUnicode(hWnd) then
+        Result := DefWindowProcW(hWnd, message, wParam, lParam)
+      else
+        Result := DefWindowProcA(hWnd, message, wParam, lParam);
   end;
   end;
 end;
 end;
 
 
@@ -406,10 +508,16 @@ end;
 
 
 function TWin32Window.WMCreate(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
 function TWin32Window.WMCreate(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
 begin
 begin
-  Result := DefWindowProcA(hWnd, uMsg, wParam, lParam);
+  if IsUnicode then
+    Result := DefWindowProcW(hWnd, uMsg, wParam, lParam)
+  else
+    Result := DefWindowProcA(hWnd, uMsg, wParam, lParam);
 end;
 end;
 
 
 function TWin32Window.WMDestroy(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
 function TWin32Window.WMDestroy(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
 begin
 begin
-  Result := DefWindowProcA(hWnd, uMsg, wParam, lParam);
+  if IsUnicode then
+    Result := DefWindowProcW(hWnd, uMsg, wParam, lParam)
+  else
+    Result := DefWindowProcA(hWnd, uMsg, wParam, lParam);
 end;
 end;

+ 3 - 1
packages/ptc/src/win32/base/win32windowd.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2003, 2006, 2007, 2009, 2010, 2012  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2003, 2006, 2007, 2009, 2010, 2012, 2017  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -48,6 +48,7 @@ type
     FMultithreaded: Boolean;
     FMultithreaded: Boolean;
     FCursorConfineInEffect: Boolean;
     FCursorConfineInEffect: Boolean;
     FInterceptClose: Boolean;
     FInterceptClose: Boolean;
+    FIsUnicode: Boolean;
 
 
 {    class function WndProcSingleThreaded(hWnd: HWND; message: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; StdCall;
 {    class function WndProcSingleThreaded(hWnd: HWND; message: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; StdCall;
     class function WndProcMultiThreaded(hWnd: HWND; message: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; StdCall;}
     class function WndProcMultiThreaded(hWnd: HWND; message: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; StdCall;}
@@ -73,4 +74,5 @@ type
     property Managed: Boolean read FManaged;
     property Managed: Boolean read FManaged;
     property Multithreaded: Boolean read FMultithreaded;
     property Multithreaded: Boolean read FMultithreaded;
     property InterceptClose: Boolean read FInterceptClose write FInterceptClose;
     property InterceptClose: Boolean read FInterceptClose write FInterceptClose;
+    property IsUnicode: Boolean read FIsUnicode;
   end;
   end;

+ 1 - 1
packages/ptc/src/win32/directx/p_ddraw.pp

@@ -2967,7 +2967,7 @@ const
 (*
 (*
  * DirectDraw supports deinterlacing of overlay surfaces
  * DirectDraw supports deinterlacing of overlay surfaces
  *)
  *)
-  DDFXCAPS_OVERLAYDEINTERLACE		= $20000000;
+  DDFXCAPS_OVERLAYDEINTERLACE     = $20000000;
 
 
 (*
 (*
  * Driver can do alpha blending for blits.
  * Driver can do alpha blending for blits.

+ 4829 - 0
packages/ptc/src/win32/directx/p_dinput.pp

@@ -0,0 +1,4829 @@
+(****************************************************************************
+ *
+ *  Copyright (C) 1996-2002 Microsoft Corporation.  All Rights Reserved.
+ *
+ *  File:       dinput.h
+ *  Content:    DirectInput include file
+ *
+ ****************************************************************************)
+
+unit p_dinput;
+
+{$MODE objfpc}{$H+}
+{$MACRO on}
+{$PACKRECORDS c}
+
+{$MODESWITCH NESTEDCOMMENTS-}
+
+interface
+
+uses
+  windows;
+
+//#ifndef __DINPUT_INCLUDED__
+//#define __DINPUT_INCLUDED__
+//
+//#include <winapifamily.h>
+//
+//#ifndef DIJ_RINGZERO
+//
+//#ifdef _WIN32
+//#define COM_NO_WINDOWS_H
+//#include <objbase.h>
+//#endif
+//
+//#endif /* DIJ_RINGZERO */
+//
+//#ifdef __cplusplus
+//extern "C" {
+//#endif
+//
+//
+//#pragma region Desktop Family
+//#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+
+
+
+
+
+(*
+ *  To build applications for older versions of DirectInput
+ *
+ *  #define DIRECTINPUT_VERSION [ 0x0300 | 0x0500 | 0x0700 ]
+ *
+ *  before #include <dinput.h>.  By default, #include <dinput.h>
+ *  will produce a DirectX 8-compatible header file.
+ *
+ *)
+
+{$DEFINE DIRECTINPUT_HEADER_VERSION:=$0800}
+{$IFNDEF DIRECTINPUT_VERSION}
+{$DEFINE DIRECTINPUT_VERSION:=DIRECTINPUT_HEADER_VERSION}
+//#pragma message(__FILE__ ": DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800")
+{$ENDIF}
+
+//#ifndef DIJ_RINGZERO
+
+(****************************************************************************
+ *
+ *      Class IDs
+ *
+ ****************************************************************************)
+
+const
+  CLSID_DirectInput       : TGuid = '{25E609E0-B259-11CF-BFC7-444553540000}';
+  CLSID_DirectInputDevice : TGuid = '{25E609E1-B259-11CF-BFC7-444553540000}';
+
+  CLSID_DirectInput8      : TGuid = '{25E609E4-B259-11CF-BFC7-444553540000}';
+  CLSID_DirectInputDevice8: TGuid = '{25E609E5-B259-11CF-BFC7-444553540000}';
+
+(****************************************************************************
+ *
+ *      Interfaces
+ *
+ ****************************************************************************)
+
+  IID_IDirectInputA       : TIID = '{89521360-AA8A-11CF-BFC7-444553540000}';
+  IID_IDirectInputW       : TIID = '{89521361-AA8A-11CF-BFC7-444553540000}';
+  IID_IDirectInput2A      : TIID = '{5944E662-AA8A-11CF-BFC7-444553540000}';
+  IID_IDirectInput2W      : TIID = '{5944E663-AA8A-11CF-BFC7-444553540000}';
+  IID_IDirectInput7A      : TIID = '{9A4CB684-236D-11D3-8E9D-00C04F6844AE}';
+  IID_IDirectInput7W      : TIID = '{9A4CB685-236D-11D3-8E9D-00C04F6844AE}';
+  IID_IDirectInput8A      : TIID = '{BF798030-483A-4DA2-AA99-5D64ED369700}';
+  IID_IDirectInput8W      : TIID = '{BF798031-483A-4DA2-AA99-5D64ED369700}';
+  IID_IDirectInputDeviceA : TIID = '{5944E680-C92E-11CF-BFC7-444553540000}';
+  IID_IDirectInputDeviceW : TIID = '{5944E681-C92E-11CF-BFC7-444553540000}';
+  IID_IDirectInputDevice2A: TIID = '{5944E682-C92E-11CF-BFC7-444553540000}';
+  IID_IDirectInputDevice2W: TIID = '{5944E683-C92E-11CF-BFC7-444553540000}';
+  IID_IDirectInputDevice7A: TIID = '{57D7C6BC-2356-11D3-8E9D-00C04F6844AE}';
+  IID_IDirectInputDevice7W: TIID = '{57D7C6BD-2356-11D3-8E9D-00C04F6844AE}';
+  IID_IDirectInputDevice8A: TIID = '{54D41080-DC15-4833-A41B-748F73A38179}';
+  IID_IDirectInputDevice8W: TIID = '{54D41081-DC15-4833-A41B-748F73A38179}';
+  IID_IDirectInputEffect  : TIID = '{E7E1F7C0-88D2-11D0-9AD0-00A0C9A06E35}';
+
+(****************************************************************************
+ *
+ *      Predefined object types
+ *
+ ****************************************************************************)
+
+  GUID_XAxis  : TGuid = '{A36D02E0-C9F3-11CF-BFC7-444553540000}';
+  GUID_YAxis  : TGuid = '{A36D02E1-C9F3-11CF-BFC7-444553540000}';
+  GUID_ZAxis  : TGuid = '{A36D02E2-C9F3-11CF-BFC7-444553540000}';
+  GUID_RxAxis : TGuid = '{A36D02F4-C9F3-11CF-BFC7-444553540000}';
+  GUID_RyAxis : TGuid = '{A36D02F5-C9F3-11CF-BFC7-444553540000}';
+  GUID_RzAxis : TGuid = '{A36D02E3-C9F3-11CF-BFC7-444553540000}';
+  GUID_Slider : TGuid = '{A36D02E4-C9F3-11CF-BFC7-444553540000}';
+
+  GUID_Button : TGuid = '{A36D02F0-C9F3-11CF-BFC7-444553540000}';
+  GUID_Key    : TGuid = '{55728220-D33C-11CF-BFC7-444553540000}';
+
+  GUID_POV    : TGuid = '{A36D02F2-C9F3-11CF-BFC7-444553540000}';
+
+  GUID_Unknown: TGuid = '{A36D02F3-C9F3-11CF-BFC7-444553540000}';
+
+(****************************************************************************
+ *
+ *      Predefined product GUIDs
+ *
+ ****************************************************************************)
+
+  GUID_SysMouse      : TGuid = '{6F1D2B60-D5A0-11CF-BFC7-444553540000}';
+  GUID_SysKeyboard   : TGuid = '{6F1D2B61-D5A0-11CF-BFC7-444553540000}';
+  GUID_Joystick      : TGuid = '{6F1D2B70-D5A0-11CF-BFC7-444553540000}';
+  GUID_SysMouseEm    : TGuid = '{6F1D2B80-D5A0-11CF-BFC7-444553540000}';
+  GUID_SysMouseEm2   : TGuid = '{6F1D2B81-D5A0-11CF-BFC7-444553540000}';
+  GUID_SysKeyboardEm : TGuid = '{6F1D2B82-D5A0-11CF-BFC7-444553540000}';
+  GUID_SysKeyboardEm2: TGuid = '{6F1D2B83-D5A0-11CF-BFC7-444553540000}';
+
+(****************************************************************************
+ *
+ *      Predefined force feedback effects
+ *
+ ****************************************************************************)
+
+  GUID_ConstantForce: TGuid = '{13541C20-8E33-11D0-9AD0-00A0C9A06E35}';
+  GUID_RampForce    : TGuid = '{13541C21-8E33-11D0-9AD0-00A0C9A06E35}';
+  GUID_Square       : TGuid = '{13541C22-8E33-11D0-9AD0-00A0C9A06E35}';
+  GUID_Sine         : TGuid = '{13541C23-8E33-11D0-9AD0-00A0C9A06E35}';
+  GUID_Triangle     : TGuid = '{13541C24-8E33-11D0-9AD0-00A0C9A06E35}';
+  GUID_SawtoothUp   : TGuid = '{13541C25-8E33-11D0-9AD0-00A0C9A06E35}';
+  GUID_SawtoothDown : TGuid = '{13541C26-8E33-11D0-9AD0-00A0C9A06E35}';
+  GUID_Spring       : TGuid = '{13541C27-8E33-11D0-9AD0-00A0C9A06E35}';
+  GUID_Damper       : TGuid = '{13541C28-8E33-11D0-9AD0-00A0C9A06E35}';
+  GUID_Inertia      : TGuid = '{13541C29-8E33-11D0-9AD0-00A0C9A06E35}';
+  GUID_Friction     : TGuid = '{13541C2A-8E33-11D0-9AD0-00A0C9A06E35}';
+  GUID_CustomForce  : TGuid = '{13541C2B-8E33-11D0-9AD0-00A0C9A06E35}';
+
+//#endif /* DIJ_RINGZERO */
+
+(****************************************************************************
+ *
+ *      Interfaces and Structures...
+ *
+ ****************************************************************************)
+
+{$IF DIRECTINPUT_VERSION >= $0500}
+
+(****************************************************************************
+ *
+ *      IDirectInputEffect
+ *
+ ****************************************************************************)
+
+  DIEFT_ALL                = $00000000;
+
+  DIEFT_CONSTANTFORCE      = $00000001;
+  DIEFT_RAMPFORCE          = $00000002;
+  DIEFT_PERIODIC           = $00000003;
+  DIEFT_CONDITION          = $00000004;
+  DIEFT_CUSTOMFORCE        = $00000005;
+  DIEFT_HARDWARE           = $000000FF;
+  DIEFT_FFATTACK           = $00000200;
+  DIEFT_FFFADE             = $00000400;
+  DIEFT_SATURATION         = $00000800;
+  DIEFT_POSNEGCOEFFICIENTS = $00001000;
+  DIEFT_POSNEGSATURATION   = $00002000;
+  DIEFT_DEADBAND           = $00004000;
+  DIEFT_STARTDELAY         = $00008000;
+//#define DIEFT_GETTYPE(n)            LOBYTE(n)
+type
+  DIEFT_GETTYPE            = byte;
+
+const
+  DI_DEGREES               = 100;
+  DI_FFNOMINALMAX          = 10000;
+  DI_SECONDS               = 1000000;
+
+type
+  LPCDICONSTANTFORCE = ^TDICONSTANTFORCE;
+  PCDICONSTANTFORCE = ^TDICONSTANTFORCE;
+  LPDICONSTANTFORCE = ^TDICONSTANTFORCE;
+  PDICONSTANTFORCE = ^TDICONSTANTFORCE;
+  TDICONSTANTFORCE = record
+    lMagnitude: LONG;
+  end;
+
+  LPCDIRAMPFORCE = ^TDIRAMPFORCE;
+  PCDIRAMPFORCE = ^TDIRAMPFORCE;
+  LPDIRAMPFORCE = ^TDIRAMPFORCE;
+  PDIRAMPFORCE = ^TDIRAMPFORCE;
+  TDIRAMPFORCE = record
+    lStart: LONG;
+    lEnd  : LONG;
+  end;
+
+  LPCDIPERIODIC = ^TDIPERIODIC;
+  PCDIPERIODIC = ^TDIPERIODIC;
+  LPDIPERIODIC = ^TDIPERIODIC;
+  PDIPERIODIC = ^TDIPERIODIC;
+  TDIPERIODIC = record
+    dwMagnitude: DWORD;
+    lOffset: LONG;
+    dwPhase: DWORD;
+    dwPeriod: DWORD;
+  end;
+
+  LPCDICONDITION = ^TDICONDITION;
+  PCDICONDITION = ^TDICONDITION;
+  LPDICONDITION = ^TDICONDITION;
+  PDICONDITION = ^TDICONDITION;
+  TDICONDITION = record
+    lOffset: LONG;
+    lPositiveCoefficient: LONG;
+    lNegativeCoefficient: LONG;
+    dwPositiveSaturation: DWORD;
+    dwNegativeSaturation: DWORD;
+    lDeadBand: LONG;
+  end;
+
+  LPCDICUSTOMFORCE = ^TDICUSTOMFORCE;
+  PCDICUSTOMFORCE = ^TDICUSTOMFORCE;
+  LPDICUSTOMFORCE = ^TDICUSTOMFORCE;
+  PDICUSTOMFORCE = ^TDICUSTOMFORCE;
+  TDICUSTOMFORCE = record
+    cChannels: DWORD;
+    dwSamplePeriod: DWORD;
+    cSamples: DWORD;
+    rglForceData: LPLONG
+  end;
+
+
+  LPCDIENVELOPE = ^TDIENVELOPE;
+  PCDIENVELOPE = ^TDIENVELOPE;
+  LPDIENVELOPE = ^TDIENVELOPE;
+  PDIENVELOPE = ^TDIENVELOPE;
+  TDIENVELOPE = record
+    dwSize: DWORD;            { sizeof(DIENVELOPE)   }
+    dwAttackLevel: DWORD;
+    dwAttackTime: DWORD;      { Microseconds         }
+    dwFadeLevel: DWORD;
+    dwFadeTime: DWORD;        { Microseconds         }
+  end;
+
+
+{ This structure is defined for DirectX 5.0 compatibility }
+  LPCDIEFFECT_DX5 = ^TDIEFFECT_DX5;
+  PCDIEFFECT_DX5 = ^TDIEFFECT_DX5;
+  LPDIEFFECT_DX5 = ^TDIEFFECT_DX5;
+  PDIEFFECT_DX5 = ^TDIEFFECT_DX5;
+  TDIEFFECT_DX5 = record
+    dwSize: DWORD;                   { sizeof(DIEFFECT_DX5) }
+    dwFlags: DWORD;                  { DIEFF_*              }
+    dwDuration: DWORD;               { Microseconds         }
+    dwSamplePeriod: DWORD;           { Microseconds         }
+    dwGain: DWORD;
+    dwTriggerButton: DWORD;          { or DIEB_NOTRIGGER    }
+    dwTriggerRepeatInterval: DWORD;  { Microseconds         }
+    cAxes: DWORD;                    { Number of axes       }
+    rgdwAxes: LPDWORD;               { Array of axes        }
+    rglDirection: LPLONG;            { Array of directions  }
+    lpEnvelope: LPDIENVELOPE;        { Optional             }
+    cbTypeSpecificParams: DWORD;     { Size of params       }
+    lpvTypeSpecificParams: LPVOID;   { Pointer to params    }
+  end;
+
+  LPCDIEFFECT = ^TDIEFFECT;
+  PCDIEFFECT = ^TDIEFFECT;
+  LPDIEFFECT = ^TDIEFFECT;
+  PDIEFFECT = ^TDIEFFECT;
+  TDIEFFECT = record
+    dwSize: DWORD;                   { sizeof(DIEFFECT)     }
+    dwFlags: DWORD;                  { DIEFF_*              }
+    dwDuration: DWORD;               { Microseconds         }
+    dwSamplePeriod: DWORD;           { Microseconds         }
+    dwGain: DWORD;
+    dwTriggerButton: DWORD;          { or DIEB_NOTRIGGER    }
+    dwTriggerRepeatInterval: DWORD;  { Microseconds         }
+    cAxes: DWORD;                    { Number of axes       }
+    rgdwAxes: LPDWORD;               { Array of axes        }
+    rglDirection: LPLONG;            { Array of directions  }
+    lpEnvelope: LPDIENVELOPE;        { Optional             }
+    cbTypeSpecificParams: DWORD;     { Size of params       }
+    lpvTypeSpecificParams: LPVOID;   { Pointer to params    }
+{$IF DIRECTINPUT_VERSION >= $0600}
+    dwStartDelay: DWORD;             { Microseconds         }
+{$ENDIF} { DIRECTINPUT_VERSION >= $0600 }
+  end;
+  LPDIEFFECT_DX6 = LPDIEFFECT;
+  TDIEFFECT_DX6 = TDIEFFECT;
+
+
+{$IF DIRECTINPUT_VERSION >= $0700}
+//#ifndef DIJ_RINGZERO
+  LPCDIFILEEFFECT= ^TDIFILEEFFECT;
+  PCDIFILEEFFECT= ^TDIFILEEFFECT;
+  LPDIFILEEFFECT = ^TDIFILEEFFECT;
+  PDIFILEEFFECT = ^TDIFILEEFFECT;
+  TDIFILEEFFECT = record
+    dwSize: DWORD;
+    GuidEffect: GUID;
+    lpDiEffect: LPCDIEFFECT;
+    szFriendlyName: array [0..MAX_PATH-1] of CHAR;
+  end;
+//typedef BOOL (FAR PASCAL * LPDIENUMEFFECTSINFILECALLBACK)(LPCDIFILEEFFECT , LPVOID);
+  LPDIENUMEFFECTSINFILECALLBACK = function(lpDiFileEf: LPCDIFILEEFFECT; pvRef: LPVOID): BOOL; stdcall;
+//#endif /* DIJ_RINGZERO */
+{$ENDIF} { DIRECTINPUT_VERSION >= $0700 }
+
+const
+  DIEFF_OBJECTIDS             = $00000001;
+  DIEFF_OBJECTOFFSETS         = $00000002;
+  DIEFF_CARTESIAN             = $00000010;
+  DIEFF_POLAR                 = $00000020;
+  DIEFF_SPHERICAL             = $00000040;
+
+  DIEP_DURATION               = $00000001;
+  DIEP_SAMPLEPERIOD           = $00000002;
+  DIEP_GAIN                   = $00000004;
+  DIEP_TRIGGERBUTTON          = $00000008;
+  DIEP_TRIGGERREPEATINTERVAL  = $00000010;
+  DIEP_AXES                   = $00000020;
+  DIEP_DIRECTION              = $00000040;
+  DIEP_ENVELOPE               = $00000080;
+  DIEP_TYPESPECIFICPARAMS     = $00000100;
+{$IF DIRECTINPUT_VERSION >= 0x0600}
+  DIEP_STARTDELAY             = $00000200;
+  DIEP_ALLPARAMS_DX5          = $000001FF;
+  DIEP_ALLPARAMS              = $000003FF;
+{$ELSE} { DIRECTINPUT_VERSION < 0x0600 }
+  DIEP_ALLPARAMS              = $000001FF;
+{$ENDIF} { DIRECTINPUT_VERSION < 0x0600 }
+  DIEP_START                  = $20000000;
+  DIEP_NORESTART              = $40000000;
+  DIEP_NODOWNLOAD             = $80000000;
+  DIEB_NOTRIGGER              = $FFFFFFFF;
+
+  DIES_SOLO                   = $00000001;
+  DIES_NODOWNLOAD             = $80000000;
+
+  DIEGES_PLAYING              = $00000001;
+  DIEGES_EMULATED             = $00000002;
+
+type
+  LPDIEFFESCAPE = ^TDIEFFESCAPE;
+  PDIEFFESCAPE = ^TDIEFFESCAPE;
+  TDIEFFESCAPE = record
+    dwSize: DWORD;
+    dwCommand: DWORD;
+    lpvInBuffer: LPVOID;
+    cbInBuffer: DWORD;
+    lpvOutBuffer: LPVOID;
+    cbOutBuffer: DWORD;
+  end;
+
+//#ifndef DIJ_RINGZERO
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInputEffect
+
+//DECLARE_INTERFACE_(IDirectInputEffect, IUnknown)
+type
+  IDirectInputEffect = interface(IUnknown)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInputEffect methods ***)
+    function Initialize(hinst: HINST; dwVersion: DWORD; const rguid: TGuid {REFGUID}): HRESULT; stdcall;
+    function GetEffectGuid(pguid: LPGUID): HRESULT; stdcall;
+    function GetParameters(peff: LPDIEFFECT; dwFlags: DWORD): HRESULT; stdcall;
+    function SetParameters(peff: LPCDIEFFECT; dwFlags: DWORD): HRESULT; stdcall;
+    function Start(dwIterations, dwFlags: DWORD): HRESULT; stdcall;
+    function Stop: HRESULT; stdcall;
+    function GetEffectStatus(pdwFlags: LPDWORD): HRESULT; stdcall;
+    function Download: HRESULT; stdcall;
+    function Unload: HRESULT; stdcall;
+    function Escape(pesc: LPDIEFFESCAPE): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInputEffect *LPDIRECTINPUTEFFECT;
+  LPDIRECTINPUTEFFECT = IDirectInputEffect;
+
+{#if !defined(__cplusplus) || defined(CINTERFACE)
+#define IDirectInputEffect_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInputEffect_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInputEffect_Release(p) (p)->lpVtbl->Release(p)
+#define IDirectInputEffect_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+#define IDirectInputEffect_GetEffectGuid(p,a) (p)->lpVtbl->GetEffectGuid(p,a)
+#define IDirectInputEffect_GetParameters(p,a,b) (p)->lpVtbl->GetParameters(p,a,b)
+#define IDirectInputEffect_SetParameters(p,a,b) (p)->lpVtbl->SetParameters(p,a,b)
+#define IDirectInputEffect_Start(p,a,b) (p)->lpVtbl->Start(p,a,b)
+#define IDirectInputEffect_Stop(p) (p)->lpVtbl->Stop(p)
+#define IDirectInputEffect_GetEffectStatus(p,a) (p)->lpVtbl->GetEffectStatus(p,a)
+#define IDirectInputEffect_Download(p) (p)->lpVtbl->Download(p)
+#define IDirectInputEffect_Unload(p) (p)->lpVtbl->Unload(p)
+#define IDirectInputEffect_Escape(p,a) (p)->lpVtbl->Escape(p,a)
+#else
+#define IDirectInputEffect_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInputEffect_AddRef(p) (p)->AddRef()
+#define IDirectInputEffect_Release(p) (p)->Release()
+#define IDirectInputEffect_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+#define IDirectInputEffect_GetEffectGuid(p,a) (p)->GetEffectGuid(a)
+#define IDirectInputEffect_GetParameters(p,a,b) (p)->GetParameters(a,b)
+#define IDirectInputEffect_SetParameters(p,a,b) (p)->SetParameters(a,b)
+#define IDirectInputEffect_Start(p,a,b) (p)->Start(a,b)
+#define IDirectInputEffect_Stop(p) (p)->Stop()
+#define IDirectInputEffect_GetEffectStatus(p,a) (p)->GetEffectStatus(a)
+#define IDirectInputEffect_Download(p) (p)->Download()
+#define IDirectInputEffect_Unload(p) (p)->Unload()
+#define IDirectInputEffect_Escape(p,a) (p)->Escape(a)
+#endif}
+
+//#endif /* DIJ_RINGZERO */
+
+{$ENDIF} { DIRECTINPUT_VERSION >= $0500 }
+
+(****************************************************************************
+ *
+ *      IDirectInputDevice
+ *
+ ****************************************************************************)
+
+{$IF DIRECTINPUT_VERSION <= $700}
+const
+  DIDEVTYPE_DEVICE   = 1;
+  DIDEVTYPE_MOUSE    = 2;
+  DIDEVTYPE_KEYBOARD = 3;
+  DIDEVTYPE_JOYSTICK = 4;
+
+{$ELSE}
+const
+  DI8DEVCLASS_ALL          = 0;
+  DI8DEVCLASS_DEVICE       = 1;
+  DI8DEVCLASS_POINTER      = 2;
+  DI8DEVCLASS_KEYBOARD     = 3;
+  DI8DEVCLASS_GAMECTRL     = 4;
+
+  DI8DEVTYPE_DEVICE        = $11;
+  DI8DEVTYPE_MOUSE         = $12;
+  DI8DEVTYPE_KEYBOARD      = $13;
+  DI8DEVTYPE_JOYSTICK      = $14;
+  DI8DEVTYPE_GAMEPAD       = $15;
+  DI8DEVTYPE_DRIVING       = $16;
+  DI8DEVTYPE_FLIGHT        = $17;
+  DI8DEVTYPE_1STPERSON     = $18;
+  DI8DEVTYPE_DEVICECTRL    = $19;
+  DI8DEVTYPE_SCREENPOINTER = $1A;
+  DI8DEVTYPE_REMOTE        = $1B;
+  DI8DEVTYPE_SUPPLEMENTAL  = $1C;
+{$ENDIF} { DIRECTINPUT_VERSION <= 0x700 }
+
+const
+  DIDEVTYPE_HID            = $00010000;
+
+{$IF DIRECTINPUT_VERSION <= $700}
+const
+  DIDEVTYPEMOUSE_UNKNOWN        = 1;
+  DIDEVTYPEMOUSE_TRADITIONAL    = 2;
+  DIDEVTYPEMOUSE_FINGERSTICK    = 3;
+  DIDEVTYPEMOUSE_TOUCHPAD       = 4;
+  DIDEVTYPEMOUSE_TRACKBALL      = 5;
+
+  DIDEVTYPEKEYBOARD_UNKNOWN     =  0;
+  DIDEVTYPEKEYBOARD_PCXT        =  1;
+  DIDEVTYPEKEYBOARD_OLIVETTI    =  2;
+  DIDEVTYPEKEYBOARD_PCAT        =  3;
+  DIDEVTYPEKEYBOARD_PCENH       =  4;
+  DIDEVTYPEKEYBOARD_NOKIA1050   =  5;
+  DIDEVTYPEKEYBOARD_NOKIA9140   =  6;
+  DIDEVTYPEKEYBOARD_NEC98       =  7;
+  DIDEVTYPEKEYBOARD_NEC98LAPTOP =  8;
+  DIDEVTYPEKEYBOARD_NEC98106    =  9;
+  DIDEVTYPEKEYBOARD_JAPAN106    = 10;
+  DIDEVTYPEKEYBOARD_JAPANAX     = 11;
+  DIDEVTYPEKEYBOARD_J3100       = 12;
+
+  DIDEVTYPEJOYSTICK_UNKNOWN     = 1;
+  DIDEVTYPEJOYSTICK_TRADITIONAL = 2;
+  DIDEVTYPEJOYSTICK_FLIGHTSTICK = 3;
+  DIDEVTYPEJOYSTICK_GAMEPAD     = 4;
+  DIDEVTYPEJOYSTICK_RUDDER      = 5;
+  DIDEVTYPEJOYSTICK_WHEEL       = 6;
+  DIDEVTYPEJOYSTICK_HEADTRACKER = 7;
+
+{$ELSE}
+const
+  DI8DEVTYPEMOUSE_UNKNOWN                       = 1;
+  DI8DEVTYPEMOUSE_TRADITIONAL                   = 2;
+  DI8DEVTYPEMOUSE_FINGERSTICK                   = 3;
+  DI8DEVTYPEMOUSE_TOUCHPAD                      = 4;
+  DI8DEVTYPEMOUSE_TRACKBALL                     = 5;
+  DI8DEVTYPEMOUSE_ABSOLUTE                      = 6;
+
+  DI8DEVTYPEKEYBOARD_UNKNOWN                    =  0;
+  DI8DEVTYPEKEYBOARD_PCXT                       =  1;
+  DI8DEVTYPEKEYBOARD_OLIVETTI                   =  2;
+  DI8DEVTYPEKEYBOARD_PCAT                       =  3;
+  DI8DEVTYPEKEYBOARD_PCENH                      =  4;
+  DI8DEVTYPEKEYBOARD_NOKIA1050                  =  5;
+  DI8DEVTYPEKEYBOARD_NOKIA9140                  =  6;
+  DI8DEVTYPEKEYBOARD_NEC98                      =  7;
+  DI8DEVTYPEKEYBOARD_NEC98LAPTOP                =  8;
+  DI8DEVTYPEKEYBOARD_NEC98106                   =  9;
+  DI8DEVTYPEKEYBOARD_JAPAN106                   = 10;
+  DI8DEVTYPEKEYBOARD_JAPANAX                    = 11;
+  DI8DEVTYPEKEYBOARD_J3100                      = 12;
+
+  DI8DEVTYPE_LIMITEDGAMESUBTYPE                 = 1;
+
+  DI8DEVTYPEJOYSTICK_LIMITED                    = DI8DEVTYPE_LIMITEDGAMESUBTYPE;
+  DI8DEVTYPEJOYSTICK_STANDARD                   = 2;
+
+  DI8DEVTYPEGAMEPAD_LIMITED                     = DI8DEVTYPE_LIMITEDGAMESUBTYPE;
+  DI8DEVTYPEGAMEPAD_STANDARD                    = 2;
+  DI8DEVTYPEGAMEPAD_TILT                        = 3;
+
+  DI8DEVTYPEDRIVING_LIMITED                     = DI8DEVTYPE_LIMITEDGAMESUBTYPE;
+  DI8DEVTYPEDRIVING_COMBINEDPEDALS              = 2;
+  DI8DEVTYPEDRIVING_DUALPEDALS                  = 3;
+  DI8DEVTYPEDRIVING_THREEPEDALS                 = 4;
+  DI8DEVTYPEDRIVING_HANDHELD                    = 5;
+
+  DI8DEVTYPEFLIGHT_LIMITED                      = DI8DEVTYPE_LIMITEDGAMESUBTYPE;
+  DI8DEVTYPEFLIGHT_STICK                        = 2;
+  DI8DEVTYPEFLIGHT_YOKE                         = 3;
+  DI8DEVTYPEFLIGHT_RC                           = 4;
+
+  DI8DEVTYPE1STPERSON_LIMITED                   = DI8DEVTYPE_LIMITEDGAMESUBTYPE;
+  DI8DEVTYPE1STPERSON_UNKNOWN                   = 2;
+  DI8DEVTYPE1STPERSON_SIXDOF                    = 3;
+  DI8DEVTYPE1STPERSON_SHOOTER                   = 4;
+
+  DI8DEVTYPESCREENPTR_UNKNOWN                   = 2;
+  DI8DEVTYPESCREENPTR_LIGHTGUN                  = 3;
+  DI8DEVTYPESCREENPTR_LIGHTPEN                  = 4;
+  DI8DEVTYPESCREENPTR_TOUCH                     = 5;
+
+  DI8DEVTYPEREMOTE_UNKNOWN                      = 2;
+
+  DI8DEVTYPEDEVICECTRL_UNKNOWN                  = 2;
+  DI8DEVTYPEDEVICECTRL_COMMSSELECTION           = 3;
+  DI8DEVTYPEDEVICECTRL_COMMSSELECTION_HARDWIRED = 4;
+
+  DI8DEVTYPESUPPLEMENTAL_UNKNOWN                =  2;
+  DI8DEVTYPESUPPLEMENTAL_2NDHANDCONTROLLER      =  3;
+  DI8DEVTYPESUPPLEMENTAL_HEADTRACKER            =  4;
+  DI8DEVTYPESUPPLEMENTAL_HANDTRACKER            =  5;
+  DI8DEVTYPESUPPLEMENTAL_SHIFTSTICKGATE         =  6;
+  DI8DEVTYPESUPPLEMENTAL_SHIFTER                =  7;
+  DI8DEVTYPESUPPLEMENTAL_THROTTLE               =  8;
+  DI8DEVTYPESUPPLEMENTAL_SPLITTHROTTLE          =  9;
+  DI8DEVTYPESUPPLEMENTAL_COMBINEDPEDALS         = 10;
+  DI8DEVTYPESUPPLEMENTAL_DUALPEDALS             = 11;
+  DI8DEVTYPESUPPLEMENTAL_THREEPEDALS            = 12;
+  DI8DEVTYPESUPPLEMENTAL_RUDDERPEDALS           = 13;
+{$ENDIF} { DIRECTINPUT_VERSION <= $700 }
+
+//#define GET_DIDEVICE_TYPE(dwDevType)    LOBYTE(dwDevType)
+type
+  GET_DIDEVICE_TYPE = byte;
+//#define GET_DIDEVICE_SUBTYPE(dwDevType) HIBYTE(dwDevType)
+
+{$IF DIRECTINPUT_VERSION >= $0500}
+{ This structure is defined for DirectX 3.0 compatibility }
+type
+  LPDIDEVCAPS_DX3 = ^TDIDEVCAPS_DX3;
+  PDIDEVCAPS_DX3 = ^TDIDEVCAPS_DX3;
+  TDIDEVCAPS_DX3 = record
+    dwSize: DWORD;
+    dwFlags: DWORD;
+    dwDevType: DWORD;
+    dwAxes: DWORD;
+    dwButtons: DWORD;
+    dwPOVs: DWORD;
+  end;
+{$ENDIF} { DIRECTINPUT_VERSION >= 0x0500 }
+
+  LPDIDEVCAPS = ^TDIDEVCAPS;
+  PDIDEVCAPS = ^TDIDEVCAPS;
+  TDIDEVCAPS = record
+    dwSize: DWORD;
+    dwFlags: DWORD;
+    dwDevType: DWORD;
+    dwAxes: DWORD;
+    dwButtons: DWORD;
+    dwPOVs: DWORD;
+{$IF DIRECTINPUT_VERSION >= $0500}
+    dwFFSamplePeriod: DWORD;
+    dwFFMinTimeResolution: DWORD;
+    dwFirmwareRevision: DWORD;
+    dwHardwareRevision: DWORD;
+    dwFFDriverVersion: DWORD;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0500 }
+  end;
+
+const
+  DIDC_ATTACHED           = $00000001;
+  DIDC_POLLEDDEVICE       = $00000002;
+  DIDC_EMULATED           = $00000004;
+  DIDC_POLLEDDATAFORMAT   = $00000008;
+{$IF DIRECTINPUT_VERSION >= $0500}
+  DIDC_FORCEFEEDBACK      = $00000100;
+  DIDC_FFATTACK           = $00000200;
+  DIDC_FFFADE             = $00000400;
+  DIDC_SATURATION         = $00000800;
+  DIDC_POSNEGCOEFFICIENTS = $00001000;
+  DIDC_POSNEGSATURATION   = $00002000;
+  DIDC_DEADBAND           = $00004000;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0500 }
+  DIDC_STARTDELAY         = $00008000;
+{$IF DIRECTINPUT_VERSION >= $050a}
+  DIDC_ALIAS              = $00010000;
+  DIDC_PHANTOM            = $00020000;
+{$ENDIF} { DIRECTINPUT_VERSION >= $050a }
+{$IF DIRECTINPUT_VERSION >= $0800}
+  DIDC_HIDDEN             = $00040000;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0800 }
+
+  DIDFT_ALL             = $00000000;
+
+  DIDFT_RELAXIS         = $00000001;
+  DIDFT_ABSAXIS         = $00000002;
+  DIDFT_AXIS            = $00000003;
+
+  DIDFT_PSHBUTTON       = $00000004;
+  DIDFT_TGLBUTTON       = $00000008;
+  DIDFT_BUTTON          = $0000000C;
+
+  DIDFT_POV             = $00000010;
+  DIDFT_COLLECTION      = $00000040;
+  DIDFT_NODATA          = $00000080;
+
+  DIDFT_ANYINSTANCE     = $00FFFF00;
+  DIDFT_INSTANCEMASK    = DIDFT_ANYINSTANCE;
+  //DIDFT_MAKEINSTANCE(n) ((WORD)(n) << 8)
+  //DIDFT_GETTYPE(n)     LOBYTE(n)
+type
+  DIDFT_GETTYPE = byte;
+  //DIDFT_GETINSTANCE(n) LOWORD((n) >> 8)
+const
+  DIDFT_FFACTUATOR      = $01000000;
+  DIDFT_FFEFFECTTRIGGER = $02000000;
+{$IF DIRECTINPUT_VERSION >= $050a}
+  DIDFT_OUTPUT          = $10000000;
+  DIDFT_VENDORDEFINED   = $04000000;
+  DIDFT_ALIAS           = $08000000;
+{$ENDIF} { DIRECTINPUT_VERSION >= $050a }
+
+//  DIDFT_ENUMCOLLECTION(n) ((WORD)(n) << 8)
+  DIDFT_NOCOLLECTION      = $00FFFF00;
+
+//#ifndef DIJ_RINGZERO
+
+type
+  LPCDIOBJECTDATAFORMAT = ^TDIOBJECTDATAFORMAT;
+  PCDIOBJECTDATAFORMAT = ^TDIOBJECTDATAFORMAT;
+  LPDIOBJECTDATAFORMAT = ^TDIOBJECTDATAFORMAT;
+  PDIOBJECTDATAFORMAT = ^TDIOBJECTDATAFORMAT;
+  TDIOBJECTDATAFORMAT = record
+    pguid: PGuid; {const GUID *}
+    dwOfs: DWORD;
+    dwType: DWORD;
+    dwFlags: DWORD;
+  end;
+
+  LPCDIDATAFORMAT = ^TDIDATAFORMAT;
+  PCDIDATAFORMAT = ^TDIDATAFORMAT;
+  LPDIDATAFORMAT = ^TDIDATAFORMAT;
+  PDIDATAFORMAT = ^TDIDATAFORMAT;
+  TDIDATAFORMAT = record
+    dwSize: DWORD;
+    dwObjSize: DWORD;
+    dwFlags: DWORD;
+    dwDataSize: DWORD;
+    dwNumObjs: DWORD;
+    rgodf: LPDIOBJECTDATAFORMAT;
+  end;
+
+const
+  DIDF_ABSAXIS = $00000001;
+  DIDF_RELAXIS = $00000002;
+
+//#ifdef __cplusplus
+//extern "C" {
+//#endif
+//extern const DIDATAFORMAT c_dfDIMouse;
+var
+  c_dfDIMouse: TDIDATAFORMAT; cvar; external;
+
+{$IF DIRECTINPUT_VERSION >= $0700}
+//extern const DIDATAFORMAT c_dfDIMouse2;
+  c_dfDIMouse2: TDIDATAFORMAT; cvar; external;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0700 }
+
+//extern const DIDATAFORMAT c_dfDIKeyboard;
+  c_dfDIKeyboard: TDIDATAFORMAT; cvar; external;
+
+{$IF DIRECTINPUT_VERSION >= $0500}
+//extern const DIDATAFORMAT c_dfDIJoystick;
+  c_dfDIJoystick: TDIDATAFORMAT; cvar; external;
+//extern const DIDATAFORMAT c_dfDIJoystick2;
+  c_dfDIJoystick2: TDIDATAFORMAT; cvar; external;
+{$ENDIF} { DIRECTINPUT_VERSION >= 0x0500 }
+
+//#ifdef __cplusplus
+//};
+//#endif
+
+
+{$IF DIRECTINPUT_VERSION > $0700}
+
+//#pragma warning(push)
+//#pragma warning(disable:4201)   // Nameless union / struct when compiled for C.
+
+type
+  LPDIACTIONA = ^TDIACTIONA;
+  PDIACTIONA = ^TDIACTIONA;
+  TDIACTIONA = record
+    uAppData: UINT_PTR;
+    dwSemantic: DWORD;
+    dwFlags: DWORD;  {OPTIONAL}
+    case Integer of
+      0: (
+        lptszActionName: LPCSTR;  {OPTIONAL}
+        guidInstance: GUID;  {OPTIONAL}
+        dwObjID: DWORD;  {OPTIONAL}
+        dwHow: DWORD; {OPTIONAL}
+      );
+      1: (
+        uResIdString: UINT  {OPTIONAL}
+      );
+  end;
+  LPDIACTIONW = ^TDIACTIONW;
+  PDIACTIONW = ^TDIACTIONW;
+  TDIACTIONW = record
+    uAppData: UINT_PTR;
+    dwSemantic: DWORD;
+    dwFlags: DWORD;  {OPTIONAL}
+    case Integer of
+      0: (
+        lptszActionName: LPCWSTR;  {OPTIONAL}
+        guidInstance: GUID;  {OPTIONAL}
+        dwObjID: DWORD;  {OPTIONAL}
+        dwHow: DWORD; {OPTIONAL}
+      );
+      1: (
+        uResIdString: UINT;  {OPTIONAL}
+      );
+  end;
+{$IFDEF UNICODE}
+  TDIACTION = TDIACTIONW;
+  LPDIACTION = LPDIACTIONW;
+  PDIACTION = PDIACTIONW;
+{$ELSE}
+  TDIACTION = TDIACTIONA;
+  LPDIACTION = LPDIACTIONA;
+  PDIACTION = PDIACTIONA;
+{$ENDIF} // UNICODE
+
+  LPCDIACTIONA = ^TDIACTIONA;
+  PCDIACTIONA = ^TDIACTIONA;
+  LPCDIACTIONW = ^TDIACTIONW;
+  PCDIACTIONW = ^TDIACTIONW;
+{$IFDEF UNICODE}
+  LPCDIACTION = LPCDIACTIONW;
+  PCDIACTION = PCDIACTIONW;
+{$ELSE}
+  LPCDIACTION = LPCDIACTIONA;
+  PCDIACTION = PCDIACTIONA;
+{$ENDIF} // UNICODE
+
+//#pragma warning(pop)
+
+const
+  DIA_FORCEFEEDBACK = $00000001;
+  DIA_APPMAPPED     = $00000002;
+  DIA_APPNOMAP      = $00000004;
+  DIA_NORANGE       = $00000008;
+  DIA_APPFIXED      = $00000010;
+
+  DIAH_UNMAPPED     = $00000000;
+  DIAH_USERCONFIG   = $00000001;
+  DIAH_APPREQUESTED = $00000002;
+  DIAH_HWAPP        = $00000004;
+  DIAH_HWDEFAULT    = $00000008;
+  DIAH_DEFAULT      = $00000020;
+  DIAH_ERROR        = $80000000;
+
+type
+  LPDIACTIONFORMATA = ^TDIACTIONFORMATA;
+  PDIACTIONFORMATA = ^TDIACTIONFORMATA;
+  TDIACTIONFORMATA = record
+    dwSize: DWORD;
+    dwActionSize: DWORD;
+    dwDataSize: DWORD;
+    dwNumActions: DWORD;
+    rgoAction: LPDIACTIONA;
+    guidActionMap: GUID;
+    dwGenre: DWORD;
+    dwBufferSize: DWORD;
+    lAxisMin: LONG;  {OPTIONAL}
+    lAxisMax: LONG;  {OPTIONAL}
+    hInstString: HINST;  {OPTIONAL}
+    ftTimeStamp: FILETIME;
+    dwCRC: DWORD;
+    tszActionMap: array [0..MAX_PATH-1] of CHAR;
+  end;
+  LPDIACTIONFORMATW = ^TDIACTIONFORMATW;
+  PDIACTIONFORMATW = ^TDIACTIONFORMATW;
+  TDIACTIONFORMATW = record
+    dwSize: DWORD;
+    dwActionSize: DWORD;
+    dwDataSize: DWORD;
+    dwNumActions: DWORD;
+    rgoAction: LPDIACTIONW;
+    guidActionMap: GUID;
+    dwGenre: DWORD;
+    dwBufferSize: DWORD;
+    lAxisMin: LONG;  {OPTIONAL}
+    lAxisMax: LONG;  {OPTIONAL}
+    hInstString: HINST;  {OPTIONAL}
+    ftTimeStamp: FILETIME;
+    dwCRC: DWORD;
+    tszActionMap: array [0..MAX_PATH-1] of WCHAR;
+  end;
+{$IFDEF UNICODE}
+  TDIACTIONFORMAT = TDIACTIONFORMATW;
+  LPDIACTIONFORMAT = LPDIACTIONFORMATW;
+  PDIACTIONFORMAT = PDIACTIONFORMATW;
+{$ELSE}
+  TDIACTIONFORMAT = TDIACTIONFORMATA;
+  LPDIACTIONFORMAT = LPDIACTIONFORMATA;
+  PDIACTIONFORMAT = PDIACTIONFORMATA;
+{$ENDIF} // UNICODE
+  LPCDIACTIONFORMATA = ^TDIACTIONFORMATA;
+  PCDIACTIONFORMATA = ^TDIACTIONFORMATA;
+  LPCDIACTIONFORMATW = ^TDIACTIONFORMATW;
+  PCDIACTIONFORMATW = ^TDIACTIONFORMATW;
+{$IFDEF UNICODE}
+  LPCDIACTIONFORMAT = LPCDIACTIONFORMATW;
+  PCDIACTIONFORMAT = PCDIACTIONFORMATW;
+{$ELSE}
+  LPCDIACTIONFORMAT = LPCDIACTIONFORMATA;
+  PCDIACTIONFORMAT = PCDIACTIONFORMATA;
+{$ENDIF} // UNICODE
+
+const
+  DIAFTS_NEWDEVICELOW     = $FFFFFFFF;
+  DIAFTS_NEWDEVICEHIGH    = $FFFFFFFF;
+  DIAFTS_UNUSEDDEVICELOW  = $00000000;
+  DIAFTS_UNUSEDDEVICEHIGH = $00000000;
+
+  DIDBAM_DEFAULT          = $00000000;
+  DIDBAM_PRESERVE         = $00000001;
+  DIDBAM_INITIALIZE       = $00000002;
+  DIDBAM_HWDEFAULTS       = $00000004;
+
+  DIDSAM_DEFAULT          = $00000000;
+  DIDSAM_NOUSER           = $00000001;
+  DIDSAM_FORCESAVE        = $00000002;
+
+  DICD_DEFAULT            = $00000000;
+  DICD_EDIT               = $00000001;
+
+(*
+ * The following definition is normally defined in d3dtypes.h
+ *)
+{$IFNDEF D3DCOLOR_DEFINED}
+type
+  D3DCOLOR = DWORD;
+{$DEFINE D3DCOLOR_DEFINED}
+{$ENDIF}
+
+  LPCDICOLORSET = ^TDICOLORSET;
+  PCDICOLORSET = ^TDICOLORSET;
+  LPDICOLORSET = ^TDICOLORSET;
+  PDICOLORSET = ^TDICOLORSET;
+  TDICOLORSET = record
+    dwSize: DWORD;
+    cTextFore: D3DCOLOR;
+    cTextHighlight: D3DCOLOR;
+    cCalloutLine: D3DCOLOR;
+    cCalloutHighlight: D3DCOLOR;
+    cBorder: D3DCOLOR;
+    cControlFill: D3DCOLOR;
+    cHighlightFill: D3DCOLOR;
+    cAreaFill: D3DCOLOR;
+  end;
+
+
+  LPDICONFIGUREDEVICESPARAMSA = ^TDICONFIGUREDEVICESPARAMSA;
+  PDICONFIGUREDEVICESPARAMSA = ^TDICONFIGUREDEVICESPARAMSA;
+  TDICONFIGUREDEVICESPARAMSA = record
+    dwSize: DWORD;
+    dwcUsers: DWORD;
+    lptszUserNames: LPSTR;
+    dwcFormats: DWORD;
+    lprgFormats: LPDIACTIONFORMATA;
+    hwnd: HWND;
+    dics: TDICOLORSET;
+    lpUnkDDSTarget: {IUnknown FAR *}IUnknown;
+  end;
+  LPDICONFIGUREDEVICESPARAMSW = ^TDICONFIGUREDEVICESPARAMSW;
+  PDICONFIGUREDEVICESPARAMSW = ^TDICONFIGUREDEVICESPARAMSW;
+  TDICONFIGUREDEVICESPARAMSW = record
+    dwSize: DWORD;
+    dwcUsers: DWORD;
+    lptszUserNames: LPWSTR;
+    dwcFormats: DWORD;
+    lprgFormats: LPDIACTIONFORMATW;
+    hwnd: HWND;
+    dics: TDICOLORSET;
+    lpUnkDDSTarget: {IUnknown FAR *}IUnknown;
+  end;
+{$IFDEF UNICODE}
+  TDICONFIGUREDEVICESPARAMS = TDICONFIGUREDEVICESPARAMSW;
+  LPDICONFIGUREDEVICESPARAMS = LPDICONFIGUREDEVICESPARAMSW;
+  PDICONFIGUREDEVICESPARAMS = PDICONFIGUREDEVICESPARAMSW;
+{$ELSE}
+  TDICONFIGUREDEVICESPARAMS = TDICONFIGUREDEVICESPARAMSA;
+  LPDICONFIGUREDEVICESPARAMS = LPDICONFIGUREDEVICESPARAMSA;
+  PDICONFIGUREDEVICESPARAMS = PDICONFIGUREDEVICESPARAMSA;
+{$ENDIF} // UNICODE
+  LPCDICONFIGUREDEVICESPARAMSA = ^TDICONFIGUREDEVICESPARAMSA;
+  PCDICONFIGUREDEVICESPARAMSA = ^TDICONFIGUREDEVICESPARAMSA;
+  LPCDICONFIGUREDEVICESPARAMSW = ^TDICONFIGUREDEVICESPARAMSW;
+  PCDICONFIGUREDEVICESPARAMSW = ^TDICONFIGUREDEVICESPARAMSW;
+{$IFDEF UNICODE}
+  LPCDICONFIGUREDEVICESPARAMS = LPCDICONFIGUREDEVICESPARAMSW;
+  PCDICONFIGUREDEVICESPARAMS = PCDICONFIGUREDEVICESPARAMSW;
+{$ELSE}
+  LPCDICONFIGUREDEVICESPARAMS = LPCDICONFIGUREDEVICESPARAMSA;
+  PCDICONFIGUREDEVICESPARAMS = PCDICONFIGUREDEVICESPARAMSA;
+{$ENDIF} // UNICODE
+
+
+const
+  DIDIFT_CONFIGURATION = $00000001;
+  DIDIFT_OVERLAY       = $00000002;
+
+  DIDAL_CENTERED      = $00000000;
+  DIDAL_LEFTALIGNED   = $00000001;
+  DIDAL_RIGHTALIGNED  = $00000002;
+  DIDAL_MIDDLE        = $00000000;
+  DIDAL_TOPALIGNED    = $00000004;
+  DIDAL_BOTTOMALIGNED = $00000008;
+
+type
+  LPDIDEVICEIMAGEINFOA = ^TDIDEVICEIMAGEINFOA;
+  PDIDEVICEIMAGEINFOA = ^TDIDEVICEIMAGEINFOA;
+  TDIDEVICEIMAGEINFOA = record
+    tszImagePath: array [0..MAX_PATH-1] of CHAR;
+    dwFlags: DWORD;
+    // These are valid if DIDIFT_OVERLAY is present in dwFlags.
+    dwViewID: DWORD;
+    rcOverlay: RECT;
+    dwObjID: DWORD;
+    dwcValidPts: DWORD;
+    rgptCalloutLine: array [0..4] of POINT;
+    rcCalloutRect: RECT;
+    dwTextAlign: DWORD;
+  end;
+  LPDIDEVICEIMAGEINFOW = ^TDIDEVICEIMAGEINFOW;
+  PDIDEVICEIMAGEINFOW = ^TDIDEVICEIMAGEINFOW;
+  TDIDEVICEIMAGEINFOW = record
+    tszImagePath: array [0..MAX_PATH-1] of WCHAR;
+    dwFlags: DWORD;
+    // These are valid if DIDIFT_OVERLAY is present in dwFlags.
+    dwViewID: DWORD;
+    rcOverlay: RECT;
+    dwObjID: DWORD;
+    dwcValidPts: DWORD;
+    rgptCalloutLine: array [0..4] of POINT;
+    rcCalloutRect: RECT;
+    dwTextAlign: DWORD;
+  end;
+{$IFDEF UNICODE}
+  TDIDEVICEIMAGEINFO = TDIDEVICEIMAGEINFOW;
+  LPDIDEVICEIMAGEINFO = LPDIDEVICEIMAGEINFOW;
+  PDIDEVICEIMAGEINFO = PDIDEVICEIMAGEINFOW;
+{$ELSE}
+  TDIDEVICEIMAGEINFO = TDIDEVICEIMAGEINFOA;
+  LPDIDEVICEIMAGEINFO = LPDIDEVICEIMAGEINFOA;
+  PDIDEVICEIMAGEINFO = PDIDEVICEIMAGEINFOA;
+{$ENDIF} // UNICODE
+  LPCDIDEVICEIMAGEINFOA = ^TDIDEVICEIMAGEINFOA;
+  PCDIDEVICEIMAGEINFOA = ^TDIDEVICEIMAGEINFOA;
+  LPCDIDEVICEIMAGEINFOW = ^TDIDEVICEIMAGEINFOW;
+  PCDIDEVICEIMAGEINFOW = ^TDIDEVICEIMAGEINFOW;
+{$IFDEF UNICODE}
+  LPCDIDEVICEIMAGEINFO = LPCDIDEVICEIMAGEINFOW;
+  PCDIDEVICEIMAGEINFO = PCDIDEVICEIMAGEINFOW;
+{$ELSE}
+  LPCDIDEVICEIMAGEINFO = LPCDIDEVICEIMAGEINFOA;
+  PCDIDEVICEIMAGEINFO = PCDIDEVICEIMAGEINFOA;
+{$ENDIF} // UNICODE
+
+  LPDIDEVICEIMAGEINFOHEADERA = ^TDIDEVICEIMAGEINFOHEADERA;
+  PDIDEVICEIMAGEINFOHEADERA = ^TDIDEVICEIMAGEINFOHEADERA;
+  TDIDEVICEIMAGEINFOHEADERA = record
+    dwSize: DWORD;
+    dwSizeImageInfo: DWORD;
+    dwcViews: DWORD;
+    dwcButtons: DWORD;
+    dwcAxes: DWORD;
+    dwcPOVs: DWORD;
+    dwBufferSize: DWORD;
+    dwBufferUsed: DWORD;
+    lprgImageInfoArray: LPDIDEVICEIMAGEINFOA;
+  end;
+  LPDIDEVICEIMAGEINFOHEADERW = ^TDIDEVICEIMAGEINFOHEADERW;
+  PDIDEVICEIMAGEINFOHEADERW = ^TDIDEVICEIMAGEINFOHEADERW;
+  TDIDEVICEIMAGEINFOHEADERW = record
+    dwSize: DWORD;
+    dwSizeImageInfo: DWORD;
+    dwcViews: DWORD;
+    dwcButtons: DWORD;
+    dwcAxes: DWORD;
+    dwcPOVs: DWORD;
+    dwBufferSize: DWORD;
+    dwBufferUsed: DWORD;
+    lprgImageInfoArray: LPDIDEVICEIMAGEINFOW;
+  end;
+{$IFDEF UNICODE}
+  TDIDEVICEIMAGEINFOHEADER = TDIDEVICEIMAGEINFOHEADERW;
+  LPDIDEVICEIMAGEINFOHEADER = LPDIDEVICEIMAGEINFOHEADERW;
+  PDIDEVICEIMAGEINFOHEADER = PDIDEVICEIMAGEINFOHEADERW;
+{$ELSE}
+  TDIDEVICEIMAGEINFOHEADER = TDIDEVICEIMAGEINFOHEADERA;
+  LPDIDEVICEIMAGEINFOHEADER = LPDIDEVICEIMAGEINFOHEADERA;
+  PDIDEVICEIMAGEINFOHEADER = PDIDEVICEIMAGEINFOHEADERA;
+{$ENDIF} // UNICODE
+  LPCDIDEVICEIMAGEINFOHEADERA = ^TDIDEVICEIMAGEINFOHEADERA;
+  PCDIDEVICEIMAGEINFOHEADERA = ^TDIDEVICEIMAGEINFOHEADERA;
+  LPCDIDEVICEIMAGEINFOHEADERW = ^TDIDEVICEIMAGEINFOHEADERW;
+  PCDIDEVICEIMAGEINFOHEADERW = ^TDIDEVICEIMAGEINFOHEADERW;
+{$IFDEF UNICODE}
+  LPCDIDEVICEIMAGEINFOHEADER = LPCDIDEVICEIMAGEINFOHEADERW;
+  PCDIDEVICEIMAGEINFOHEADER = PCDIDEVICEIMAGEINFOHEADERW;
+{$ELSE}
+  LPCDIDEVICEIMAGEINFOHEADER = LPCDIDEVICEIMAGEINFOHEADERA;
+  PCDIDEVICEIMAGEINFOHEADER = PCDIDEVICEIMAGEINFOHEADERA;
+{$ENDIF} // UNICODE
+
+{$ENDIF} { DIRECTINPUT_VERSION > $0700 }
+
+{$IF DIRECTINPUT_VERSION >= $0500}
+{ These structures are defined for DirectX 3.0 compatibility }
+
+type
+  LPDIDEVICEOBJECTINSTANCE_DX3A = ^TDIDEVICEOBJECTINSTANCE_DX3A;
+  PDIDEVICEOBJECTINSTANCE_DX3A = ^TDIDEVICEOBJECTINSTANCE_DX3A;
+  TDIDEVICEOBJECTINSTANCE_DX3A = record
+    dwSize: DWORD;
+    guidType: GUID;
+    dwOfs: DWORD;
+    dwType: DWORD;
+    dwFlags: DWORD;
+    tszName: array [0..MAX_PATH-1] of CHAR;
+  end;
+  LPDIDEVICEOBJECTINSTANCE_DX3W = ^TDIDEVICEOBJECTINSTANCE_DX3W;
+  PDIDEVICEOBJECTINSTANCE_DX3W = ^TDIDEVICEOBJECTINSTANCE_DX3W;
+  TDIDEVICEOBJECTINSTANCE_DX3W = record
+    dwSize: DWORD;
+    guidType: GUID;
+    dwOfs: DWORD;
+    dwType: DWORD;
+    dwFlags: DWORD;
+    tszName: array [0..MAX_PATH-1] of WCHAR;
+  end;
+{$IFDEF UNICODE}
+  TDIDEVICEOBJECTINSTANCE_DX3 = TDIDEVICEOBJECTINSTANCE_DX3W;
+  LPDIDEVICEOBJECTINSTANCE_DX3 = LPDIDEVICEOBJECTINSTANCE_DX3W;
+  PDIDEVICEOBJECTINSTANCE_DX3 = PDIDEVICEOBJECTINSTANCE_DX3W;
+{$ELSE}
+  TDIDEVICEOBJECTINSTANCE_DX3 = TDIDEVICEOBJECTINSTANCE_DX3A;
+  LPDIDEVICEOBJECTINSTANCE_DX3 = LPDIDEVICEOBJECTINSTANCE_DX3A;
+  PDIDEVICEOBJECTINSTANCE_DX3 = PDIDEVICEOBJECTINSTANCE_DX3A;
+{$ENDIF} // UNICODE
+  LPCDIDEVICEOBJECTINSTANCE_DX3A = ^TDIDEVICEOBJECTINSTANCE_DX3A;
+  LPCDIDEVICEOBJECTINSTANCE_DX3W = ^TDIDEVICEOBJECTINSTANCE_DX3W;
+  LPCDIDEVICEOBJECTINSTANCE_DX3 = ^TDIDEVICEOBJECTINSTANCE_DX3;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0500 }
+
+  LPDIDEVICEOBJECTINSTANCEA = ^TDIDEVICEOBJECTINSTANCEA;
+  PDIDEVICEOBJECTINSTANCEA = ^TDIDEVICEOBJECTINSTANCEA;
+  TDIDEVICEOBJECTINSTANCEA = record
+    dwSize: DWORD;
+    guidType: GUID;
+    dwOfs: DWORD;
+    dwType: DWORD;
+    dwFlags: DWORD;
+    tszName: array [0..MAX_PATH-1] of CHAR;
+{$IF DIRECTINPUT_VERSION >= $0500}
+    dwFFMaxForce: DWORD;
+    dwFFForceResolution: DWORD;
+    wCollectionNumber: WORD;
+    wDesignatorIndex: WORD;
+    wUsagePage: WORD;
+    wUsage: WORD;
+    dwDimension: DWORD;
+    wExponent: WORD;
+    wReportId: WORD;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0500 }
+  end;
+  LPDIDEVICEOBJECTINSTANCEW = ^TDIDEVICEOBJECTINSTANCEW;
+  PDIDEVICEOBJECTINSTANCEW = ^TDIDEVICEOBJECTINSTANCEW;
+  TDIDEVICEOBJECTINSTANCEW = record
+    dwSize: DWORD;
+    guidType: GUID;
+    dwOfs: DWORD;
+    dwType: DWORD;
+    dwFlags: DWORD;
+    tszName: array [0..MAX_PATH-1] of WCHAR;
+{$IF DIRECTINPUT_VERSION >= $0500}
+    dwFFMaxForce: DWORD;
+    dwFFForceResolution: DWORD;
+    wCollectionNumber: WORD;
+    wDesignatorIndex: WORD;
+    wUsagePage: WORD;
+    wUsage: WORD;
+    dwDimension: DWORD;
+    wExponent: WORD;
+    wReportId: WORD;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0500 }
+  end;
+{$IFDEF UNICODE}
+  TDIDEVICEOBJECTINSTANCE = TDIDEVICEOBJECTINSTANCEW;
+  LPDIDEVICEOBJECTINSTANCE = LPDIDEVICEOBJECTINSTANCEW;
+  PDIDEVICEOBJECTINSTANCE = PDIDEVICEOBJECTINSTANCEW;
+{$ELSE}
+  TDIDEVICEOBJECTINSTANCE = TDIDEVICEOBJECTINSTANCEA;
+  LPDIDEVICEOBJECTINSTANCE = LPDIDEVICEOBJECTINSTANCEA;
+  PDIDEVICEOBJECTINSTANCE = PDIDEVICEOBJECTINSTANCEA;
+{$ENDIF} // UNICODE
+  LPCDIDEVICEOBJECTINSTANCEA = ^TDIDEVICEOBJECTINSTANCEA;
+  PCDIDEVICEOBJECTINSTANCEA = ^TDIDEVICEOBJECTINSTANCEA;
+  LPCDIDEVICEOBJECTINSTANCEW = ^TDIDEVICEOBJECTINSTANCEW;
+  PCDIDEVICEOBJECTINSTANCEW = ^TDIDEVICEOBJECTINSTANCEW;
+  LPCDIDEVICEOBJECTINSTANCE = ^TDIDEVICEOBJECTINSTANCE;
+  PCDIDEVICEOBJECTINSTANCE = ^TDIDEVICEOBJECTINSTANCE;
+
+  LPDIENUMDEVICEOBJECTSCALLBACKA = function(lpddoi: LPCDIDEVICEOBJECTINSTANCEA; pvRef: LPVOID): BOOL; stdcall;
+  LPDIENUMDEVICEOBJECTSCALLBACKW = function(lpddoi: LPCDIDEVICEOBJECTINSTANCEW; pvRef: LPVOID): BOOL; stdcall;
+{$IFDEF UNICODE}
+  LPDIENUMDEVICEOBJECTSCALLBACK = LPDIENUMDEVICEOBJECTSCALLBACKW;
+{$ELSE}
+  LPDIENUMDEVICEOBJECTSCALLBACK = LPDIENUMDEVICEOBJECTSCALLBACKA;
+{$ENDIF} // !UNICODE
+
+{$IF DIRECTINPUT_VERSION >= $0500}
+const
+  DIDOI_FFACTUATOR      = $00000001;
+  DIDOI_FFEFFECTTRIGGER = $00000002;
+  DIDOI_POLLED          = $00008000;
+  DIDOI_ASPECTPOSITION  = $00000100;
+  DIDOI_ASPECTVELOCITY  = $00000200;
+  DIDOI_ASPECTACCEL     = $00000300;
+  DIDOI_ASPECTFORCE     = $00000400;
+  DIDOI_ASPECTMASK      = $00000F00;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0500 }
+{$IF DIRECTINPUT_VERSION >= $050a}
+  DIDOI_GUIDISUSAGE     = $00010000;
+{$ENDIF} { DIRECTINPUT_VERSION >= $050a }
+
+type
+  LPCDIPROPHEADER = ^TDIPROPHEADER;
+  PCDIPROPHEADER = ^TDIPROPHEADER;
+  LPDIPROPHEADER = ^TDIPROPHEADER;
+  PDIPROPHEADER = ^TDIPROPHEADER;
+  TDIPROPHEADER = record
+    dwSize: DWORD;
+    dwHeaderSize: DWORD;
+    dwObj: DWORD;
+    dwHow: DWORD;
+  end;
+
+const
+  DIPH_DEVICE           = 0;
+  DIPH_BYOFFSET         = 1;
+  DIPH_BYID             = 2;
+{$IF DIRECTINPUT_VERSION >= $050a}
+  DIPH_BYUSAGE          = 3;
+{$ENDIF} { DIRECTINPUT_VERSION >= $050a }
+
+//#if(DIRECTINPUT_VERSION >= 0x050a)
+//#define DIMAKEUSAGEDWORD(UsagePage, Usage) \
+//                                (DWORD)MAKELONG(Usage, UsagePage)
+//#endif /* DIRECTINPUT_VERSION >= 0x050a */
+
+type
+  LPCDIPROPDWORD = ^TDIPROPDWORD;
+  PCDIPROPDWORD = ^TDIPROPDWORD;
+  LPDIPROPDWORD = ^TDIPROPDWORD;
+  PDIPROPDWORD = ^TDIPROPDWORD;
+  TDIPROPDWORD = record
+    diph: TDIPROPHEADER;
+    dwData: DWORD;
+  end;
+
+{$IF DIRECTINPUT_VERSION >= $0800}
+  LPCDIPROPPOINTER = ^TDIPROPPOINTER;
+  PCDIPROPPOINTER = ^TDIPROPPOINTER;
+  LPDIPROPPOINTER = ^TDIPROPPOINTER;
+  PDIPROPPOINTER = ^TDIPROPPOINTER;
+  TDIPROPPOINTER = record
+    diph: TDIPROPHEADER;
+    uData: UINT_PTR;
+  end;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0800 }
+
+  LPCDIPROPRANGE = ^TDIPROPRANGE;
+  PCDIPROPRANGE = ^TDIPROPRANGE;
+  LPDIPROPRANGE = ^TDIPROPRANGE;
+  PDIPROPRANGE = ^TDIPROPRANGE;
+  TDIPROPRANGE = record
+    diph: TDIPROPHEADER;
+    lMin: LONG;
+    lMax: LONG;
+  end;
+
+const
+  DIPROPRANGE_NOMIN     = LONG($80000000);
+  DIPROPRANGE_NOMAX     = LONG($7FFFFFFF);
+
+{$IF DIRECTINPUT_VERSION >= $050a}
+type
+  LPCDIPROPCAL = ^TDIPROPCAL;
+  PCDIPROPCAL = ^TDIPROPCAL;
+  LPDIPROPCAL = ^TDIPROPCAL;
+  PDIPROPCAL = ^TDIPROPCAL;
+  TDIPROPCAL = record
+    diph: TDIPROPHEADER;
+    lMin: LONG;
+    lCenter: LONG;
+    lMax: LONG;
+  end;
+
+  LPCDIPROPCALPOV = ^TDIPROPCALPOV;
+  PCDIPROPCALPOV = ^TDIPROPCALPOV;
+  LPDIPROPCALPOV = ^TDIPROPCALPOV;
+  PDIPROPCALPOV = ^TDIPROPCALPOV;
+  TDIPROPCALPOV = record
+    diph: TDIPROPHEADER;
+    lMin: array [0..4] of LONG;
+    lMax: array [0..4] of LONG;
+  end;
+
+  LPCDIPROPGUIDANDPATH = ^TDIPROPGUIDANDPATH;
+  PCDIPROPGUIDANDPATH = ^TDIPROPGUIDANDPATH;
+  LPDIPROPGUIDANDPATH = ^TDIPROPGUIDANDPATH;
+  PDIPROPGUIDANDPATH = ^TDIPROPGUIDANDPATH;
+  TDIPROPGUIDANDPATH = record
+    diph: TDIPROPHEADER;
+    guidClass: GUID;
+    wszPath: array [0..MAX_PATH-1] of WCHAR;
+  end;
+
+  LPCDIPROPSTRING = ^TDIPROPSTRING;
+  PCDIPROPSTRING = ^TDIPROPSTRING;
+  LPDIPROPSTRING = ^TDIPROPSTRING;
+  PDIPROPSTRING = ^TDIPROPSTRING;
+  TDIPROPSTRING = record
+    diph: TDIPROPHEADER;
+    wsz: array [0..MAX_PATH-1] of WCHAR;
+  end;
+
+{$ENDIF} { DIRECTINPUT_VERSION >= $050a }
+
+{$IF DIRECTINPUT_VERSION >= $0800}
+const
+  MAXCPOINTSNUM        = 8;
+
+type
+  PCPOINT = ^TCPOINT;
+  TCPOINT = record
+    lP: LONG;      // raw value
+    dwLog: DWORD;  // logical_value / max_logical_value * 10000
+  end;
+
+  LPCDIPROPCPOINTS = ^TDIPROPCPOINTS;
+  PCDIPROPCPOINTS = ^TDIPROPCPOINTS;
+  LPDIPROPCPOINTS = ^TDIPROPCPOINTS;
+  PDIPROPCPOINTS = ^TDIPROPCPOINTS;
+  TDIPROPCPOINTS = record
+    diph: TDIPROPHEADER;
+    dwCPointsNum: DWORD;
+    cp: array [0..MAXCPOINTSNUM-1] of TCPOINT;
+  end;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0800 }
+
+
+//#ifdef __cplusplus
+//#define MAKEDIPROP(prop)    (*(const GUID * )(prop))
+//#else
+//#define MAKEDIPROP(prop)    ((REFGUID)(prop))
+//#endif
+
+var
+//#define DIPROP_BUFFERSIZE       MAKEDIPROP(1)
+  DIPROP_BUFFERSIZE: TGuid absolute 1;
+
+//#define DIPROP_AXISMODE         MAKEDIPROP(2)
+  DIPROP_AXISMODE: TGuid absolute 2;
+
+const
+  DIPROPAXISMODE_ABS    = 0;
+  DIPROPAXISMODE_REL    = 1;
+
+var
+//#define DIPROP_GRANULARITY      MAKEDIPROP(3)
+  DIPROP_GRANULARITY: TGuid absolute 3;
+
+//#define DIPROP_RANGE            MAKEDIPROP(4)
+  DIPROP_RANGE: TGuid absolute 4;
+
+//#define DIPROP_DEADZONE         MAKEDIPROP(5)
+  DIPROP_DEADZONE: TGuid absolute 5;
+
+//#define DIPROP_SATURATION       MAKEDIPROP(6)
+  DIPROP_SATURATION: TGuid absolute 6;
+
+//#define DIPROP_FFGAIN           MAKEDIPROP(7)
+  DIPROP_FFGAIN: TGuid absolute 7;
+
+//#define DIPROP_FFLOAD           MAKEDIPROP(8)
+  DIPROP_FFLOAD: TGuid absolute 8;
+
+//#define DIPROP_AUTOCENTER       MAKEDIPROP(9)
+  DIPROP_AUTOCENTER: TGuid absolute 9;
+
+const
+  DIPROPAUTOCENTER_OFF  = 0;
+  DIPROPAUTOCENTER_ON   = 1;
+
+var
+//#define DIPROP_CALIBRATIONMODE  MAKEDIPROP(10)
+  DIPROP_CALIBRATIONMODE: TGuid absolute 10;
+
+const
+  DIPROPCALIBRATIONMODE_COOKED  = 0;
+  DIPROPCALIBRATIONMODE_RAW     = 1;
+
+{$IF DIRECTINPUT_VERSION >= $050a}
+var
+//#define DIPROP_CALIBRATION      MAKEDIPROP(11)
+  DIPROP_CALIBRATION: TGuid absolute 11;
+
+//#define DIPROP_GUIDANDPATH      MAKEDIPROP(12)
+  DIPROP_GUIDANDPATH: TGuid absolute 12;
+
+//#define DIPROP_INSTANCENAME     MAKEDIPROP(13)
+  DIPROP_INSTANCENAME: TGuid absolute 13;
+
+//#define DIPROP_PRODUCTNAME      MAKEDIPROP(14)
+  DIPROP_PRODUCTNAME: TGuid absolute 14;
+{$ENDIF} { DIRECTINPUT_VERSION >= $050a }
+
+{$IF DIRECTINPUT_VERSION >= $05b2}
+var
+//#define DIPROP_JOYSTICKID       MAKEDIPROP(15)
+  DIPROP_JOYSTICKID: TGuid absolute 15;
+
+//#define DIPROP_GETPORTDISPLAYNAME       MAKEDIPROP(16)
+  DIPROP_GETPORTDISPLAYNAME: TGuid absolute 16;
+
+{$ENDIF} { DIRECTINPUT_VERSION >= $05b2 }
+
+{$IF DIRECTINPUT_VERSION >= $0700}
+var
+//#define DIPROP_PHYSICALRANGE            MAKEDIPROP(18)
+  DIPROP_PHYSICALRANGE: TGuid absolute 18;
+
+//#define DIPROP_LOGICALRANGE             MAKEDIPROP(19)
+  DIPROP_LOGICALRANGE: TGuid absolute 19;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0700 }
+
+{$IF DIRECTINPUT_VERSION >= $0800}
+//#define DIPROP_KEYNAME                     MAKEDIPROP(20)
+  DIPROP_KEYNAME: TGuid absolute 20;
+
+//#define DIPROP_CPOINTS                 MAKEDIPROP(21)
+  DIPROP_CPOINTS: TGuid absolute 21;
+
+//#define DIPROP_APPDATA       MAKEDIPROP(22)
+  DIPROP_APPDATA: TGuid absolute 22;
+
+//#define DIPROP_SCANCODE      MAKEDIPROP(23)
+  DIPROP_SCANCODE: TGuid absolute 23;
+
+//#define DIPROP_VIDPID           MAKEDIPROP(24)
+  DIPROP_VIDPID: TGuid absolute 24;
+
+//#define DIPROP_USERNAME         MAKEDIPROP(25)
+  DIPROP_USERNAME: TGuid absolute 25;
+
+//#define DIPROP_TYPENAME         MAKEDIPROP(26)
+  DIPROP_TYPENAME: TGuid absolute 26;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0800 }
+
+
+type
+  LPCDIDEVICEOBJECTDATA_DX = ^TDIDEVICEOBJECTDATA_DX3;
+  PCDIDEVICEOBJECTDATA_DX = ^TDIDEVICEOBJECTDATA_DX3;
+  LPDIDEVICEOBJECTDATA_DX3 = ^TDIDEVICEOBJECTDATA_DX3;
+  PDIDEVICEOBJECTDATA_DX3 = ^TDIDEVICEOBJECTDATA_DX3;
+  TDIDEVICEOBJECTDATA_DX3 = record
+    dwOfs: DWORD;
+    dwData: DWORD;
+    dwTimeStamp: DWORD;
+    dwSequence: DWORD;
+  end;
+
+  LPCDIDEVICEOBJECTDATA = ^TDIDEVICEOBJECTDATA;
+  PCDIDEVICEOBJECTDATA = ^TDIDEVICEOBJECTDATA;
+  LPDIDEVICEOBJECTDATA = ^TDIDEVICEOBJECTDATA;
+  PDIDEVICEOBJECTDATA = ^TDIDEVICEOBJECTDATA;
+  TDIDEVICEOBJECTDATA = record
+    dwOfs: DWORD;
+    dwData: DWORD;
+    dwTimeStamp: DWORD;
+    dwSequence: DWORD;
+{$IF DIRECTINPUT_VERSION >= $0800}
+    uAppData: UINT_PTR;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0800 }
+  end;
+
+const
+  DIGDD_PEEK        = $00000001;
+
+//#define DISEQUENCE_COMPARE(dwSequence1, cmp, dwSequence2) \
+//                        ((int)((dwSequence1) - (dwSequence2)) cmp 0)
+const
+  DISCL_EXCLUSIVE    = $00000001;
+  DISCL_NONEXCLUSIVE = $00000002;
+  DISCL_FOREGROUND   = $00000004;
+  DISCL_BACKGROUND   = $00000008;
+  DISCL_NOWINKEY     = $00000010;
+
+{$IF DIRECTINPUT_VERSION >= $0500}
+{ These structures are defined for DirectX 3.0 compatibility }
+
+type
+  LPDIDEVICEINSTANCE_DX3A = ^TDIDEVICEINSTANCE_DX3A;
+  PDIDEVICEINSTANCE_DX3A = ^TDIDEVICEINSTANCE_DX3A;
+  TDIDEVICEINSTANCE_DX3A = record
+    dwSize: DWORD;
+    guidInstance: GUID;
+    guidProduct: GUID;
+    dwDevType: DWORD;
+    tszInstanceName: array [0..MAX_PATH-1] of CHAR;
+    tszProductName: array [0..MAX_PATH-1] of CHAR;
+  end;
+  LPDIDEVICEINSTANCE_DX3W = ^TDIDEVICEINSTANCE_DX3W;
+  PDIDEVICEINSTANCE_DX3W = ^TDIDEVICEINSTANCE_DX3W;
+  TDIDEVICEINSTANCE_DX3W = record
+    dwSize: DWORD;
+    guidInstance: GUID;
+    guidProduct: GUID;
+    dwDevType: DWORD;
+    tszInstanceName: array [0..MAX_PATH-1] of WCHAR;
+    tszProductName: array [0..MAX_PATH-1] of WCHAR;
+  end;
+{$IFDEF UNICODE}
+  TDIDEVICEINSTANCE_DX3 = TDIDEVICEINSTANCE_DX3W;
+  LPDIDEVICEINSTANCE_DX3 = LPDIDEVICEINSTANCE_DX3W;
+  PDIDEVICEINSTANCE_DX3 = PDIDEVICEINSTANCE_DX3W;
+{$ELSE}
+  TDIDEVICEINSTANCE_DX3 = TDIDEVICEINSTANCE_DX3A;
+  LPDIDEVICEINSTANCE_DX3 = LPDIDEVICEINSTANCE_DX3A;
+  PDIDEVICEINSTANCE_DX3 = PDIDEVICEINSTANCE_DX3A;
+{$ENDIF} // UNICODE
+  LPCDIDEVICEINSTANCE_DX3A = ^TDIDEVICEINSTANCE_DX3A;
+  PCDIDEVICEINSTANCE_DX3A = ^TDIDEVICEINSTANCE_DX3A;
+  LPCDIDEVICEINSTANCE_DX3W = ^TDIDEVICEINSTANCE_DX3W;
+  PCDIDEVICEINSTANCE_DX3W = ^TDIDEVICEINSTANCE_DX3W;
+  LPCDIDEVICEINSTANCE_DX3 = ^TDIDEVICEINSTANCE_DX3;
+  PCDIDEVICEINSTANCE_DX3 = ^TDIDEVICEINSTANCE_DX3;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0500 }
+
+  LPDIDEVICEINSTANCEA = ^TDIDEVICEINSTANCEA;
+  PDIDEVICEINSTANCEA = ^TDIDEVICEINSTANCEA;
+  TDIDEVICEINSTANCEA = record
+    dwSize: DWORD;
+    guidInstance: GUID;
+    guidProduct: GUID;
+    dwDevType: DWORD;
+    tszInstanceName: array [0..MAX_PATH-1] of CHAR;
+    tszProductName: array [0..MAX_PATH-1] of CHAR;
+{$IF DIRECTINPUT_VERSION >= $0500}
+    guidFFDriver: GUID;
+    wUsagePage: WORD;
+    wUsage: WORD;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0500 }
+  end;
+  LPDIDEVICEINSTANCEW = ^TDIDEVICEINSTANCEW;
+  PDIDEVICEINSTANCEW = ^TDIDEVICEINSTANCEW;
+  TDIDEVICEINSTANCEW = record
+    dwSize: DWORD;
+    guidInstance: GUID;
+    guidProduct: GUID;
+    dwDevType: DWORD;
+    tszInstanceName: array [0..MAX_PATH-1] of WCHAR;
+    tszProductName: array [0..MAX_PATH-1] of WCHAR;
+{$IF DIRECTINPUT_VERSION >= $0500}
+    guidFFDriver: GUID;
+    wUsagePage: WORD;
+    wUsage: WORD;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0500 }
+  end;
+{$IFDEF UNICODE}
+  TDIDEVICEINSTANCE = TDIDEVICEINSTANCEW;
+  LPDIDEVICEINSTANCE = LPDIDEVICEINSTANCEW;
+  PDIDEVICEINSTANCE = PDIDEVICEINSTANCEW;
+{$ELSE}
+  TDIDEVICEINSTANCE = TDIDEVICEINSTANCEA;
+  LPDIDEVICEINSTANCE = LPDIDEVICEINSTANCEA;
+  PDIDEVICEINSTANCE = PDIDEVICEINSTANCEA;
+{$ENDIF} // UNICODE
+
+  LPCDIDEVICEINSTANCEA = ^TDIDEVICEINSTANCEA;
+  PCDIDEVICEINSTANCEA = ^TDIDEVICEINSTANCEA;
+  LPCDIDEVICEINSTANCEW = ^TDIDEVICEINSTANCEW;
+  PCDIDEVICEINSTANCEW = ^TDIDEVICEINSTANCEW;
+  LPCDIDEVICEINSTANCE = ^TDIDEVICEINSTANCE;
+  PCDIDEVICEINSTANCE = ^TDIDEVICEINSTANCE;
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInputDeviceW
+
+  IDirectInputDeviceW = interface(IUnknown)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInputDeviceW methods ***)
+    function GetCapabilities(lpDIDevCaps: LPDIDEVCAPS): HRESULT; stdcall;
+    function EnumObjects(lpCallback: LPDIENUMDEVICEOBJECTSCALLBACKW; pvRef: LPVOID; dwFlags: DWORD): HRESULT; stdcall;
+    function GetProperty(const rguidProp: TGuid {REFGUID}; pdiph: LPDIPROPHEADER): HRESULT; stdcall;
+    function SetProperty(const rguidProp: TGuid {REFGUID}; pdiph: LPCDIPROPHEADER): HRESULT; stdcall;
+    function Acquire: HRESULT; stdcall;
+    function Unacquire: HRESULT; stdcall;
+    function GetDeviceState(cbData: DWORD; lpvData: LPVOID): HRESULT; stdcall;
+    function GetDeviceData(cbObjectData: DWORD; rgdod: LPDIDEVICEOBJECTDATA; pdwInOut: LPDWORD; dwFlags: DWORD): HRESULT; stdcall;
+    function SetDataFormat(lpdf: LPCDIDATAFORMAT): HRESULT; stdcall;
+    function SetEventNotification(hEvent: HANDLE): HRESULT; stdcall;
+    function SetCooperativeLevel(hwnd: HWND; dwFlags: DWORD): HRESULT; stdcall;
+    function GetObjectInfo(pdidoi: LPDIDEVICEOBJECTINSTANCEW; dwObj: DWORD; dwHow: DWORD): HRESULT; stdcall;
+    function GetDeviceInfo(pdidi: LPDIDEVICEINSTANCEW): HRESULT; stdcall;
+    function RunControlPanel(hwndOwner: HWND; dwFlags: DWORD): HRESULT; stdcall;
+    function Initialize(hinst: HINST; dwVersion: DWORD; const rguid: TGuid {REFGUID}): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInputDeviceW *LPDIRECTINPUTDEVICEW;
+  LPDIRECTINPUTDEVICEW = IDirectInputDeviceW;
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInputDeviceA
+
+  IDirectInputDeviceA = interface(IUnknown)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInputDeviceA methods ***)
+    function GetCapabilities(lpDIDevCaps: LPDIDEVCAPS): HRESULT; stdcall;
+    function EnumObjects(lpCallback: LPDIENUMDEVICEOBJECTSCALLBACKA; pvRef: LPVOID; dwFlags: DWORD): HRESULT; stdcall;
+    function GetProperty(const rguidProp: TGuid {REFGUID}; pdiph: LPDIPROPHEADER): HRESULT; stdcall;
+    function SetProperty(const rguidProp: TGuid {REFGUID}; pdiph: LPCDIPROPHEADER): HRESULT; stdcall;
+    function Acquire: HRESULT; stdcall;
+    function Unacquire: HRESULT; stdcall;
+    function GetDeviceState(cbData: DWORD; lpvData: LPVOID): HRESULT; stdcall;
+    function GetDeviceData(cbObjectData: DWORD; rgdod: LPDIDEVICEOBJECTDATA; pdwInOut: LPDWORD; dwFlags: DWORD): HRESULT; stdcall;
+    function SetDataFormat(lpdf: LPCDIDATAFORMAT): HRESULT; stdcall;
+    function SetEventNotification(hEvent: HANDLE): HRESULT; stdcall;
+    function SetCooperativeLevel(hwnd: HWND; dwFlags: DWORD): HRESULT; stdcall;
+    function GetObjectInfo(pdidoi: LPDIDEVICEOBJECTINSTANCEA; dwObj: DWORD; dwHow: DWORD): HRESULT; stdcall;
+    function GetDeviceInfo(pdidi: LPDIDEVICEINSTANCEA): HRESULT; stdcall;
+    function RunControlPanel(hwndOwner: HWND; dwFlags: DWORD): HRESULT; stdcall;
+    function Initialize(hinst: HINST; dwVersion: DWORD; const rguid: TGuid {REFGUID}): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInputDeviceA *LPDIRECTINPUTDEVICEA;
+  LPDIRECTINPUTDEVICEA = IDirectInputDeviceA;
+
+{$IFDEF UNICODE}
+const
+  IID_IDirectInputDevice: TIID = '{5944E681-C92E-11CF-BFC7-444553540000}'{IID_IDirectInputDeviceW};
+type
+  IDirectInputDevice = IDirectInputDeviceW;
+{$ELSE}
+const
+  IID_IDirectInputDevice: TIID = '{5944E680-C92E-11CF-BFC7-444553540000}'{IID_IDirectInputDeviceA};
+type
+  IDirectInputDevice = IDirectInputDeviceA;
+{$ENDIF}
+//typedef struct IDirectInputDevice *LPDIRECTINPUTDEVICE;
+  LPDIRECTINPUTDEVICE = IDirectInputDevice;
+
+//#if !defined(__cplusplus) || defined(CINTERFACE)
+//#define IDirectInputDevice_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+//#define IDirectInputDevice_AddRef(p) (p)->lpVtbl->AddRef(p)
+//#define IDirectInputDevice_Release(p) (p)->lpVtbl->Release(p)
+//#define IDirectInputDevice_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a)
+//#define IDirectInputDevice_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c)
+//#define IDirectInputDevice_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b)
+//#define IDirectInputDevice_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b)
+//#define IDirectInputDevice_Acquire(p) (p)->lpVtbl->Acquire(p)
+//#define IDirectInputDevice_Unacquire(p) (p)->lpVtbl->Unacquire(p)
+//#define IDirectInputDevice_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b)
+//#define IDirectInputDevice_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d)
+//#define IDirectInputDevice_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a)
+//#define IDirectInputDevice_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a)
+//#define IDirectInputDevice_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+//#define IDirectInputDevice_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c)
+//#define IDirectInputDevice_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a)
+//#define IDirectInputDevice_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+//#define IDirectInputDevice_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+//#else
+//#define IDirectInputDevice_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+//#define IDirectInputDevice_AddRef(p) (p)->AddRef()
+//#define IDirectInputDevice_Release(p) (p)->Release()
+//#define IDirectInputDevice_GetCapabilities(p,a) (p)->GetCapabilities(a)
+//#define IDirectInputDevice_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c)
+//#define IDirectInputDevice_GetProperty(p,a,b) (p)->GetProperty(a,b)
+//#define IDirectInputDevice_SetProperty(p,a,b) (p)->SetProperty(a,b)
+//#define IDirectInputDevice_Acquire(p) (p)->Acquire()
+//#define IDirectInputDevice_Unacquire(p) (p)->Unacquire()
+//#define IDirectInputDevice_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b)
+//#define IDirectInputDevice_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d)
+//#define IDirectInputDevice_SetDataFormat(p,a) (p)->SetDataFormat(a)
+//#define IDirectInputDevice_SetEventNotification(p,a) (p)->SetEventNotification(a)
+//#define IDirectInputDevice_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+//#define IDirectInputDevice_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c)
+//#define IDirectInputDevice_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a)
+//#define IDirectInputDevice_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+//#define IDirectInputDevice_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+//#endif
+
+//#endif /* DIJ_RINGZERO */
+
+
+{$IF DIRECTINPUT_VERSION >= $0500}
+
+const
+  DISFFC_RESET           = $00000001;
+  DISFFC_STOPALL         = $00000002;
+  DISFFC_PAUSE           = $00000004;
+  DISFFC_CONTINUE        = $00000008;
+  DISFFC_SETACTUATORSON  = $00000010;
+  DISFFC_SETACTUATORSOFF = $00000020;
+
+  DIGFFS_EMPTY           = $00000001;
+  DIGFFS_STOPPED         = $00000002;
+  DIGFFS_PAUSED          = $00000004;
+  DIGFFS_ACTUATORSON     = $00000010;
+  DIGFFS_ACTUATORSOFF    = $00000020;
+  DIGFFS_POWERON         = $00000040;
+  DIGFFS_POWEROFF        = $00000080;
+  DIGFFS_SAFETYSWITCHON  = $00000100;
+  DIGFFS_SAFETYSWITCHOFF = $00000200;
+  DIGFFS_USERFFSWITCHON  = $00000400;
+  DIGFFS_USERFFSWITCHOFF = $00000800;
+  DIGFFS_DEVICELOST      = $80000000;
+
+//#ifndef DIJ_RINGZERO
+
+type
+  LPDIEFFECTINFOA = ^TDIEFFECTINFOA;
+  PDIEFFECTINFOA = ^TDIEFFECTINFOA;
+  TDIEFFECTINFOA = record
+    dwSize: DWORD;
+    guid: GUID;
+    dwEffType: DWORD;
+    dwStaticParams: DWORD;
+    dwDynamicParams: DWORD;
+    tszName: array [0..MAX_PATH-1] of CHAR;
+  end;
+  LPDIEFFECTINFOW = ^TDIEFFECTINFOW;
+  PDIEFFECTINFOW = ^TDIEFFECTINFOW;
+  TDIEFFECTINFOW = record
+    dwSize: DWORD;
+    guid: GUID;
+    dwEffType: DWORD;
+    dwStaticParams: DWORD;
+    dwDynamicParams: DWORD;
+    tszName: array [0..MAX_PATH-1] of WCHAR;
+  end;
+{$IFDEF UNICODE}
+  TDIEFFECTINFO = TDIEFFECTINFOW;
+  LPDIEFFECTINFO = LPDIEFFECTINFOW;
+  PDIEFFECTINFO = PDIEFFECTINFOW;
+{$ELSE}
+  TDIEFFECTINFO = TDIEFFECTINFOA;
+  LPDIEFFECTINFO = LPDIEFFECTINFOA;
+  PDIEFFECTINFO = PDIEFFECTINFOA;
+{$ENDIF} // UNICODE
+  LPCDIEFFECTINFOA = ^TDIEFFECTINFOA;
+  PCDIEFFECTINFOA = ^TDIEFFECTINFOA;
+  LPCDIEFFECTINFOW = ^TDIEFFECTINFOW;
+  PCDIEFFECTINFOW = ^TDIEFFECTINFOW;
+  LPCDIEFFECTINFO = ^TDIEFFECTINFO;
+  PCDIEFFECTINFO = ^TDIEFFECTINFO;
+
+const
+  DISDD_CONTINUE        = $00000001;
+
+type
+  LPDIENUMEFFECTSCALLBACKA = function(pdei: LPCDIEFFECTINFOA; pvRef: LPVOID): BOOL; stdcall;
+  LPDIENUMEFFECTSCALLBACKW = function(pdei: LPCDIEFFECTINFOW; pvRef: LPVOID): BOOL; stdcall;
+{$IFDEF UNICODE}
+  LPDIENUMEFFECTSCALLBACK = LPDIENUMEFFECTSCALLBACKW;
+{$ELSE}
+  LPDIENUMEFFECTSCALLBACK = LPDIENUMEFFECTSCALLBACKA;
+{$ENDIF} // !UNICODE
+  LPDIENUMCREATEDEFFECTOBJECTSCALLBACK = function(peff: LPDIRECTINPUTEFFECT; pvRef: LPVOID): BOOL; stdcall;
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInputDevice2W
+
+  IDirectInputDevice2W = interface(IDirectInputDeviceW)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInputDeviceW methods ***)
+    {STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS) PURE;
+    STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW,LPVOID,DWORD) PURE;
+    STDMETHOD(GetProperty)(THIS_ REFGUID,LPDIPROPHEADER) PURE;
+    STDMETHOD(SetProperty)(THIS_ REFGUID,LPCDIPROPHEADER) PURE;
+    STDMETHOD(Acquire)(THIS) PURE;
+    STDMETHOD(Unacquire)(THIS) PURE;
+    STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID) PURE;
+    STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE;
+    STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT) PURE;
+    STDMETHOD(SetEventNotification)(THIS_ HANDLE) PURE;
+    STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE;
+    STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW,DWORD,DWORD) PURE;
+    STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW) PURE;
+    STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE;
+    STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD,REFGUID) PURE;}
+
+    (*** IDirectInputDevice2W methods ***)
+    function CreateEffect(const rguid: TGuid {REFGUID}; lpeff: LPCDIEFFECT; out ppdeff: IDirectInputEffect {LPDIRECTINPUTEFFECT *}; punkOuter: {LPUNKNOWN}IUnknown): HRESULT; stdcall;
+    function EnumEffects(lpCallback: LPDIENUMEFFECTSCALLBACKW; pvRef: LPVOID; dwEffType: DWORD): HRESULT; stdcall;
+    function GetEffectInfo(pdei: LPDIEFFECTINFOW; const rguid: TGuid {REFGUID}): HRESULT; stdcall;
+    function GetForceFeedbackState(pdwOut: LPDWORD): HRESULT; stdcall;
+    function SendForceFeedbackCommand(dwFlags: DWORD): HRESULT; stdcall;
+    function EnumCreatedEffectObjects(lpCallback: LPDIENUMCREATEDEFFECTOBJECTSCALLBACK; pvRef: LPVOID; fl: DWORD): HRESULT; stdcall;
+    function Escape(pesc: LPDIEFFESCAPE): HRESULT; stdcall;
+    function Poll: HRESULT; stdcall;
+    function SendDeviceData(cbObjectData: DWORD; rgdod: LPCDIDEVICEOBJECTDATA; pdwInOut: LPDWORD; fl: DWORD): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInputDevice2W *LPDIRECTINPUTDEVICE2W;
+  LPDIRECTINPUTDEVICE2W = IDirectInputDevice2W;
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInputDevice2A
+
+  IDirectInputDevice2A = interface(IDirectInputDeviceA)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInputDeviceA methods ***)
+    {STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS) PURE;
+    STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA,LPVOID,DWORD) PURE;
+    STDMETHOD(GetProperty)(THIS_ REFGUID,LPDIPROPHEADER) PURE;
+    STDMETHOD(SetProperty)(THIS_ REFGUID,LPCDIPROPHEADER) PURE;
+    STDMETHOD(Acquire)(THIS) PURE;
+    STDMETHOD(Unacquire)(THIS) PURE;
+    STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID) PURE;
+    STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE;
+    STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT) PURE;
+    STDMETHOD(SetEventNotification)(THIS_ HANDLE) PURE;
+    STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE;
+    STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA,DWORD,DWORD) PURE;
+    STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA) PURE;
+    STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE;
+    STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD,REFGUID) PURE;}
+
+    (*** IDirectInputDevice2A methods ***)
+    function CreateEffect(const rguid: TGuid {REFGUID}; lpeff: LPCDIEFFECT; out ppdeff: IDirectInputEffect {LPDIRECTINPUTEFFECT *}; punkOuter: {LPUNKNOWN}IUnknown): HRESULT; stdcall;
+    function EnumEffects(lpCallback: LPDIENUMEFFECTSCALLBACKA; pvRef: LPVOID; dwEffType: DWORD): HRESULT; stdcall;
+    function GetEffectInfo(pdei: LPDIEFFECTINFOA; const rguid: TGuid {REFGUID}): HRESULT; stdcall;
+    function GetForceFeedbackState(pdwOut: LPDWORD): HRESULT; stdcall;
+    function SendForceFeedbackCommand(dwFlags: DWORD): HRESULT; stdcall;
+    function EnumCreatedEffectObjects(lpCallback: LPDIENUMCREATEDEFFECTOBJECTSCALLBACK; pvRef: LPVOID; fl: DWORD): HRESULT; stdcall;
+    function Escape(pesc: LPDIEFFESCAPE): HRESULT; stdcall;
+    function Poll: HRESULT; stdcall;
+    function SendDeviceData(cbObjectData: DWORD; rgdod: LPCDIDEVICEOBJECTDATA; pdwInOut: LPDWORD; fl: DWORD): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInputDevice2A *LPDIRECTINPUTDEVICE2A;
+  LPDIRECTINPUTDEVICE2A = IDirectInputDevice2A;
+
+{$IFDEF UNICODE}
+const
+  IID_IDirectInputDevice2: TIID = '{5944E683-C92E-11CF-BFC7-444553540000}'{IID_IDirectInputDevice2W};
+type
+  IDirectInputDevice2 = IDirectInputDevice2W;
+{$ELSE}
+const
+  IID_IDirectInputDevice2: TIID = '{5944E682-C92E-11CF-BFC7-444553540000}'{IID_IDirectInputDevice2A};
+type
+  IDirectInputDevice2 = IDirectInputDevice2A;
+{$ENDIF}
+//typedef struct IDirectInputDevice2 *LPDIRECTINPUTDEVICE2;
+  LPDIRECTINPUTDEVICE2 = IDirectInputDevice2;
+
+//#if !defined(__cplusplus) || defined(CINTERFACE)
+//#define IDirectInputDevice2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+//#define IDirectInputDevice2_AddRef(p) (p)->lpVtbl->AddRef(p)
+//#define IDirectInputDevice2_Release(p) (p)->lpVtbl->Release(p)
+//#define IDirectInputDevice2_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a)
+//#define IDirectInputDevice2_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c)
+//#define IDirectInputDevice2_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b)
+//#define IDirectInputDevice2_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b)
+//#define IDirectInputDevice2_Acquire(p) (p)->lpVtbl->Acquire(p)
+//#define IDirectInputDevice2_Unacquire(p) (p)->lpVtbl->Unacquire(p)
+//#define IDirectInputDevice2_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b)
+//#define IDirectInputDevice2_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d)
+//#define IDirectInputDevice2_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a)
+//#define IDirectInputDevice2_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a)
+//#define IDirectInputDevice2_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+//#define IDirectInputDevice2_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c)
+//#define IDirectInputDevice2_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a)
+//#define IDirectInputDevice2_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+//#define IDirectInputDevice2_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+//#define IDirectInputDevice2_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d)
+//#define IDirectInputDevice2_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c)
+//#define IDirectInputDevice2_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b)
+//#define IDirectInputDevice2_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a)
+//#define IDirectInputDevice2_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a)
+//#define IDirectInputDevice2_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c)
+//#define IDirectInputDevice2_Escape(p,a) (p)->lpVtbl->Escape(p,a)
+//#define IDirectInputDevice2_Poll(p) (p)->lpVtbl->Poll(p)
+//#define IDirectInputDevice2_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d)
+//#else
+//#define IDirectInputDevice2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+//#define IDirectInputDevice2_AddRef(p) (p)->AddRef()
+//#define IDirectInputDevice2_Release(p) (p)->Release()
+//#define IDirectInputDevice2_GetCapabilities(p,a) (p)->GetCapabilities(a)
+//#define IDirectInputDevice2_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c)
+//#define IDirectInputDevice2_GetProperty(p,a,b) (p)->GetProperty(a,b)
+//#define IDirectInputDevice2_SetProperty(p,a,b) (p)->SetProperty(a,b)
+//#define IDirectInputDevice2_Acquire(p) (p)->Acquire()
+//#define IDirectInputDevice2_Unacquire(p) (p)->Unacquire()
+//#define IDirectInputDevice2_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b)
+//#define IDirectInputDevice2_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d)
+//#define IDirectInputDevice2_SetDataFormat(p,a) (p)->SetDataFormat(a)
+//#define IDirectInputDevice2_SetEventNotification(p,a) (p)->SetEventNotification(a)
+//#define IDirectInputDevice2_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+//#define IDirectInputDevice2_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c)
+//#define IDirectInputDevice2_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a)
+//#define IDirectInputDevice2_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+//#define IDirectInputDevice2_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+//#define IDirectInputDevice2_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d)
+//#define IDirectInputDevice2_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c)
+//#define IDirectInputDevice2_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b)
+//#define IDirectInputDevice2_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a)
+//#define IDirectInputDevice2_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a)
+//#define IDirectInputDevice2_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c)
+//#define IDirectInputDevice2_Escape(p,a) (p)->Escape(a)
+//#define IDirectInputDevice2_Poll(p) (p)->Poll()
+//#define IDirectInputDevice2_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d)
+//#endif
+
+//#endif /* DIJ_RINGZERO */
+
+{$ENDIF} { DIRECTINPUT_VERSION >= $0500 }
+
+{$IF DIRECTINPUT_VERSION >= $0700}
+const
+  DIFEF_DEFAULT             = $00000000;
+  DIFEF_INCLUDENONSTANDARD  = $00000001;
+  DIFEF_MODIFYIFNEEDED      = $00000010;
+
+//#ifndef DIJ_RINGZERO
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInputDevice7W
+
+type
+  IDirectInputDevice7W = interface(IDirectInputDevice2W)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInputDevice2W methods ***)
+    {STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS) PURE;
+    STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW,LPVOID,DWORD) PURE;
+    STDMETHOD(GetProperty)(THIS_ REFGUID,LPDIPROPHEADER) PURE;
+    STDMETHOD(SetProperty)(THIS_ REFGUID,LPCDIPROPHEADER) PURE;
+    STDMETHOD(Acquire)(THIS) PURE;
+    STDMETHOD(Unacquire)(THIS) PURE;
+    STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID) PURE;
+    STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE;
+    STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT) PURE;
+    STDMETHOD(SetEventNotification)(THIS_ HANDLE) PURE;
+    STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE;
+    STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW,DWORD,DWORD) PURE;
+    STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW) PURE;
+    STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE;
+    STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD,REFGUID) PURE;
+    STDMETHOD(CreateEffect)(THIS_ REFGUID,LPCDIEFFECT,LPDIRECTINPUTEFFECT *,LPUNKNOWN) PURE;
+    STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKW,LPVOID,DWORD) PURE;
+    STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOW,REFGUID) PURE;
+    STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD) PURE;
+    STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD) PURE;
+    STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK,LPVOID,DWORD) PURE;
+    STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE) PURE;
+    STDMETHOD(Poll)(THIS) PURE;
+    STDMETHOD(SendDeviceData)(THIS_ DWORD,LPCDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE;}
+
+    (*** IDirectInputDevice7W methods ***)
+    function EnumEffectsInFile(lpszFileName: LPCWSTR; pec: LPDIENUMEFFECTSINFILECALLBACK; pvRef: LPVOID; dwFlags: DWORD): HRESULT; stdcall;
+    function WriteEffectToFile(lpszFileName: LPCWSTR; dwEntries: DWORD; rgDiFileEft: LPDIFILEEFFECT; dwFlags: DWORD): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInputDevice7W *LPDIRECTINPUTDEVICE7W;
+  LPDIRECTINPUTDEVICE7W = IDirectInputDevice7W;
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInputDevice7A
+
+  IDirectInputDevice7A = interface(IDirectInputDevice2A)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInputDevice2A methods ***)
+    {STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS) PURE;
+    STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA,LPVOID,DWORD) PURE;
+    STDMETHOD(GetProperty)(THIS_ REFGUID,LPDIPROPHEADER) PURE;
+    STDMETHOD(SetProperty)(THIS_ REFGUID,LPCDIPROPHEADER) PURE;
+    STDMETHOD(Acquire)(THIS) PURE;
+    STDMETHOD(Unacquire)(THIS) PURE;
+    STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID) PURE;
+    STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE;
+    STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT) PURE;
+    STDMETHOD(SetEventNotification)(THIS_ HANDLE) PURE;
+    STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE;
+    STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA,DWORD,DWORD) PURE;
+    STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA) PURE;
+    STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE;
+    STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD,REFGUID) PURE;
+    STDMETHOD(CreateEffect)(THIS_ REFGUID,LPCDIEFFECT,LPDIRECTINPUTEFFECT *,LPUNKNOWN) PURE;
+    STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA,LPVOID,DWORD) PURE;
+    STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA,REFGUID) PURE;
+    STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD) PURE;
+    STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD) PURE;
+    STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK,LPVOID,DWORD) PURE;
+    STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE) PURE;
+    STDMETHOD(Poll)(THIS) PURE;
+    STDMETHOD(SendDeviceData)(THIS_ DWORD,LPCDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE;}
+
+    (*** IDirectInputDevice7A methods ***)
+    function EnumEffectsInFile(lpszFileName: LPCSTR; pec: LPDIENUMEFFECTSINFILECALLBACK; pvRef: LPVOID; dwFlags: DWORD): HRESULT; stdcall;
+    function WriteEffectToFile(lpszFileName: LPCSTR; dwEntries: DWORD; rgDiFileEft: LPDIFILEEFFECT; dwFlags: DWORD): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInputDevice7A *LPDIRECTINPUTDEVICE7A;
+  LPDIRECTINPUTDEVICE7A = IDirectInputDevice7A;
+
+{$IFDEF UNICODE}
+const
+  IID_IDirectInputDevice7: TIID = '{57D7C6BD-2356-11D3-8E9D-00C04F6844AE}'{IID_IDirectInputDevice7W};
+type
+  IDirectInputDevice7 = IDirectInputDevice7W;
+{$ELSE}
+const
+  IID_IDirectInputDevice7: TIID = '{57D7C6BC-2356-11D3-8E9D-00C04F6844AE}'{IID_IDirectInputDevice7A};
+type
+  IDirectInputDevice7 = IDirectInputDevice7A;
+{$ENDIF}
+//typedef struct IDirectInputDevice7 *LPDIRECTINPUTDEVICE7;
+  LPDIRECTINPUTDEVICE7 = IDirectInputDevice7;
+
+//#if !defined(__cplusplus) || defined(CINTERFACE)
+//#define IDirectInputDevice7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+//#define IDirectInputDevice7_AddRef(p) (p)->lpVtbl->AddRef(p)
+//#define IDirectInputDevice7_Release(p) (p)->lpVtbl->Release(p)
+//#define IDirectInputDevice7_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a)
+//#define IDirectInputDevice7_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c)
+//#define IDirectInputDevice7_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b)
+//#define IDirectInputDevice7_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b)
+//#define IDirectInputDevice7_Acquire(p) (p)->lpVtbl->Acquire(p)
+//#define IDirectInputDevice7_Unacquire(p) (p)->lpVtbl->Unacquire(p)
+//#define IDirectInputDevice7_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b)
+//#define IDirectInputDevice7_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d)
+//#define IDirectInputDevice7_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a)
+//#define IDirectInputDevice7_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a)
+//#define IDirectInputDevice7_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+//#define IDirectInputDevice7_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c)
+//#define IDirectInputDevice7_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a)
+//#define IDirectInputDevice7_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+//#define IDirectInputDevice7_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+//#define IDirectInputDevice7_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d)
+//#define IDirectInputDevice7_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c)
+//#define IDirectInputDevice7_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b)
+//#define IDirectInputDevice7_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a)
+//#define IDirectInputDevice7_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a)
+//#define IDirectInputDevice7_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c)
+//#define IDirectInputDevice7_Escape(p,a) (p)->lpVtbl->Escape(p,a)
+//#define IDirectInputDevice7_Poll(p) (p)->lpVtbl->Poll(p)
+//#define IDirectInputDevice7_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d)
+//#define IDirectInputDevice7_EnumEffectsInFile(p,a,b,c,d) (p)->lpVtbl->EnumEffectsInFile(p,a,b,c,d)
+//#define IDirectInputDevice7_WriteEffectToFile(p,a,b,c,d) (p)->lpVtbl->WriteEffectToFile(p,a,b,c,d)
+//#else
+//#define IDirectInputDevice7_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+//#define IDirectInputDevice7_AddRef(p) (p)->AddRef()
+//#define IDirectInputDevice7_Release(p) (p)->Release()
+//#define IDirectInputDevice7_GetCapabilities(p,a) (p)->GetCapabilities(a)
+//#define IDirectInputDevice7_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c)
+//#define IDirectInputDevice7_GetProperty(p,a,b) (p)->GetProperty(a,b)
+//#define IDirectInputDevice7_SetProperty(p,a,b) (p)->SetProperty(a,b)
+//#define IDirectInputDevice7_Acquire(p) (p)->Acquire()
+//#define IDirectInputDevice7_Unacquire(p) (p)->Unacquire()
+//#define IDirectInputDevice7_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b)
+//#define IDirectInputDevice7_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d)
+//#define IDirectInputDevice7_SetDataFormat(p,a) (p)->SetDataFormat(a)
+//#define IDirectInputDevice7_SetEventNotification(p,a) (p)->SetEventNotification(a)
+//#define IDirectInputDevice7_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+//#define IDirectInputDevice7_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c)
+//#define IDirectInputDevice7_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a)
+//#define IDirectInputDevice7_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+//#define IDirectInputDevice7_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+//#define IDirectInputDevice7_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d)
+//#define IDirectInputDevice7_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c)
+//#define IDirectInputDevice7_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b)
+//#define IDirectInputDevice7_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a)
+//#define IDirectInputDevice7_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a)
+//#define IDirectInputDevice7_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c)
+//#define IDirectInputDevice7_Escape(p,a) (p)->Escape(a)
+//#define IDirectInputDevice7_Poll(p) (p)->Poll()
+//#define IDirectInputDevice7_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d)
+//#define IDirectInputDevice7_EnumEffectsInFile(p,a,b,c,d) (p)->EnumEffectsInFile(a,b,c,d)
+//#define IDirectInputDevice7_WriteEffectToFile(p,a,b,c,d) (p)->WriteEffectToFile(a,b,c,d)
+//#endif
+
+//#endif /* DIJ_RINGZERO */
+
+{$ENDIF} { DIRECTINPUT_VERSION >= $0700 }
+
+{$IF DIRECTINPUT_VERSION >= $0800}
+
+//#ifndef DIJ_RINGZERO
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInputDevice8W
+
+type
+  IDirectInputDevice8W = interface(IUnknown)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInputDevice8W methods ***)
+    function GetCapabilities(lpDIDevCaps: LPDIDEVCAPS): HRESULT; stdcall;
+    function EnumObjects(lpCallback: LPDIENUMDEVICEOBJECTSCALLBACKW; pvRef: LPVOID; dwFlags: DWORD): HRESULT; stdcall;
+    function GetProperty(const rguidProp: TGuid {REFGUID}; pdiph: LPDIPROPHEADER): HRESULT; stdcall;
+    function SetProperty(const rguidProp: TGuid {REFGUID}; pdiph: LPCDIPROPHEADER): HRESULT; stdcall;
+    function Acquire: HRESULT; stdcall;
+    function Unacquire: HRESULT; stdcall;
+    function GetDeviceState(cbData: DWORD; lpvData: LPVOID): HRESULT; stdcall;
+    function GetDeviceData(cbObjectData: DWORD; rgdod: LPDIDEVICEOBJECTDATA; pdwInOut: LPDWORD; dwFlags: DWORD): HRESULT; stdcall;
+    function SetDataFormat(lpdf: LPCDIDATAFORMAT): HRESULT; stdcall;
+    function SetEventNotification(hEvent: HANDLE): HRESULT; stdcall;
+    function SetCooperativeLevel(hwnd: HWND; dwFlags: DWORD): HRESULT; stdcall;
+    function GetObjectInfo(pdidoi: LPDIDEVICEOBJECTINSTANCEW; dwObj: DWORD; dwHow: DWORD): HRESULT; stdcall;
+    function GetDeviceInfo(pdidi: LPDIDEVICEINSTANCEW): HRESULT; stdcall;
+    function RunControlPanel(hwndOwner: HWND; dwFlags: DWORD): HRESULT; stdcall;
+    function Initialize(hinst: HINST; dwVersion: DWORD; const rguid: TGuid {REFGUID}): HRESULT; stdcall;
+    function CreateEffect(const rguid: TGuid {REFGUID}; lpeff: LPCDIEFFECT; out ppdeff: IDirectInputEffect {LPDIRECTINPUTEFFECT *}; punkOuter: {LPUNKNOWN}IUnknown): HRESULT; stdcall;
+    function EnumEffects(lpCallback: LPDIENUMEFFECTSCALLBACKW; pvRef: LPVOID; dwEffType: DWORD): HRESULT; stdcall;
+    function GetEffectInfo(pdei: LPDIEFFECTINFOW; const rguid: TGuid {REFGUID}): HRESULT; stdcall;
+    function GetForceFeedbackState(pdwOut: LPDWORD): HRESULT; stdcall;
+    function SendForceFeedbackCommand(dwFlags: DWORD): HRESULT; stdcall;
+    function EnumCreatedEffectObjects(lpCallback: LPDIENUMCREATEDEFFECTOBJECTSCALLBACK; pvRef: LPVOID; fl: DWORD): HRESULT; stdcall;
+    function Escape(pesc: LPDIEFFESCAPE): HRESULT; stdcall;
+    function Poll: HRESULT; stdcall;
+    function SendDeviceData(cbObjectData: DWORD; rgdod: LPCDIDEVICEOBJECTDATA; pdwInOut: LPDWORD; fl: DWORD): HRESULT; stdcall;
+    function EnumEffectsInFile(lpszFileName: LPCWSTR; pec: LPDIENUMEFFECTSINFILECALLBACK; pvRef: LPVOID; dwFlags: DWORD): HRESULT; stdcall;
+    function WriteEffectToFile(lpszFileName: LPCWSTR; dwEntries: DWORD; rgDiFileEft: LPDIFILEEFFECT; dwFlags: DWORD): HRESULT; stdcall;
+    function BuildActionMap(lpdiaf: LPDIACTIONFORMATW; lpszUserName: LPCWSTR; dwFlags: DWORD): HRESULT; stdcall;
+    function SetActionMap(lpdiActionFormat: LPDIACTIONFORMATW; lptszUserName: LPCWSTR; dwFlags: DWORD): HRESULT; stdcall;
+    function GetImageInfo(lpdiDevImageInfoHeader: LPDIDEVICEIMAGEINFOHEADERW): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInputDevice8W *LPDIRECTINPUTDEVICE8W;
+  LPDIRECTINPUTDEVICE8W = IDirectInputDevice8W;
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInputDevice8A
+
+  IDirectInputDevice8A = interface(IUnknown)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInputDevice8A methods ***)
+    function GetCapabilities(lpDIDevCaps: LPDIDEVCAPS): HRESULT; stdcall;
+    function EnumObjects(lpCallback: LPDIENUMDEVICEOBJECTSCALLBACKA; pvRef: LPVOID; dwFlags: DWORD): HRESULT; stdcall;
+    function GetProperty(const rguidProp: TGuid {REFGUID}; pdiph: LPDIPROPHEADER): HRESULT; stdcall;
+    function SetProperty(const rguidProp: TGuid {REFGUID}; pdiph: LPCDIPROPHEADER): HRESULT; stdcall;
+    function Acquire: HRESULT; stdcall;
+    function Unacquire: HRESULT; stdcall;
+    function GetDeviceState(cbData: DWORD; lpvData: LPVOID): HRESULT; stdcall;
+    function GetDeviceData(cbObjectData: DWORD; rgdod: LPDIDEVICEOBJECTDATA; pdwInOut: LPDWORD; dwFlags: DWORD): HRESULT; stdcall;
+    function SetDataFormat(lpdf: LPCDIDATAFORMAT): HRESULT; stdcall;
+    function SetEventNotification(hEvent: HANDLE): HRESULT; stdcall;
+    function SetCooperativeLevel(hwnd: HWND; dwFlags: DWORD): HRESULT; stdcall;
+    function GetObjectInfo(pdidoi: LPDIDEVICEOBJECTINSTANCEA; dwObj: DWORD; dwHow: DWORD): HRESULT; stdcall;
+    function GetDeviceInfo(pdidi: LPDIDEVICEINSTANCEA): HRESULT; stdcall;
+    function RunControlPanel(hwndOwner: HWND; dwFlags: DWORD): HRESULT; stdcall;
+    function Initialize(hinst: HINST; dwVersion: DWORD; const rguid: TGuid {REFGUID}): HRESULT; stdcall;
+    function CreateEffect(const rguid: TGuid {REFGUID}; lpeff: LPCDIEFFECT;  out ppdeff: IDirectInputEffect {LPDIRECTINPUTEFFECT *}; punkOuter: {LPUNKNOWN}IUnknown): HRESULT; stdcall;
+    function EnumEffects(lpCallback: LPDIENUMEFFECTSCALLBACKA; pvRef: LPVOID; dwEffType: DWORD): HRESULT; stdcall;
+    function GetEffectInfo(pdei: LPDIEFFECTINFOA; const rguid: TGuid {REFGUID}): HRESULT; stdcall;
+    function GetForceFeedbackState(pdwOut: LPDWORD): HRESULT; stdcall;
+    function SendForceFeedbackCommand(dwFlags: DWORD): HRESULT; stdcall;
+    function EnumCreatedEffectObjects(lpCallback: LPDIENUMCREATEDEFFECTOBJECTSCALLBACK; pvRef: LPVOID; fl: DWORD): HRESULT; stdcall;
+    function Escape(pesc: LPDIEFFESCAPE): HRESULT; stdcall;
+    function Poll: HRESULT; stdcall;
+    function SendDeviceData(cbObjectData: DWORD; rgdod: LPCDIDEVICEOBJECTDATA; pdwInOut: LPDWORD; fl: DWORD): HRESULT; stdcall;
+    function EnumEffectsInFile(lpszFileName: LPCSTR; pec: LPDIENUMEFFECTSINFILECALLBACK; pvRef: LPVOID; dwFlags: DWORD): HRESULT; stdcall;
+    function WriteEffectToFile(lpszFileName: LPCSTR; dwEntries: DWORD; rgDiFileEft: LPDIFILEEFFECT; dwFlags: DWORD): HRESULT; stdcall;
+    function BuildActionMap(lpdiaf: LPDIACTIONFORMATA; lpszUserName: LPCSTR; dwFlags: DWORD): HRESULT; stdcall;
+    function SetActionMap(lpdiActionFormat: LPDIACTIONFORMATA; lptszUserName: LPCSTR; dwFlags: DWORD): HRESULT; stdcall;
+    function GetImageInfo(lpdiDevImageInfoHeader: LPDIDEVICEIMAGEINFOHEADERA): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInputDevice8A *LPDIRECTINPUTDEVICE8A;
+  LPDIRECTINPUTDEVICE8A = IDirectInputDevice8A;
+
+{$IFDEF UNICODE}
+const
+  IID_IDirectInputDevice8: TIID = '{54D41081-DC15-4833-A41B-748F73A38179}'{IID_IDirectInputDevice8W};
+type
+  IDirectInputDevice8 = IDirectInputDevice8W;
+{$ELSE}
+const
+  IID_IDirectInputDevice8: TIID = '{54D41080-DC15-4833-A41B-748F73A38179}'{IID_IDirectInputDevice8A};
+type
+  IDirectInputDevice8 = IDirectInputDevice8A;
+{$ENDIF}
+//typedef struct IDirectInputDevice8 *LPDIRECTINPUTDEVICE8;
+  LPDIRECTINPUTDEVICE8 = IDirectInputDevice8;
+
+//#if !defined(__cplusplus) || defined(CINTERFACE)
+//#define IDirectInputDevice8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+//#define IDirectInputDevice8_AddRef(p) (p)->lpVtbl->AddRef(p)
+//#define IDirectInputDevice8_Release(p) (p)->lpVtbl->Release(p)
+//#define IDirectInputDevice8_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a)
+//#define IDirectInputDevice8_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c)
+//#define IDirectInputDevice8_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b)
+//#define IDirectInputDevice8_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b)
+//#define IDirectInputDevice8_Acquire(p) (p)->lpVtbl->Acquire(p)
+//#define IDirectInputDevice8_Unacquire(p) (p)->lpVtbl->Unacquire(p)
+//#define IDirectInputDevice8_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b)
+//#define IDirectInputDevice8_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d)
+//#define IDirectInputDevice8_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a)
+//#define IDirectInputDevice8_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a)
+//#define IDirectInputDevice8_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+//#define IDirectInputDevice8_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c)
+//#define IDirectInputDevice8_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a)
+//#define IDirectInputDevice8_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+//#define IDirectInputDevice8_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+//#define IDirectInputDevice8_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d)
+//#define IDirectInputDevice8_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c)
+//#define IDirectInputDevice8_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b)
+//#define IDirectInputDevice8_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a)
+//#define IDirectInputDevice8_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a)
+//#define IDirectInputDevice8_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c)
+//#define IDirectInputDevice8_Escape(p,a) (p)->lpVtbl->Escape(p,a)
+//#define IDirectInputDevice8_Poll(p) (p)->lpVtbl->Poll(p)
+//#define IDirectInputDevice8_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d)
+//#define IDirectInputDevice8_EnumEffectsInFile(p,a,b,c,d) (p)->lpVtbl->EnumEffectsInFile(p,a,b,c,d)
+//#define IDirectInputDevice8_WriteEffectToFile(p,a,b,c,d) (p)->lpVtbl->WriteEffectToFile(p,a,b,c,d)
+//#define IDirectInputDevice8_BuildActionMap(p,a,b,c) (p)->lpVtbl->BuildActionMap(p,a,b,c)
+//#define IDirectInputDevice8_SetActionMap(p,a,b,c) (p)->lpVtbl->SetActionMap(p,a,b,c)
+//#define IDirectInputDevice8_GetImageInfo(p,a) (p)->lpVtbl->GetImageInfo(p,a)
+//#else
+//#define IDirectInputDevice8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+//#define IDirectInputDevice8_AddRef(p) (p)->AddRef()
+//#define IDirectInputDevice8_Release(p) (p)->Release()
+//#define IDirectInputDevice8_GetCapabilities(p,a) (p)->GetCapabilities(a)
+//#define IDirectInputDevice8_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c)
+//#define IDirectInputDevice8_GetProperty(p,a,b) (p)->GetProperty(a,b)
+//#define IDirectInputDevice8_SetProperty(p,a,b) (p)->SetProperty(a,b)
+//#define IDirectInputDevice8_Acquire(p) (p)->Acquire()
+//#define IDirectInputDevice8_Unacquire(p) (p)->Unacquire()
+//#define IDirectInputDevice8_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b)
+//#define IDirectInputDevice8_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d)
+//#define IDirectInputDevice8_SetDataFormat(p,a) (p)->SetDataFormat(a)
+//#define IDirectInputDevice8_SetEventNotification(p,a) (p)->SetEventNotification(a)
+//#define IDirectInputDevice8_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+//#define IDirectInputDevice8_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c)
+//#define IDirectInputDevice8_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a)
+//#define IDirectInputDevice8_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+//#define IDirectInputDevice8_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+//#define IDirectInputDevice8_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d)
+//#define IDirectInputDevice8_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c)
+//#define IDirectInputDevice8_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b)
+//#define IDirectInputDevice8_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a)
+//#define IDirectInputDevice8_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a)
+//#define IDirectInputDevice8_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c)
+//#define IDirectInputDevice8_Escape(p,a) (p)->Escape(a)
+//#define IDirectInputDevice8_Poll(p) (p)->Poll()
+//#define IDirectInputDevice8_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d)
+//#define IDirectInputDevice8_EnumEffectsInFile(p,a,b,c,d) (p)->EnumEffectsInFile(a,b,c,d)
+//#define IDirectInputDevice8_WriteEffectToFile(p,a,b,c,d) (p)->WriteEffectToFile(a,b,c,d)
+//#define IDirectInputDevice8_BuildActionMap(p,a,b,c) (p)->BuildActionMap(a,b,c)
+//#define IDirectInputDevice8_SetActionMap(p,a,b,c) (p)->SetActionMap(a,b,c)
+//#define IDirectInputDevice8_GetImageInfo(p,a) (p)->GetImageInfo(a)
+//#endif
+
+//#endif /* DIJ_RINGZERO */
+
+{$ENDIF} { DIRECTINPUT_VERSION >= $0800 }
+
+(****************************************************************************
+ *
+ *      Mouse
+ *
+ ****************************************************************************)
+
+//#ifndef DIJ_RINGZERO
+
+type
+  LPDIMOUSESTATE = ^TDIMOUSESTATE;
+  PDIMOUSESTATE = ^TDIMOUSESTATE;
+  TDIMOUSESTATE = record
+    lX: LONG;
+    lY: LONG;
+    lZ: LONG;
+    rgbButtons: array [0..3] of BYTE;
+  end;
+
+{$IF DIRECTINPUT_VERSION >= $0700}
+  LPDIMOUSESTATE2 = ^TDIMOUSESTATE2;
+  PDIMOUSESTATE2 = ^TDIMOUSESTATE2;
+  TDIMOUSESTATE2 = record
+    lX: LONG;
+    lY: LONG;
+    lZ: LONG;
+    rgbButtons: array [0..7] of BYTE;
+  end;
+{$ENDIF}
+
+
+//const
+//  DIMOFS_X: LONG       =  Ofs(PDIMOUSESTATE(nil)^.lX); { FIELD_OFFSET(DIMOUSESTATE, lX)}
+{  DIMOFS_Y       =  FIELD_OFFSET(DIMOUSESTATE, lY);
+  DIMOFS_Z       =  FIELD_OFFSET(DIMOUSESTATE, lZ);
+  DIMOFS_BUTTON0 = (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 0);
+  DIMOFS_BUTTON1 = (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 1);
+  DIMOFS_BUTTON2 = (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 2);
+  DIMOFS_BUTTON3 = (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 3);}
+{$IF DIRECTINPUT_VERSION >= $0700}
+{  DIMOFS_BUTTON4 = (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 4);
+  DIMOFS_BUTTON5 = (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 5);
+  DIMOFS_BUTTON6 = (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 6);
+  DIMOFS_BUTTON7 = (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 7);}
+{$ENDIF}
+//#endif /* DIJ_RINGZERO */
+
+(****************************************************************************
+ *
+ *      Keyboard
+ *
+ ****************************************************************************)
+
+//#ifndef DIJ_RINGZERO
+
+(****************************************************************************
+ *
+ *      DirectInput keyboard scan codes
+ *
+ ****************************************************************************)
+//
+//    Copyright (C) Microsoft.  All rights reserved.
+//
+const
+  DIK_ESCAPE          = $01;
+  DIK_1               = $02;
+  DIK_2               = $03;
+  DIK_3               = $04;
+  DIK_4               = $05;
+  DIK_5               = $06;
+  DIK_6               = $07;
+  DIK_7               = $08;
+  DIK_8               = $09;
+  DIK_9               = $0A;
+  DIK_0               = $0B;
+  DIK_MINUS           = $0C;    { - on main keyboard }
+  DIK_EQUALS          = $0D;
+  DIK_BACK            = $0E;    { backspace }
+  DIK_TAB             = $0F;
+  DIK_Q               = $10;
+  DIK_W               = $11;
+  DIK_E               = $12;
+  DIK_R               = $13;
+  DIK_T               = $14;
+  DIK_Y               = $15;
+  DIK_U               = $16;
+  DIK_I               = $17;
+  DIK_O               = $18;
+  DIK_P               = $19;
+  DIK_LBRACKET        = $1A;
+  DIK_RBRACKET        = $1B;
+  DIK_RETURN          = $1C;    { Enter on main keyboard }
+  DIK_LCONTROL        = $1D;
+  DIK_A               = $1E;
+  DIK_S               = $1F;
+  DIK_D               = $20;
+  DIK_F               = $21;
+  DIK_G               = $22;
+  DIK_H               = $23;
+  DIK_J               = $24;
+  DIK_K               = $25;
+  DIK_L               = $26;
+  DIK_SEMICOLON       = $27;
+  DIK_APOSTROPHE      = $28;
+  DIK_GRAVE           = $29;    { accent grave }
+  DIK_LSHIFT          = $2A;
+  DIK_BACKSLASH       = $2B;
+  DIK_Z               = $2C;
+  DIK_X               = $2D;
+  DIK_C               = $2E;
+  DIK_V               = $2F;
+  DIK_B               = $30;
+  DIK_N               = $31;
+  DIK_M               = $32;
+  DIK_COMMA           = $33;
+  DIK_PERIOD          = $34;    { . on main keyboard }
+  DIK_SLASH           = $35;    { / on main keyboard }
+  DIK_RSHIFT          = $36;
+  DIK_MULTIPLY        = $37;    { * on numeric keypad }
+  DIK_LMENU           = $38;    { left Alt }
+  DIK_SPACE           = $39;
+  DIK_CAPITAL         = $3A;
+  DIK_F1              = $3B;
+  DIK_F2              = $3C;
+  DIK_F3              = $3D;
+  DIK_F4              = $3E;
+  DIK_F5              = $3F;
+  DIK_F6              = $40;
+  DIK_F7              = $41;
+  DIK_F8              = $42;
+  DIK_F9              = $43;
+  DIK_F10             = $44;
+  DIK_NUMLOCK         = $45;
+  DIK_SCROLL          = $46;    { Scroll Lock }
+  DIK_NUMPAD7         = $47;
+  DIK_NUMPAD8         = $48;
+  DIK_NUMPAD9         = $49;
+  DIK_SUBTRACT        = $4A;    { - on numeric keypad }
+  DIK_NUMPAD4         = $4B;
+  DIK_NUMPAD5         = $4C;
+  DIK_NUMPAD6         = $4D;
+  DIK_ADD             = $4E;    { + on numeric keypad }
+  DIK_NUMPAD1         = $4F;
+  DIK_NUMPAD2         = $50;
+  DIK_NUMPAD3         = $51;
+  DIK_NUMPAD0         = $52;
+  DIK_DECIMAL         = $53;    { . on numeric keypad }
+  DIK_OEM_102         = $56;    { <> or \| on RT 102-key keyboard (Non-U.S.) }
+  DIK_F11             = $57;
+  DIK_F12             = $58;
+  DIK_F13             = $64;    {                     (NEC PC98) }
+  DIK_F14             = $65;    {                     (NEC PC98) }
+  DIK_F15             = $66;    {                     (NEC PC98) }
+  DIK_KANA            = $70;    { (Japanese keyboard)            }
+  DIK_ABNT_C1         = $73;    { /? on Brazilian keyboard }
+  DIK_CONVERT         = $79;    { (Japanese keyboard)            }
+  DIK_NOCONVERT       = $7B;    { (Japanese keyboard)            }
+  DIK_YEN             = $7D;    { (Japanese keyboard)            }
+  DIK_ABNT_C2         = $7E;    { Numpad . on Brazilian keyboard }
+  DIK_NUMPADEQUALS    = $8D;    { = on numeric keypad (NEC PC98) }
+  DIK_PREVTRACK       = $90;    { Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) }
+  DIK_AT              = $91;    {                     (NEC PC98) }
+  DIK_COLON           = $92;    {                     (NEC PC98) }
+  DIK_UNDERLINE       = $93;    {                     (NEC PC98) }
+  DIK_KANJI           = $94;    { (Japanese keyboard)            }
+  DIK_STOP            = $95;    {                     (NEC PC98) }
+  DIK_AX              = $96;    {                     (Japan AX) }
+  DIK_UNLABELED       = $97;    {                        (J3100) }
+  DIK_NEXTTRACK       = $99;    { Next Track }
+  DIK_NUMPADENTER     = $9C;    { Enter on numeric keypad }
+  DIK_RCONTROL        = $9D;
+  DIK_MUTE            = $A0;    { Mute }
+  DIK_CALCULATOR      = $A1;    { Calculator }
+  DIK_PLAYPAUSE       = $A2;    { Play / Pause }
+  DIK_MEDIASTOP       = $A4;    { Media Stop }
+  DIK_VOLUMEDOWN      = $AE;    { Volume - }
+  DIK_VOLUMEUP        = $B0;    { Volume + }
+  DIK_WEBHOME         = $B2;    { Web home }
+  DIK_NUMPADCOMMA     = $B3;    { , on numeric keypad (NEC PC98) }
+  DIK_DIVIDE          = $B5;    { / on numeric keypad }
+  DIK_SYSRQ           = $B7;
+  DIK_RMENU           = $B8;    { right Alt }
+  DIK_PAUSE           = $C5;    { Pause }
+  DIK_HOME            = $C7;    { Home on arrow keypad }
+  DIK_UP              = $C8;    { UpArrow on arrow keypad }
+  DIK_PRIOR           = $C9;    { PgUp on arrow keypad }
+  DIK_LEFT            = $CB;    { LeftArrow on arrow keypad }
+  DIK_RIGHT           = $CD;    { RightArrow on arrow keypad }
+  DIK_END             = $CF;    { End on arrow keypad }
+  DIK_DOWN            = $D0;    { DownArrow on arrow keypad }
+  DIK_NEXT            = $D1;    { PgDn on arrow keypad }
+  DIK_INSERT          = $D2;    { Insert on arrow keypad }
+  DIK_DELETE          = $D3;    { Delete on arrow keypad }
+  DIK_LWIN            = $DB;    { Left Windows key }
+  DIK_RWIN            = $DC;    { Right Windows key }
+  DIK_APPS            = $DD;    { AppMenu key }
+  DIK_POWER           = $DE;    { System Power }
+  DIK_SLEEP           = $DF;    { System Sleep }
+  DIK_WAKE            = $E3;    { System Wake }
+  DIK_WEBSEARCH       = $E5;    { Web Search }
+  DIK_WEBFAVORITES    = $E6;    { Web Favorites }
+  DIK_WEBREFRESH      = $E7;    { Web Refresh }
+  DIK_WEBSTOP         = $E8;    { Web Stop }
+  DIK_WEBFORWARD      = $E9;    { Web Forward }
+  DIK_WEBBACK         = $EA;    { Web Back }
+  DIK_MYCOMPUTER      = $EB;    { My Computer }
+  DIK_MAIL            = $EC;    { Mail }
+  DIK_MEDIASELECT     = $ED;    { Media Select }
+
+(*
+ *  Alternate names for keys, to facilitate transition from DOS.
+ *)
+  DIK_BACKSPACE       = DIK_BACK;            { backspace }
+  DIK_NUMPADSTAR      = DIK_MULTIPLY;        { * on numeric keypad }
+  DIK_LALT            = DIK_LMENU;           { left Alt }
+  DIK_CAPSLOCK        = DIK_CAPITAL;         { CapsLock }
+  DIK_NUMPADMINUS     = DIK_SUBTRACT;        { - on numeric keypad }
+  DIK_NUMPADPLUS      = DIK_ADD;             { + on numeric keypad }
+  DIK_NUMPADPERIOD    = DIK_DECIMAL;         { . on numeric keypad }
+  DIK_NUMPADSLASH     = DIK_DIVIDE;          { / on numeric keypad }
+  DIK_RALT            = DIK_RMENU;           { right Alt }
+  DIK_UPARROW         = DIK_UP;              { UpArrow on arrow keypad }
+  DIK_PGUP            = DIK_PRIOR;           { PgUp on arrow keypad }
+  DIK_LEFTARROW       = DIK_LEFT;            { LeftArrow on arrow keypad }
+  DIK_RIGHTARROW      = DIK_RIGHT;           { RightArrow on arrow keypad }
+  DIK_DOWNARROW       = DIK_DOWN;            { DownArrow on arrow keypad }
+  DIK_PGDN            = DIK_NEXT;            { PgDn on arrow keypad }
+
+(*
+ *  Alternate names for keys originally not used on US keyboards.
+ *)
+  DIK_CIRCUMFLEX      = DIK_PREVTRACK;       { Japanese keyboard }
+
+//#endif /* DIJ_RINGZERO */
+
+(****************************************************************************
+ *
+ *      Joystick
+ *
+ ****************************************************************************)
+
+//#ifndef DIJ_RINGZERO
+
+type
+  LPDIJOYSTATE = ^TDIJOYSTATE;
+  PDIJOYSTATE = ^TDIJOYSTATE;
+  TDIJOYSTATE = record
+    lX: LONG;                            { x-axis position              }
+    lY: LONG;                            { y-axis position              }
+    lZ: LONG;                            { z-axis position              }
+    lRx: LONG;                           { x-axis rotation              }
+    lRy: LONG;                           { y-axis rotation              }
+    lRz: LONG;                           { z-axis rotation              }
+    rglSlider: array [0..1] of LONG;     { extra axes positions         }
+    rgdwPOV: array [0..3] of DWORD;      { POV directions               }
+    rgbButtons: array [0..31] of BYTE;   { 32 buttons                   }
+  end;
+
+  LPDIJOYSTATE2 = ^TDIJOYSTATE2;
+  PDIJOYSTATE2 = ^TDIJOYSTATE2;
+  TDIJOYSTATE2 = record
+    lX: LONG;                            { x-axis position              }
+    lY: LONG;                            { y-axis position              }
+    lZ: LONG;                            { z-axis position              }
+    lRx: LONG;                           { x-axis rotation              }
+    lRy: LONG;                           { y-axis rotation              }
+    lRz: LONG;                           { z-axis rotation              }
+    rglSlider: array [0..1] of LONG;     { extra axes positions         }
+    rgdwPOV: array [0..3] of DWORD;      { POV directions               }
+    rgbButtons: array [0..127] of BYTE;  { 128 buttons                  }
+    lVX: LONG;                           { x-axis velocity              }
+    lVY: LONG;                           { y-axis velocity              }
+    lVZ: LONG;                           { z-axis velocity              }
+    lVRx: LONG;                          { x-axis angular velocity      }
+    lVRy: LONG;                          { y-axis angular velocity      }
+    lVRz: LONG;                          { z-axis angular velocity      }
+    rglVSlider: array [0..1] of LONG;    { extra axes velocities        }
+    lAX: LONG;                           { x-axis acceleration          }
+    lAY: LONG;                           { y-axis acceleration          }
+    lAZ: LONG;                           { z-axis acceleration          }
+    lARx: LONG;                          { x-axis angular acceleration  }
+    lARy: LONG;                          { y-axis angular acceleration  }
+    lARz: LONG;                          { z-axis angular acceleration  }
+    rglASlider: array [0..1] of LONG;    { extra axes accelerations     }
+    lFX: LONG;                           { x-axis force                 }
+    lFY: LONG;                           { y-axis force                 }
+    lFZ: LONG;                           { z-axis force                 }
+    lFRx: LONG;                          { x-axis torque                }
+    lFRy: LONG;                          { y-axis torque                }
+    lFRz: LONG;                          { z-axis torque                }
+    rglFSlider: array [0..1] of LONG;    { extra axes forces            }
+  end;
+
+(*#define DIJOFS_X            FIELD_OFFSET(DIJOYSTATE, lX)
+#define DIJOFS_Y            FIELD_OFFSET(DIJOYSTATE, lY)
+#define DIJOFS_Z            FIELD_OFFSET(DIJOYSTATE, lZ)
+#define DIJOFS_RX           FIELD_OFFSET(DIJOYSTATE, lRx)
+#define DIJOFS_RY           FIELD_OFFSET(DIJOYSTATE, lRy)
+#define DIJOFS_RZ           FIELD_OFFSET(DIJOYSTATE, lRz)
+#define DIJOFS_SLIDER(n)   (FIELD_OFFSET(DIJOYSTATE, rglSlider) + \
+                                                        (n) * sizeof(LONG))
+#define DIJOFS_POV(n)      (FIELD_OFFSET(DIJOYSTATE, rgdwPOV) + \
+                                                        (n) * sizeof(DWORD))
+#define DIJOFS_BUTTON(n)   (FIELD_OFFSET(DIJOYSTATE, rgbButtons) + (n))
+#define DIJOFS_BUTTON0      DIJOFS_BUTTON(0)
+#define DIJOFS_BUTTON1      DIJOFS_BUTTON(1)
+#define DIJOFS_BUTTON2      DIJOFS_BUTTON(2)
+#define DIJOFS_BUTTON3      DIJOFS_BUTTON(3)
+#define DIJOFS_BUTTON4      DIJOFS_BUTTON(4)
+#define DIJOFS_BUTTON5      DIJOFS_BUTTON(5)
+#define DIJOFS_BUTTON6      DIJOFS_BUTTON(6)
+#define DIJOFS_BUTTON7      DIJOFS_BUTTON(7)
+#define DIJOFS_BUTTON8      DIJOFS_BUTTON(8)
+#define DIJOFS_BUTTON9      DIJOFS_BUTTON(9)
+#define DIJOFS_BUTTON10     DIJOFS_BUTTON(10)
+#define DIJOFS_BUTTON11     DIJOFS_BUTTON(11)
+#define DIJOFS_BUTTON12     DIJOFS_BUTTON(12)
+#define DIJOFS_BUTTON13     DIJOFS_BUTTON(13)
+#define DIJOFS_BUTTON14     DIJOFS_BUTTON(14)
+#define DIJOFS_BUTTON15     DIJOFS_BUTTON(15)
+#define DIJOFS_BUTTON16     DIJOFS_BUTTON(16)
+#define DIJOFS_BUTTON17     DIJOFS_BUTTON(17)
+#define DIJOFS_BUTTON18     DIJOFS_BUTTON(18)
+#define DIJOFS_BUTTON19     DIJOFS_BUTTON(19)
+#define DIJOFS_BUTTON20     DIJOFS_BUTTON(20)
+#define DIJOFS_BUTTON21     DIJOFS_BUTTON(21)
+#define DIJOFS_BUTTON22     DIJOFS_BUTTON(22)
+#define DIJOFS_BUTTON23     DIJOFS_BUTTON(23)
+#define DIJOFS_BUTTON24     DIJOFS_BUTTON(24)
+#define DIJOFS_BUTTON25     DIJOFS_BUTTON(25)
+#define DIJOFS_BUTTON26     DIJOFS_BUTTON(26)
+#define DIJOFS_BUTTON27     DIJOFS_BUTTON(27)
+#define DIJOFS_BUTTON28     DIJOFS_BUTTON(28)
+#define DIJOFS_BUTTON29     DIJOFS_BUTTON(29)
+#define DIJOFS_BUTTON30     DIJOFS_BUTTON(30)
+#define DIJOFS_BUTTON31     DIJOFS_BUTTON(31)*)
+
+
+//#endif /* DIJ_RINGZERO */
+
+(****************************************************************************
+ *
+ *  IDirectInput
+ *
+ ****************************************************************************)
+
+//#ifndef DIJ_RINGZERO
+
+const
+  DIENUM_STOP           = 0;
+  DIENUM_CONTINUE       = 1;
+
+type
+  LPDIENUMDEVICESCALLBACKA = function(lpddi: LPCDIDEVICEINSTANCEA; pvRef: LPVOID): BOOL; stdcall;
+  LPDIENUMDEVICESCALLBACKW = function(lpddi: LPCDIDEVICEINSTANCEW; pvRef: LPVOID): BOOL; stdcall;
+{$IFDEF UNICODE}
+  LPDIENUMDEVICESCALLBACK = LPDIENUMDEVICESCALLBACKW;
+{$ELSE}
+  LPDIENUMDEVICESCALLBACK = LPDIENUMDEVICESCALLBACKA;
+{$ENDIF} // !UNICODE
+  LPDICONFIGUREDEVICESCALLBACK = function(lpDDSTarget: {IUnknown FAR *}IUnknown; pvRef: LPVOID): BOOL; stdcall;
+
+const
+  DIEDFL_ALLDEVICES      = $00000000;
+  DIEDFL_ATTACHEDONLY    = $00000001;
+{$IF DIRECTINPUT_VERSION >= $0500}
+  DIEDFL_FORCEFEEDBACK   = $00000100;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0500 }
+{$IF DIRECTINPUT_VERSION >= $050a}
+  DIEDFL_INCLUDEALIASES  = $00010000;
+  DIEDFL_INCLUDEPHANTOMS = $00020000;
+{$ENDIF} { DIRECTINPUT_VERSION >= $050a }
+{$IF DIRECTINPUT_VERSION >= $0800}
+  DIEDFL_INCLUDEHIDDEN   = $00040000;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0800 }
+
+
+{$IF DIRECTINPUT_VERSION >= $0800}
+type
+  LPDIENUMDEVICESBYSEMANTICSCBA = function(lpddi: LPCDIDEVICEINSTANCEA; lpdid: LPDIRECTINPUTDEVICE8A; dwFlags: DWORD; dwRemaining: DWORD; pvRef: LPVOID): BOOL; stdcall;
+  LPDIENUMDEVICESBYSEMANTICSCBW = function(lpddi: LPCDIDEVICEINSTANCEW; lpdid: LPDIRECTINPUTDEVICE8W; dwFlags: DWORD; dwRemaining: DWORD; pvRef: LPVOID): BOOL; stdcall;
+{$IFDEF UNICODE}
+  LPDIENUMDEVICESBYSEMANTICSCB = LPDIENUMDEVICESBYSEMANTICSCBW;
+{$ELSE}
+  LPDIENUMDEVICESBYSEMANTICSCB = LPDIENUMDEVICESBYSEMANTICSCBA;
+{$ENDIF} // !UNICODE
+{$ENDIF} { DIRECTINPUT_VERSION >= $0800 }
+
+{$IF DIRECTINPUT_VERSION >= $0800}
+const
+  DIEDBS_MAPPEDPRI1        = $00000001;
+  DIEDBS_MAPPEDPRI2        = $00000002;
+  DIEDBS_RECENTDEVICE      = $00000010;
+  DIEDBS_NEWDEVICE         = $00000020;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0800 }
+
+{$IF DIRECTINPUT_VERSION >= $0800}
+const
+  DIEDBSFL_ATTACHEDONLY       = $00000000;
+  DIEDBSFL_THISUSER           = $00000010;
+  DIEDBSFL_FORCEFEEDBACK      = DIEDFL_FORCEFEEDBACK;
+  DIEDBSFL_AVAILABLEDEVICES   = $00001000;
+  DIEDBSFL_MULTIMICEKEYBOARDS = $00002000;
+  DIEDBSFL_NONGAMINGDEVICES   = $00004000;
+  DIEDBSFL_VALID              = $00007110;
+{$ENDIF} { DIRECTINPUT_VERSION >= $0800 }
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInputW
+
+type
+  IDirectInputW = interface(IUnknown)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInputW methods ***)
+    function CreateDevice(const rguid: TGuid; out lplpDirectInputDevice: IDirectInputDeviceW; pUnkOuter: IUnknown): HRESULT; stdcall;
+    function EnumDevices(dwDevType: DWORD; lpCallback: LPDIENUMDEVICESCALLBACKW; pvRef: LPVOID; dwFlags: DWORD): HRESULT; stdcall;
+    function GetDeviceStatus(const rguidInstance: TGuid): HRESULT; stdcall;
+    function RunControlPanel(hwndOwner: HWND; dwFlags: DWORD): HRESULT; stdcall;
+    function Initialize(hinst: HINST; dwVersion: DWORD): HRESULT; stdcall;
+  end;
+
+//  typedef struct IDirectInputW *LPDIRECTINPUTW;
+  LPDIRECTINPUTW = IDirectInputW;
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInputA
+
+  IDirectInputA = interface(IUnknown)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInputA methods ***)
+    function CreateDevice(const rguid: TGuid; out lplpDirectInputDevice: IDirectInputDeviceA; pUnkOuter: IUnknown): HRESULT; stdcall;
+    function EnumDevices(dwDevType: DWORD; lpCallback: LPDIENUMDEVICESCALLBACKA; pvRef: LPVOID; dwFlags: DWORD): HRESULT; stdcall;
+    function GetDeviceStatus(const rguidInstance: TGuid): HRESULT; stdcall;
+    function RunControlPanel(hwndOwner: HWND; dwFlags: DWORD): HRESULT; stdcall;
+    function Initialize(hinst: HINST; dwVersion: DWORD): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInputA *LPDIRECTINPUTA;
+  LPDIRECTINPUTA = IDirectInputA;
+
+{$IFDEF UNICODE}
+const
+  IID_IDirectInput: TIID = {IID_IDirectInputW}'{89521361-AA8A-11CF-BFC7-444553540000}';
+type
+  IDirectInput = IDirectInputW;
+{$ELSE}
+const
+  IID_IDirectInput: TIID = {IID_IDirectInputA}'{89521360-AA8A-11CF-BFC7-444553540000}';
+type
+  IDirectInput = IDirectInputA;
+{$ENDIF}
+//typedef struct IDirectInput *LPDIRECTINPUT;
+  LPDIRECTINPUT = IDirectInput;
+
+//#if !defined(__cplusplus) || defined(CINTERFACE)
+//#define IDirectInput_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+//#define IDirectInput_AddRef(p) (p)->lpVtbl->AddRef(p)
+//#define IDirectInput_Release(p) (p)->lpVtbl->Release(p)
+//#define IDirectInput_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
+//#define IDirectInput_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d)
+//#define IDirectInput_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a)
+//#define IDirectInput_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+//#define IDirectInput_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+//#else
+//#define IDirectInput_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+//#define IDirectInput_AddRef(p) (p)->AddRef()
+//#define IDirectInput_Release(p) (p)->Release()
+//#define IDirectInput_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
+//#define IDirectInput_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d)
+//#define IDirectInput_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a)
+//#define IDirectInput_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+//#define IDirectInput_Initialize(p,a,b) (p)->Initialize(a,b)
+//#endif
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInput2W
+
+type
+  IDirectInput2W = interface(IDirectInputW)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInputW methods ***)
+    {STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICEW *,LPUNKNOWN) PURE;
+    STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACKW,LPVOID,DWORD) PURE;
+    STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE;
+    STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE;
+    STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD) PURE;}
+
+    (*** IDirectInput2W methods ***)
+    function FindDevice(const rguidClass: TGuid; ptszName: LPCWSTR; pguidInstance: LPGUID): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInput2W *LPDIRECTINPUT2W;
+  LPDIRECTINPUT2W = IDirectInput2W;
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInput2A
+
+  IDirectInput2A = interface(IDirectInputA)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInputA methods ***)
+    {STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICEA *,LPUNKNOWN) PURE;
+    STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACKA,LPVOID,DWORD) PURE;
+    STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE;
+    STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE;
+    STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD) PURE;}
+
+    (*** IDirectInput2A methods ***)
+    function FindDevice(const rguidClass: TGuid; ptszName: LPCSTR; pguidInstance: LPGUID): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInput2A *LPDIRECTINPUT2A;
+  LPDIRECTINPUT2A = IDirectInput2A;
+
+{$IFDEF UNICODE}
+const
+  IID_IDirectInput2: TIID = {IID_IDirectInput2W}'{5944E663-AA8A-11CF-BFC7-444553540000}';
+type
+  IDirectInput2 = IDirectInput2W;
+{$ELSE}
+const
+  IID_IDirectInput2: TIID = {IID_IDirectInput2A}'{5944E662-AA8A-11CF-BFC7-444553540000}';
+type
+  IDirectInput2 = IDirectInput2A;
+{$ENDIF}
+//typedef struct IDirectInput2 *LPDIRECTINPUT2;
+  LPDIRECTINPUT2 = IDirectInput2;
+
+//#if !defined(__cplusplus) || defined(CINTERFACE)
+//#define IDirectInput2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+//#define IDirectInput2_AddRef(p) (p)->lpVtbl->AddRef(p)
+//#define IDirectInput2_Release(p) (p)->lpVtbl->Release(p)
+//#define IDirectInput2_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
+//#define IDirectInput2_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d)
+//#define IDirectInput2_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a)
+//#define IDirectInput2_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+//#define IDirectInput2_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+//#define IDirectInput2_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c)
+//#else
+//#define IDirectInput2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+//#define IDirectInput2_AddRef(p) (p)->AddRef()
+//#define IDirectInput2_Release(p) (p)->Release()
+//#define IDirectInput2_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
+//#define IDirectInput2_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d)
+//#define IDirectInput2_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a)
+//#define IDirectInput2_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+//#define IDirectInput2_Initialize(p,a,b) (p)->Initialize(a,b)
+//#define IDirectInput2_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c)
+//#endif
+
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInput7W
+
+type
+  IDirectInput7W = interface(IDirectInput2W)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInput2W methods ***)
+    {STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICEW *,LPUNKNOWN) PURE;
+    STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACKW,LPVOID,DWORD) PURE;
+    STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE;
+    STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE;
+    STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD) PURE;
+    STDMETHOD(FindDevice)(THIS_ REFGUID,LPCWSTR,LPGUID) PURE;}
+
+    (*** IDirectInput7W methods ***)
+    function CreateDeviceEx(const rguid: TGuid; const riid: TIID; out pvOut: LPVOID; pUnkOuter: IUnknown): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInput7W *LPDIRECTINPUT7W;
+  LPDIRECTINPUT7W = IDirectInput7W;
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInput7A
+
+  IDirectInput7A = interface(IDirectInput2A)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInput2A methods ***)
+    {STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICEA *,LPUNKNOWN) PURE;
+    STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACKA,LPVOID,DWORD) PURE;
+    STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE;
+    STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE;
+    STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD) PURE;
+    STDMETHOD(FindDevice)(THIS_ REFGUID,LPCSTR,LPGUID) PURE;}
+
+    (*** IDirectInput7A methods ***)
+    function CreateDeviceEx(const rguid: TGuid; const riid: TIID; out pvOut: LPVOID; pUnkOuter: IUnknown): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInput7A *LPDIRECTINPUT7A;
+  LPDIRECTINPUT7A = IDirectInput7A;
+
+{$IFDEF UNICODE}
+const
+  IID_IDirectInput7: TIID = {IID_IDirectInput7W}'{9A4CB685-236D-11D3-8E9D-00C04F6844AE}';
+type
+  IDirectInput7 = IDirectInput7W;
+{$ELSE}
+const
+  IID_IDirectInput7: TIID = {IID_IDirectInput7A}'{9A4CB684-236D-11D3-8E9D-00C04F6844AE}';
+type
+  IDirectInput7 = IDirectInput7A;
+{$ENDIF}
+//typedef struct IDirectInput7 *LPDIRECTINPUT7;
+  LPDIRECTINPUT7 = IDirectInput7;
+
+//#if !defined(__cplusplus) || defined(CINTERFACE)
+//#define IDirectInput7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+//#define IDirectInput7_AddRef(p) (p)->lpVtbl->AddRef(p)
+//#define IDirectInput7_Release(p) (p)->lpVtbl->Release(p)
+//#define IDirectInput7_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
+//#define IDirectInput7_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d)
+//#define IDirectInput7_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a)
+//#define IDirectInput7_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+//#define IDirectInput7_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+//#define IDirectInput7_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c)
+//#define IDirectInput7_CreateDeviceEx(p,a,b,c,d) (p)->lpVtbl->CreateDeviceEx(p,a,b,c,d)
+//#else
+//#define IDirectInput7_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+//#define IDirectInput7_AddRef(p) (p)->AddRef()
+//#define IDirectInput7_Release(p) (p)->Release()
+//#define IDirectInput7_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
+//#define IDirectInput7_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d)
+//#define IDirectInput7_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a)
+//#define IDirectInput7_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+//#define IDirectInput7_Initialize(p,a,b) (p)->Initialize(a,b)
+//#define IDirectInput7_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c)
+//#define IDirectInput7_CreateDeviceEx(p,a,b,c,d) (p)->CreateDeviceEx(a,b,c,d)
+//#endif
+
+{$IF DIRECTINPUT_VERSION >= $0800}
+//#undef INTERFACE
+//#define INTERFACE IDirectInput8W
+
+type
+  IDirectInput8W = interface(IUnknown)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInput8W methods ***)
+    function CreateDevice(const rguid: TGuid; out lplpDirectInputDevice: IDirectInputDevice8W; pUnkOuter: IUnknown): HRESULT; stdcall;
+    function EnumDevices(dwDevType: DWORD; lpCallback: LPDIENUMDEVICESCALLBACKW; pvRef: LPVOID; dwFlags: DWORD): HRESULT; stdcall;
+    function GetDeviceStatus(const rguidInstance: TGuid): HRESULT; stdcall;
+    function RunControlPanel(hwndOwner: HWND; dwFlags: DWORD): HRESULT; stdcall;
+    function Initialize(hinst: HINST; dwVersion: DWORD): HRESULT; stdcall;
+    function FindDevice(const rguidClass: TGuid; ptszName: LPCWSTR; pguidInstance: LPGUID): HRESULT; stdcall;
+    function EnumDevicesBySemantics(ptszUserName: LPCWSTR; lpdiActionFormat: LPDIACTIONFORMATW; lpCallback: LPDIENUMDEVICESBYSEMANTICSCBW; pvRef: LPVOID; dwFlags: DWORD): HRESULT; stdcall;
+    function ConfigureDevices(lpdiCallback: LPDICONFIGUREDEVICESCALLBACK; lpdiCDParams: LPDICONFIGUREDEVICESPARAMSW; dwFlags: DWORD; pvRefData: LPVOID): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInput8W *LPDIRECTINPUT8W;
+  LPDIRECTINPUT8W = IDirectInput8W;
+
+//#undef INTERFACE
+//#define INTERFACE IDirectInput8A
+
+  IDirectInput8A = interface(IUnknown)
+    (*** IUnknown methods ***)
+    {STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;}
+
+    (*** IDirectInput8A methods ***)
+    function CreateDevice(const rguid: TGuid; out lplpDirectInputDevice: IDirectInputDevice8A; pUnkOuter: IUnknown): HRESULT; stdcall;
+    function EnumDevices(dwDevType: DWORD; lpCallback: LPDIENUMDEVICESCALLBACKA; pvRef: LPVOID; dwFlags: DWORD): HRESULT; stdcall;
+    function GetDeviceStatus(const rguidInstance: TGuid): HRESULT; stdcall;
+    function RunControlPanel(hwndOwner: HWND; dwFlags: DWORD): HRESULT; stdcall;
+    function Initialize(hinst: HINST; dwVersion: DWORD): HRESULT; stdcall;
+    function FindDevice(const rguidClass: TGuid; ptszName: LPCSTR; pguidInstance: LPGUID): HRESULT; stdcall;
+    function EnumDevicesBySemantics(ptszUserName: LPCSTR; lpdiActionFormat: LPDIACTIONFORMATA; lpCallback: LPDIENUMDEVICESBYSEMANTICSCBA; pvRef: LPVOID; dwFlags: DWORD): HRESULT; stdcall;
+    function ConfigureDevices(lpdiCallback: LPDICONFIGUREDEVICESCALLBACK; lpdiCDParams: LPDICONFIGUREDEVICESPARAMSA; dwFlags: DWORD; pvRefData: LPVOID): HRESULT; stdcall;
+  end;
+
+//typedef struct IDirectInput8A *LPDIRECTINPUT8A;
+  LPDIRECTINPUT8A = IDirectInput8A;
+
+{$IFDEF UNICODE}
+const
+  IID_IDirectInput8: TIID = {IID_IDirectInput8W}'{BF798031-483A-4DA2-AA99-5D64ED369700}';
+type
+  IDirectInput8 = IDirectInput8W;
+{$ELSE}
+const
+  IID_IDirectInput8: TIID = {IID_IDirectInput8A}'{BF798030-483A-4DA2-AA99-5D64ED369700}';
+type
+  IDirectInput8 = IDirectInput8A;
+{$ENDIF}
+//typedef struct IDirectInput8 *LPDIRECTINPUT8;
+  LPDIRECTINPUT8 = IDirectInput8;
+
+//#if !defined(__cplusplus) || defined(CINTERFACE)
+//#define IDirectInput8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+//#define IDirectInput8_AddRef(p) (p)->lpVtbl->AddRef(p)
+//#define IDirectInput8_Release(p) (p)->lpVtbl->Release(p)
+//#define IDirectInput8_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
+//#define IDirectInput8_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d)
+//#define IDirectInput8_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a)
+//#define IDirectInput8_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+//#define IDirectInput8_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+//#define IDirectInput8_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c)
+//#define IDirectInput8_EnumDevicesBySemantics(p,a,b,c,d,e) (p)->lpVtbl->EnumDevicesBySemantics(p,a,b,c,d,e)
+//#define IDirectInput8_ConfigureDevices(p,a,b,c,d) (p)->lpVtbl->ConfigureDevices(p,a,b,c,d)
+//#else
+//#define IDirectInput8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+//#define IDirectInput8_AddRef(p) (p)->AddRef()
+//#define IDirectInput8_Release(p) (p)->Release()
+//#define IDirectInput8_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
+//#define IDirectInput8_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d)
+//#define IDirectInput8_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a)
+//#define IDirectInput8_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+//#define IDirectInput8_Initialize(p,a,b) (p)->Initialize(a,b)
+//#define IDirectInput8_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c)
+//#define IDirectInput8_EnumDevicesBySemantics(p,a,b,c,d,e) (p)->EnumDevicesBySemantics(a,b,c,d,e)
+//#define IDirectInput8_ConfigureDevices(p,a,b,c,d) (p)->ConfigureDevices(a,b,c,d)
+//#endif
+{$ENDIF} { DIRECTINPUT_VERSION >= $0800 }
+
+{$IF DIRECTINPUT_VERSION > $0700}
+
+//extern HRESULT WINAPI DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter);
+function DirectInput8Create(hinst: HINST; dwVersion: DWORD; const riidltf: TIID; out ppvOut: LPVOID; punkOuter: IUnknown): HRESULT; stdcall; external 'dinput8';
+
+{$ELSE}
+//extern HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter);
+function DirectInputCreateA(hinst: HINST; dwVersion: DWORD; out ppDI: IDirectInputA; punkOuter: IUnknown): HRESULT; stdcall; external 'dinput';
+//extern HRESULT WINAPI DirectInputCreateW(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTW *ppDI, LPUNKNOWN punkOuter);
+function DirectInputCreateW(hinst: HINST; dwVersion: DWORD; out ppDI: IDirectInputW; punkOuter: IUnknown): HRESULT; stdcall; external 'dinput';
+{$IFDEF UNICODE}
+function DirectInputCreate(hinst: HINST; dwVersion: DWORD; out ppDI: IDirectInputW; punkOuter: IUnknown): HRESULT; stdcall; external 'dinput' name 'DirectInputCreateW';
+{$ELSE}
+function DirectInputCreate(hinst: HINST; dwVersion: DWORD; out ppDI: IDirectInputA; punkOuter: IUnknown): HRESULT; stdcall; external 'dinput' name 'DirectInputCreateA';
+{$ENDIF} // !UNICODE
+
+//extern HRESULT WINAPI DirectInputCreateEx(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter);
+function DirectInputCreateEx(hinst: HINST; dwVersion: DWORD; const riidltf: TIID; out ppvOut: LPVOID; punkOuter: IUnknown): HRESULT; stdcall; external 'dinput';
+
+{$ENDIF} { DIRECTINPUT_VERSION > $700 }
+
+//#endif /* DIJ_RINGZERO */
+
+
+(****************************************************************************
+ *
+ *  Return Codes
+ *
+ ****************************************************************************)
+
+(*
+ *  The operation completed successfully.
+ *)
+const
+  DI_OK                           = S_OK;
+
+(*
+ *  The device exists but is not currently attached.
+ *)
+  DI_NOTATTACHED                  = S_FALSE;
+
+(*
+ *  The device buffer overflowed.  Some input was lost.
+ *)
+  DI_BUFFEROVERFLOW               = S_FALSE;
+
+(*
+ *  The change in device properties had no effect.
+ *)
+  DI_PROPNOEFFECT                 = S_FALSE;
+
+(*
+ *  The operation had no effect.
+ *)
+  DI_NOEFFECT                     = S_FALSE;
+
+(*
+ *  The device is a polled device.  As a result, device buffering
+ *  will not collect any data and event notifications will not be
+ *  signalled until GetDeviceState is called.
+ *)
+  DI_POLLEDDEVICE                 = HRESULT($00000002);
+
+(*
+ *  The parameters of the effect were successfully updated by
+ *  IDirectInputEffect::SetParameters, but the effect was not
+ *  downloaded because the device is not exclusively acquired
+ *  or because the DIEP_NODOWNLOAD flag was passed.
+ *)
+  DI_DOWNLOADSKIPPED              = HRESULT($00000003);
+
+(*
+ *  The parameters of the effect were successfully updated by
+ *  IDirectInputEffect::SetParameters, but in order to change
+ *  the parameters, the effect needed to be restarted.
+ *)
+  DI_EFFECTRESTARTED              = HRESULT($00000004);
+
+(*
+ *  The parameters of the effect were successfully updated by
+ *  IDirectInputEffect::SetParameters, but some of them were
+ *  beyond the capabilities of the device and were truncated.
+ *)
+  DI_TRUNCATED                    = HRESULT($00000008);
+
+(*
+ *  The settings have been successfully applied but could not be
+ *  persisted.
+ *)
+  DI_SETTINGSNOTSAVED             = HRESULT($0000000B);
+
+(*
+ *  Equal to DI_EFFECTRESTARTED | DI_TRUNCATED.
+ *)
+  DI_TRUNCATEDANDRESTARTED        = HRESULT($0000000C);
+
+(*
+ *  A SUCCESS code indicating that settings cannot be modified.
+ *)
+  DI_WRITEPROTECT                 = HRESULT($00000013);
+
+(*
+ *  The application requires a newer version of DirectInput.
+ *)
+//  DIERR_OLDDIRECTINPUTVERSION     \
+//    MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_OLD_WIN_VERSION)
+
+(*
+ *  The application was written for an unsupported prerelease version
+ *  of DirectInput.
+ *)
+//  DIERR_BETADIRECTINPUTVERSION    \
+//    MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_RMODE_APP)
+
+(*
+ *  The object could not be created due to an incompatible driver version
+ *  or mismatched or incomplete driver components.
+ *)
+//  DIERR_BADDRIVERVER              \
+//    MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_BAD_DRIVER_LEVEL)
+
+(*
+ * The device or device instance or effect is not registered with DirectInput.
+ *)
+  DIERR_DEVICENOTREG              = REGDB_E_CLASSNOTREG;
+
+(*
+ * The requested object does not exist.
+ *)
+//  DIERR_NOTFOUND                  \
+//    MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND)
+
+(*
+ * The requested object does not exist.
+ *)
+//  DIERR_OBJECTNOTFOUND            \
+//    MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND)
+
+(*
+ * An invalid parameter was passed to the returning function,
+ * or the object was not in a state that admitted the function
+ * to be called.
+ *)
+  DIERR_INVALIDPARAM              = E_INVALIDARG;
+
+(*
+ * The specified interface is not supported by the object
+ *)
+  DIERR_NOINTERFACE               = E_NOINTERFACE;
+
+(*
+ * An undetermined error occured inside the DInput subsystem
+ *)
+  DIERR_GENERIC                   = E_FAIL;
+
+(*
+ * The DInput subsystem couldn't allocate sufficient memory to complete the
+ * caller's request.
+ *)
+  DIERR_OUTOFMEMORY               = E_OUTOFMEMORY;
+
+(*
+ * The function called is not supported at this time
+ *)
+  DIERR_UNSUPPORTED               = E_NOTIMPL;
+
+(*
+ * This object has not been initialized
+ *)
+//  DIERR_NOTINITIALIZED            \
+//    MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_READY)
+
+(*
+ * This object is already initialized
+ *)
+//  DIERR_ALREADYINITIALIZED        \
+//    MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_ALREADY_INITIALIZED)
+
+(*
+ * This object does not support aggregation
+ *)
+  DIERR_NOAGGREGATION             = CLASS_E_NOAGGREGATION;
+
+(*
+ * Another app has a higher priority level, preventing this call from
+ * succeeding.
+ *)
+  DIERR_OTHERAPPHASPRIO           = E_ACCESSDENIED;
+
+(*
+ * Access to the device has been lost.  It must be re-acquired.
+ *)
+//  DIERR_INPUTLOST                 \
+//    MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_READ_FAULT)
+
+(*
+ * The operation cannot be performed while the device is acquired.
+ *)
+//  DIERR_ACQUIRED                  \
+//    MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_BUSY)
+
+(*
+ * The operation cannot be performed unless the device is acquired.
+ *)
+//  DIERR_NOTACQUIRED               \
+//    MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_INVALID_ACCESS)
+
+(*
+ * The specified property cannot be changed.
+ *)
+  DIERR_READONLY                  = E_ACCESSDENIED;
+
+(*
+ * The device already has an event notification associated with it.
+ *)
+  DIERR_HANDLEEXISTS              = E_ACCESSDENIED;
+
+(*
+ * Data is not yet available.
+ *)
+//#ifndef E_PENDING
+  E_PENDING                       = $8000000A;
+//#endif
+
+(*
+ * Unable to IDirectInputJoyConfig_Acquire because the user
+ * does not have sufficient privileges to change the joystick
+ * configuration.
+ *)
+  DIERR_INSUFFICIENTPRIVS         = $80040200;
+
+(*
+ * The device is full.
+ *)
+  DIERR_DEVICEFULL                = $80040201;
+
+(*
+ * Not all the requested information fit into the buffer.
+ *)
+  DIERR_MOREDATA                  = $80040202;
+
+(*
+ * The effect is not downloaded.
+ *)
+  DIERR_NOTDOWNLOADED             = $80040203;
+
+(*
+ *  The device cannot be reinitialized because there are still effects
+ *  attached to it.
+ *)
+  DIERR_HASEFFECTS                = $80040204;
+
+(*
+ *  The operation cannot be performed unless the device is acquired
+ *  in DISCL_EXCLUSIVE mode.
+ *)
+  DIERR_NOTEXCLUSIVEACQUIRED      = $80040205;
+
+(*
+ *  The effect could not be downloaded because essential information
+ *  is missing.  For example, no axes have been associated with the
+ *  effect, or no type-specific information has been created.
+ *)
+  DIERR_INCOMPLETEEFFECT          = $80040206;
+
+(*
+ *  Attempted to read buffered device data from a device that is
+ *  not buffered.
+ *)
+  DIERR_NOTBUFFERED               = $80040207;
+
+(*
+ *  An attempt was made to modify parameters of an effect while it is
+ *  playing.  Not all hardware devices support altering the parameters
+ *  of an effect while it is playing.
+ *)
+  DIERR_EFFECTPLAYING             = $80040208;
+
+(*
+ *  The operation could not be completed because the device is not
+ *  plugged in.
+ *)
+  DIERR_UNPLUGGED                 = $80040209;
+
+(*
+ *  SendDeviceData failed because more information was requested
+ *  to be sent than can be sent to the device.  Some devices have
+ *  restrictions on how much data can be sent to them.  (For example,
+ *  there might be a limit on the number of buttons that can be
+ *  pressed at once.)
+ *)
+  DIERR_REPORTFULL                = $8004020A;
+
+
+(*
+ *  A mapper file function failed because reading or writing the user or IHV
+ *  settings file failed.
+ *)
+  DIERR_MAPFILEFAIL               = $8004020B;
+
+
+//
+//    Copyright (C) Microsoft.  All rights reserved.
+//
+
+
+//
+//    Copyright (C) Microsoft.  All rights reserved.
+//
+(*--- DINPUT Mapper Definitions: New for Dx8         ---*)
+
+
+(*--- Keyboard
+      Physical Keyboard Device       ---*)
+
+//
+//    Copyright (C) Microsoft.  All rights reserved.
+//
+  DIKEYBOARD_ESCAPE                       = $81000401;
+  DIKEYBOARD_1                            = $81000402;
+  DIKEYBOARD_2                            = $81000403;
+  DIKEYBOARD_3                            = $81000404;
+  DIKEYBOARD_4                            = $81000405;
+  DIKEYBOARD_5                            = $81000406;
+  DIKEYBOARD_6                            = $81000407;
+  DIKEYBOARD_7                            = $81000408;
+  DIKEYBOARD_8                            = $81000409;
+  DIKEYBOARD_9                            = $8100040A;
+  DIKEYBOARD_0                            = $8100040B;
+  DIKEYBOARD_MINUS                        = $8100040C;    { - on main keyboard }
+  DIKEYBOARD_EQUALS                       = $8100040D;
+  DIKEYBOARD_BACK                         = $8100040E;    { backspace }
+  DIKEYBOARD_TAB                          = $8100040F;
+  DIKEYBOARD_Q                            = $81000410;
+  DIKEYBOARD_W                            = $81000411;
+  DIKEYBOARD_E                            = $81000412;
+  DIKEYBOARD_R                            = $81000413;
+  DIKEYBOARD_T                            = $81000414;
+  DIKEYBOARD_Y                            = $81000415;
+  DIKEYBOARD_U                            = $81000416;
+  DIKEYBOARD_I                            = $81000417;
+  DIKEYBOARD_O                            = $81000418;
+  DIKEYBOARD_P                            = $81000419;
+  DIKEYBOARD_LBRACKET                     = $8100041A;
+  DIKEYBOARD_RBRACKET                     = $8100041B;
+  DIKEYBOARD_RETURN                       = $8100041C;    { Enter on main keyboard }
+  DIKEYBOARD_LCONTROL                     = $8100041D;
+  DIKEYBOARD_A                            = $8100041E;
+  DIKEYBOARD_S                            = $8100041F;
+  DIKEYBOARD_D                            = $81000420;
+  DIKEYBOARD_F                            = $81000421;
+  DIKEYBOARD_G                            = $81000422;
+  DIKEYBOARD_H                            = $81000423;
+  DIKEYBOARD_J                            = $81000424;
+  DIKEYBOARD_K                            = $81000425;
+  DIKEYBOARD_L                            = $81000426;
+  DIKEYBOARD_SEMICOLON                    = $81000427;
+  DIKEYBOARD_APOSTROPHE                   = $81000428;
+  DIKEYBOARD_GRAVE                        = $81000429;    { accent grave }
+  DIKEYBOARD_LSHIFT                       = $8100042A;
+  DIKEYBOARD_BACKSLASH                    = $8100042B;
+  DIKEYBOARD_Z                            = $8100042C;
+  DIKEYBOARD_X                            = $8100042D;
+  DIKEYBOARD_C                            = $8100042E;
+  DIKEYBOARD_V                            = $8100042F;
+  DIKEYBOARD_B                            = $81000430;
+  DIKEYBOARD_N                            = $81000431;
+  DIKEYBOARD_M                            = $81000432;
+  DIKEYBOARD_COMMA                        = $81000433;
+  DIKEYBOARD_PERIOD                       = $81000434;    { . on main keyboard }
+  DIKEYBOARD_SLASH                        = $81000435;    { / on main keyboard }
+  DIKEYBOARD_RSHIFT                       = $81000436;
+  DIKEYBOARD_MULTIPLY                     = $81000437;    { * on numeric keypad }
+  DIKEYBOARD_LMENU                        = $81000438;    { left Alt }
+  DIKEYBOARD_SPACE                        = $81000439;
+  DIKEYBOARD_CAPITAL                      = $8100043A;
+  DIKEYBOARD_F1                           = $8100043B;
+  DIKEYBOARD_F2                           = $8100043C;
+  DIKEYBOARD_F3                           = $8100043D;
+  DIKEYBOARD_F4                           = $8100043E;
+  DIKEYBOARD_F5                           = $8100043F;
+  DIKEYBOARD_F6                           = $81000440;
+  DIKEYBOARD_F7                           = $81000441;
+  DIKEYBOARD_F8                           = $81000442;
+  DIKEYBOARD_F9                           = $81000443;
+  DIKEYBOARD_F10                          = $81000444;
+  DIKEYBOARD_NUMLOCK                      = $81000445;
+  DIKEYBOARD_SCROLL                       = $81000446;    { Scroll Lock }
+  DIKEYBOARD_NUMPAD7                      = $81000447;
+  DIKEYBOARD_NUMPAD8                      = $81000448;
+  DIKEYBOARD_NUMPAD9                      = $81000449;
+  DIKEYBOARD_SUBTRACT                     = $8100044A;    { - on numeric keypad }
+  DIKEYBOARD_NUMPAD4                      = $8100044B;
+  DIKEYBOARD_NUMPAD5                      = $8100044C;
+  DIKEYBOARD_NUMPAD6                      = $8100044D;
+  DIKEYBOARD_ADD                          = $8100044E;    { + on numeric keypad }
+  DIKEYBOARD_NUMPAD1                      = $8100044F;
+  DIKEYBOARD_NUMPAD2                      = $81000450;
+  DIKEYBOARD_NUMPAD3                      = $81000451;
+  DIKEYBOARD_NUMPAD0                      = $81000452;
+  DIKEYBOARD_DECIMAL                      = $81000453;    { . on numeric keypad }
+  DIKEYBOARD_OEM_102                      = $81000456;    { <> or \| on RT 102-key keyboard (Non-U.S.) }
+  DIKEYBOARD_F11                          = $81000457;
+  DIKEYBOARD_F12                          = $81000458;
+  DIKEYBOARD_F13                          = $81000464;    {                     (NEC PC98) }
+  DIKEYBOARD_F14                          = $81000465;    {                     (NEC PC98) }
+  DIKEYBOARD_F15                          = $81000466;    {                     (NEC PC98) }
+  DIKEYBOARD_KANA                         = $81000470;    { (Japanese keyboard)            }
+  DIKEYBOARD_ABNT_C1                      = $81000473;    { /? on Brazilian keyboard }
+  DIKEYBOARD_CONVERT                      = $81000479;    { (Japanese keyboard)            }
+  DIKEYBOARD_NOCONVERT                    = $8100047B;    { (Japanese keyboard)            }
+  DIKEYBOARD_YEN                          = $8100047D;    { (Japanese keyboard)            }
+  DIKEYBOARD_ABNT_C2                      = $8100047E;    { Numpad . on Brazilian keyboard }
+  DIKEYBOARD_NUMPADEQUALS                 = $8100048D;    { = on numeric keypad (NEC PC98) }
+  DIKEYBOARD_PREVTRACK                    = $81000490;    { Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) }
+  DIKEYBOARD_AT                           = $81000491;    {                     (NEC PC98) }
+  DIKEYBOARD_COLON                        = $81000492;    {                     (NEC PC98) }
+  DIKEYBOARD_UNDERLINE                    = $81000493;    {                     (NEC PC98) }
+  DIKEYBOARD_KANJI                        = $81000494;    { (Japanese keyboard)            }
+  DIKEYBOARD_STOP                         = $81000495;    {                     (NEC PC98) }
+  DIKEYBOARD_AX                           = $81000496;    {                     (Japan AX) }
+  DIKEYBOARD_UNLABELED                    = $81000497;    {                        (J3100) }
+  DIKEYBOARD_NEXTTRACK                    = $81000499;    { Next Track }
+  DIKEYBOARD_NUMPADENTER                  = $8100049C;    { Enter on numeric keypad }
+  DIKEYBOARD_RCONTROL                     = $8100049D;
+  DIKEYBOARD_MUTE                         = $810004A0;    { Mute }
+  DIKEYBOARD_CALCULATOR                   = $810004A1;    { Calculator }
+  DIKEYBOARD_PLAYPAUSE                    = $810004A2;    { Play / Pause }
+  DIKEYBOARD_MEDIASTOP                    = $810004A4;    { Media Stop }
+  DIKEYBOARD_VOLUMEDOWN                   = $810004AE;    { Volume - }
+  DIKEYBOARD_VOLUMEUP                     = $810004B0;    { Volume + }
+  DIKEYBOARD_WEBHOME                      = $810004B2;    { Web home }
+  DIKEYBOARD_NUMPADCOMMA                  = $810004B3;    { , on numeric keypad (NEC PC98) }
+  DIKEYBOARD_DIVIDE                       = $810004B5;    { / on numeric keypad }
+  DIKEYBOARD_SYSRQ                        = $810004B7;
+  DIKEYBOARD_RMENU                        = $810004B8;    { right Alt }
+  DIKEYBOARD_PAUSE                        = $810004C5;    { Pause }
+  DIKEYBOARD_HOME                         = $810004C7;    { Home on arrow keypad }
+  DIKEYBOARD_UP                           = $810004C8;    { UpArrow on arrow keypad }
+  DIKEYBOARD_PRIOR                        = $810004C9;    { PgUp on arrow keypad }
+  DIKEYBOARD_LEFT                         = $810004CB;    { LeftArrow on arrow keypad }
+  DIKEYBOARD_RIGHT                        = $810004CD;    { RightArrow on arrow keypad }
+  DIKEYBOARD_END                          = $810004CF;    { End on arrow keypad }
+  DIKEYBOARD_DOWN                         = $810004D0;    { DownArrow on arrow keypad }
+  DIKEYBOARD_NEXT                         = $810004D1;    { PgDn on arrow keypad }
+  DIKEYBOARD_INSERT                       = $810004D2;    { Insert on arrow keypad }
+  DIKEYBOARD_DELETE                       = $810004D3;    { Delete on arrow keypad }
+  DIKEYBOARD_LWIN                         = $810004DB;    { Left Windows key }
+  DIKEYBOARD_RWIN                         = $810004DC;    { Right Windows key }
+  DIKEYBOARD_APPS                         = $810004DD;    { AppMenu key }
+  DIKEYBOARD_POWER                        = $810004DE;    { System Power }
+  DIKEYBOARD_SLEEP                        = $810004DF;    { System Sleep }
+  DIKEYBOARD_WAKE                         = $810004E3;    { System Wake }
+  DIKEYBOARD_WEBSEARCH                    = $810004E5;    { Web Search }
+  DIKEYBOARD_WEBFAVORITES                 = $810004E6;    { Web Favorites }
+  DIKEYBOARD_WEBREFRESH                   = $810004E7;    { Web Refresh }
+  DIKEYBOARD_WEBSTOP                      = $810004E8;    { Web Stop }
+  DIKEYBOARD_WEBFORWARD                   = $810004E9;    { Web Forward }
+  DIKEYBOARD_WEBBACK                      = $810004EA;    { Web Back }
+  DIKEYBOARD_MYCOMPUTER                   = $810004EB;    { My Computer }
+  DIKEYBOARD_MAIL                         = $810004EC;    { Mail }
+  DIKEYBOARD_MEDIASELECT                  = $810004ED;    { Media Select }
+
+
+(*--- MOUSE
+      Physical Mouse Device             ---*)
+
+{#define DIMOUSE_XAXISAB                         (0x82000200 |DIMOFS_X ) /* X Axis-absolute: Some mice natively report absolute coordinates  */
+#define DIMOUSE_YAXISAB                         (0x82000200 |DIMOFS_Y ) /* Y Axis-absolute: Some mice natively report absolute coordinates */
+#define DIMOUSE_XAXIS                           (0x82000300 |DIMOFS_X ) /* X Axis */
+#define DIMOUSE_YAXIS                           (0x82000300 |DIMOFS_Y ) /* Y Axis */
+#define DIMOUSE_WHEEL                           (0x82000300 |DIMOFS_Z ) /* Z Axis */
+#define DIMOUSE_BUTTON0                         (0x82000400 |DIMOFS_BUTTON0) /* Button 0 */
+#define DIMOUSE_BUTTON1                         (0x82000400 |DIMOFS_BUTTON1) /* Button 1 */
+#define DIMOUSE_BUTTON2                         (0x82000400 |DIMOFS_BUTTON2) /* Button 2 */
+#define DIMOUSE_BUTTON3                         (0x82000400 |DIMOFS_BUTTON3) /* Button 3 */
+#define DIMOUSE_BUTTON4                         (0x82000400 |DIMOFS_BUTTON4) /* Button 4 */
+#define DIMOUSE_BUTTON5                         (0x82000400 |DIMOFS_BUTTON5) /* Button 5 */
+#define DIMOUSE_BUTTON6                         (0x82000400 |DIMOFS_BUTTON6) /* Button 6 */
+#define DIMOUSE_BUTTON7                         (0x82000400 |DIMOFS_BUTTON7) /* Button 7 */}
+
+
+(*--- VOICE
+      Physical Dplay Voice Device       ---*)
+
+  DIVOICE_CHANNEL1                        = $83000401;
+  DIVOICE_CHANNEL2                        = $83000402;
+  DIVOICE_CHANNEL3                        = $83000403;
+  DIVOICE_CHANNEL4                        = $83000404;
+  DIVOICE_CHANNEL5                        = $83000405;
+  DIVOICE_CHANNEL6                        = $83000406;
+  DIVOICE_CHANNEL7                        = $83000407;
+  DIVOICE_CHANNEL8                        = $83000408;
+  DIVOICE_TEAM                            = $83000409;
+  DIVOICE_ALL                             = $8300040A;
+  DIVOICE_RECORDMUTE                      = $8300040B;
+  DIVOICE_PLAYBACKMUTE                    = $8300040C;
+  DIVOICE_TRANSMIT                        = $8300040D;
+
+  DIVOICE_VOICECOMMAND                    = $83000410;
+
+
+(*--- Driving Simulator - Racing
+      Vehicle control is primary objective  ---*)
+  DIVIRTUAL_DRIVING_RACE                  = $01000000;
+  DIAXIS_DRIVINGR_STEER                   = $01008A01; { Steering }
+  DIAXIS_DRIVINGR_ACCELERATE              = $01039202; { Accelerate }
+  DIAXIS_DRIVINGR_BRAKE                   = $01041203; { Brake-Axis }
+  DIBUTTON_DRIVINGR_SHIFTUP               = $01000C01; { Shift to next higher gear }
+  DIBUTTON_DRIVINGR_SHIFTDOWN             = $01000C02; { Shift to next lower gear }
+  DIBUTTON_DRIVINGR_VIEW                  = $01001C03; { Cycle through view options }
+  DIBUTTON_DRIVINGR_MENU                  = $010004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIAXIS_DRIVINGR_ACCEL_AND_BRAKE         = $01014A04; { Some devices combine accelerate and brake in a single axis }
+  DIHATSWITCH_DRIVINGR_GLANCE             = $01004601; { Look around }
+  DIBUTTON_DRIVINGR_BRAKE                 = $01004C04; { Brake-button }
+  DIBUTTON_DRIVINGR_DASHBOARD             = $01004405; { Select next dashboard option }
+  DIBUTTON_DRIVINGR_AIDS                  = $01004406; { Driver correction aids }
+  DIBUTTON_DRIVINGR_MAP                   = $01004407; { Display Driving Map }
+  DIBUTTON_DRIVINGR_BOOST                 = $01004408; { Turbo Boost }
+  DIBUTTON_DRIVINGR_PIT                   = $01004409; { Pit stop notification }
+  DIBUTTON_DRIVINGR_ACCELERATE_LINK       = $0103D4E0; { Fallback Accelerate button }
+  DIBUTTON_DRIVINGR_STEER_LEFT_LINK       = $0100CCE4; { Fallback Steer Left button }
+  DIBUTTON_DRIVINGR_STEER_RIGHT_LINK      = $0100CCEC; { Fallback Steer Right button }
+  DIBUTTON_DRIVINGR_GLANCE_LEFT_LINK      = $0107C4E4; { Fallback Glance Left button }
+  DIBUTTON_DRIVINGR_GLANCE_RIGHT_LINK     = $0107C4EC; { Fallback Glance Right button }
+  DIBUTTON_DRIVINGR_DEVICE                = $010044FE; { Show input device and controls }
+  DIBUTTON_DRIVINGR_PAUSE                 = $010044FC; { Start / Pause / Restart game }
+
+(*--- Driving Simulator - Combat
+      Combat from within a vehicle is primary objective  ---*)
+  DIVIRTUAL_DRIVING_COMBAT                = $02000000;
+  DIAXIS_DRIVINGC_STEER                   = $02008A01; { Steering  }
+  DIAXIS_DRIVINGC_ACCELERATE              = $02039202; { Accelerate }
+  DIAXIS_DRIVINGC_BRAKE                   = $02041203; { Brake-axis }
+  DIBUTTON_DRIVINGC_FIRE                  = $02000C01; { Fire }
+  DIBUTTON_DRIVINGC_WEAPONS               = $02000C02; { Select next weapon }
+  DIBUTTON_DRIVINGC_TARGET                = $02000C03; { Select next available target }
+  DIBUTTON_DRIVINGC_MENU                  = $020004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIAXIS_DRIVINGC_ACCEL_AND_BRAKE         = $02014A04; { Some devices combine accelerate and brake in a single axis }
+  DIHATSWITCH_DRIVINGC_GLANCE             = $02004601; { Look around }
+  DIBUTTON_DRIVINGC_SHIFTUP               = $02004C04; { Shift to next higher gear }
+  DIBUTTON_DRIVINGC_SHIFTDOWN             = $02004C05; { Shift to next lower gear }
+  DIBUTTON_DRIVINGC_DASHBOARD             = $02004406; { Select next dashboard option }
+  DIBUTTON_DRIVINGC_AIDS                  = $02004407; { Driver correction aids }
+  DIBUTTON_DRIVINGC_BRAKE                 = $02004C08; { Brake-button }
+  DIBUTTON_DRIVINGC_FIRESECONDARY         = $02004C09; { Alternative fire button }
+  DIBUTTON_DRIVINGC_ACCELERATE_LINK       = $0203D4E0; { Fallback Accelerate button }
+  DIBUTTON_DRIVINGC_STEER_LEFT_LINK       = $0200CCE4; { Fallback Steer Left button }
+  DIBUTTON_DRIVINGC_STEER_RIGHT_LINK      = $0200CCEC; { Fallback Steer Right button }
+  DIBUTTON_DRIVINGC_GLANCE_LEFT_LINK      = $0207C4E4; { Fallback Glance Left button }
+  DIBUTTON_DRIVINGC_GLANCE_RIGHT_LINK     = $0207C4EC; { Fallback Glance Right button }
+  DIBUTTON_DRIVINGC_DEVICE                = $020044FE; { Show input device and controls }
+  DIBUTTON_DRIVINGC_PAUSE                 = $020044FC; { Start / Pause / Restart game }
+
+(*--- Driving Simulator - Tank
+      Combat from withing a tank is primary objective  ---*)
+  DIVIRTUAL_DRIVING_TANK                  = $03000000;
+  DIAXIS_DRIVINGT_STEER                   = $03008A01; { Turn tank left / right }
+  DIAXIS_DRIVINGT_BARREL                  = $03010202; { Raise / lower barrel }
+  DIAXIS_DRIVINGT_ACCELERATE              = $03039203; { Accelerate }
+  DIAXIS_DRIVINGT_ROTATE                  = $03020204; { Turn barrel left / right }
+  DIBUTTON_DRIVINGT_FIRE                  = $03000C01; { Fire }
+  DIBUTTON_DRIVINGT_WEAPONS               = $03000C02; { Select next weapon }
+  DIBUTTON_DRIVINGT_TARGET                = $03000C03; { Selects next available target }
+  DIBUTTON_DRIVINGT_MENU                  = $030004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_DRIVINGT_GLANCE             = $03004601; { Look around }
+  DIAXIS_DRIVINGT_BRAKE                   = $03045205; { Brake-axis }
+  DIAXIS_DRIVINGT_ACCEL_AND_BRAKE         = $03014A06; { Some devices combine accelerate and brake in a single axis }
+  DIBUTTON_DRIVINGT_VIEW                  = $03005C04; { Cycle through view options }
+  DIBUTTON_DRIVINGT_DASHBOARD             = $03005C05; { Select next dashboard option }
+  DIBUTTON_DRIVINGT_BRAKE                 = $03004C06; { Brake-button }
+  DIBUTTON_DRIVINGT_FIRESECONDARY         = $03004C07; { Alternative fire button }
+  DIBUTTON_DRIVINGT_ACCELERATE_LINK       = $0303D4E0; { Fallback Accelerate button }
+  DIBUTTON_DRIVINGT_STEER_LEFT_LINK       = $0300CCE4; { Fallback Steer Left button }
+  DIBUTTON_DRIVINGT_STEER_RIGHT_LINK      = $0300CCEC; { Fallback Steer Right button }
+  DIBUTTON_DRIVINGT_BARREL_UP_LINK        = $030144E0; { Fallback Barrel up button }
+  DIBUTTON_DRIVINGT_BARREL_DOWN_LINK      = $030144E8; { Fallback Barrel down button }
+  DIBUTTON_DRIVINGT_ROTATE_LEFT_LINK      = $030244E4; { Fallback Rotate left button }
+  DIBUTTON_DRIVINGT_ROTATE_RIGHT_LINK     = $030244EC; { Fallback Rotate right button }
+  DIBUTTON_DRIVINGT_GLANCE_LEFT_LINK      = $0307C4E4; { Fallback Glance Left button }
+  DIBUTTON_DRIVINGT_GLANCE_RIGHT_LINK     = $0307C4EC; { Fallback Glance Right button }
+  DIBUTTON_DRIVINGT_DEVICE                = $030044FE; { Show input device and controls }
+  DIBUTTON_DRIVINGT_PAUSE                 = $030044FC; { Start / Pause / Restart game }
+
+(*--- Flight Simulator - Civilian
+      Plane control is the primary objective  ---*)
+  DIVIRTUAL_FLYING_CIVILIAN               = $04000000;
+  DIAXIS_FLYINGC_BANK                     = $04008A01; { Roll ship left / right }
+  DIAXIS_FLYINGC_PITCH                    = $04010A02; { Nose up / down }
+  DIAXIS_FLYINGC_THROTTLE                 = $04039203; { Throttle }
+  DIBUTTON_FLYINGC_VIEW                   = $04002401; { Cycle through view options }
+  DIBUTTON_FLYINGC_DISPLAY                = $04002402; { Select next dashboard / heads up display option }
+  DIBUTTON_FLYINGC_GEAR                   = $04002C03; { Gear up / down }
+  DIBUTTON_FLYINGC_MENU                   = $040004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_FLYINGC_GLANCE              = $04004601; { Look around }
+  DIAXIS_FLYINGC_BRAKE                    = $04046A04; { Apply Brake }
+  DIAXIS_FLYINGC_RUDDER                   = $04025205; { Yaw ship left/right }
+  DIAXIS_FLYINGC_FLAPS                    = $04055A06; { Flaps }
+  DIBUTTON_FLYINGC_FLAPSUP                = $04006404; { Increment stepping up until fully retracted }
+  DIBUTTON_FLYINGC_FLAPSDOWN              = $04006405; { Decrement stepping down until fully extended }
+  DIBUTTON_FLYINGC_BRAKE_LINK             = $04046CE0; { Fallback brake button }
+  DIBUTTON_FLYINGC_FASTER_LINK            = $0403D4E0; { Fallback throttle up button }
+  DIBUTTON_FLYINGC_SLOWER_LINK            = $0403D4E8; { Fallback throttle down button }
+  DIBUTTON_FLYINGC_GLANCE_LEFT_LINK       = $0407C4E4; { Fallback Glance Left button }
+  DIBUTTON_FLYINGC_GLANCE_RIGHT_LINK      = $0407C4EC; { Fallback Glance Right button }
+  DIBUTTON_FLYINGC_GLANCE_UP_LINK         = $0407C4E0; { Fallback Glance Up button }
+  DIBUTTON_FLYINGC_GLANCE_DOWN_LINK       = $0407C4E8; { Fallback Glance Down button }
+  DIBUTTON_FLYINGC_DEVICE                 = $040044FE; { Show input device and controls }
+  DIBUTTON_FLYINGC_PAUSE                  = $040044FC; { Start / Pause / Restart game }
+
+(*--- Flight Simulator - Military
+      Aerial combat is the primary objective  ---*)
+  DIVIRTUAL_FLYING_MILITARY               = $05000000;
+  DIAXIS_FLYINGM_BANK                     = $05008A01; { Bank - Roll ship left / right }
+  DIAXIS_FLYINGM_PITCH                    = $05010A02; { Pitch - Nose up / down }
+  DIAXIS_FLYINGM_THROTTLE                 = $05039203; { Throttle - faster / slower }
+  DIBUTTON_FLYINGM_FIRE                   = $05000C01; { Fire }
+  DIBUTTON_FLYINGM_WEAPONS                = $05000C02; { Select next weapon }
+  DIBUTTON_FLYINGM_TARGET                 = $05000C03; { Selects next available target }
+  DIBUTTON_FLYINGM_MENU                   = $050004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_FLYINGM_GLANCE              = $05004601; { Look around }
+  DIBUTTON_FLYINGM_COUNTER                = $05005C04; { Activate counter measures }
+  DIAXIS_FLYINGM_RUDDER                   = $05024A04; { Rudder - Yaw ship left/right }
+  DIAXIS_FLYINGM_BRAKE                    = $05046205; { Brake-axis }
+  DIBUTTON_FLYINGM_VIEW                   = $05006405; { Cycle through view options }
+  DIBUTTON_FLYINGM_DISPLAY                = $05006406; { Select next dashboard option }
+  DIAXIS_FLYINGM_FLAPS                    = $05055206; { Flaps }
+  DIBUTTON_FLYINGM_FLAPSUP                = $05005407; { Increment stepping up until fully retracted }
+  DIBUTTON_FLYINGM_FLAPSDOWN              = $05005408; { Decrement stepping down until fully extended }
+  DIBUTTON_FLYINGM_FIRESECONDARY          = $05004C09; { Alternative fire button }
+  DIBUTTON_FLYINGM_GEAR                   = $0500640A; { Gear up / down }
+  DIBUTTON_FLYINGM_BRAKE_LINK             = $050464E0; { Fallback brake button }
+  DIBUTTON_FLYINGM_FASTER_LINK            = $0503D4E0; { Fallback throttle up button }
+  DIBUTTON_FLYINGM_SLOWER_LINK            = $0503D4E8; { Fallback throttle down button }
+  DIBUTTON_FLYINGM_GLANCE_LEFT_LINK       = $0507C4E4; { Fallback Glance Left button }
+  DIBUTTON_FLYINGM_GLANCE_RIGHT_LINK      = $0507C4EC; { Fallback Glance Right button }
+  DIBUTTON_FLYINGM_GLANCE_UP_LINK         = $0507C4E0; { Fallback Glance Up button }
+  DIBUTTON_FLYINGM_GLANCE_DOWN_LINK       = $0507C4E8; { Fallback Glance Down button }
+  DIBUTTON_FLYINGM_DEVICE                 = $050044FE; { Show input device and controls }
+  DIBUTTON_FLYINGM_PAUSE                  = $050044FC; { Start / Pause / Restart game }
+
+(*--- Flight Simulator - Combat Helicopter
+      Combat from helicopter is primary objective  ---*)
+  DIVIRTUAL_FLYING_HELICOPTER             = $06000000;
+  DIAXIS_FLYINGH_BANK                     = $06008A01; { Bank - Roll ship left / right }
+  DIAXIS_FLYINGH_PITCH                    = $06010A02; { Pitch - Nose up / down }
+  DIAXIS_FLYINGH_COLLECTIVE               = $06018A03; { Collective - Blade pitch/power }
+  DIBUTTON_FLYINGH_FIRE                   = $06001401; { Fire }
+  DIBUTTON_FLYINGH_WEAPONS                = $06001402; { Select next weapon }
+  DIBUTTON_FLYINGH_TARGET                 = $06001403; { Selects next available target }
+  DIBUTTON_FLYINGH_MENU                   = $060004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_FLYINGH_GLANCE              = $06004601; { Look around }
+  DIAXIS_FLYINGH_TORQUE                   = $06025A04; { Torque - Rotate ship around left / right axis }
+  DIAXIS_FLYINGH_THROTTLE                 = $0603DA05; { Throttle }
+  DIBUTTON_FLYINGH_COUNTER                = $06005404; { Activate counter measures }
+  DIBUTTON_FLYINGH_VIEW                   = $06006405; { Cycle through view options }
+  DIBUTTON_FLYINGH_GEAR                   = $06006406; { Gear up / down }
+  DIBUTTON_FLYINGH_FIRESECONDARY          = $06004C07; { Alternative fire button }
+  DIBUTTON_FLYINGH_FASTER_LINK            = $0603DCE0; { Fallback throttle up button }
+  DIBUTTON_FLYINGH_SLOWER_LINK            = $0603DCE8; { Fallback throttle down button }
+  DIBUTTON_FLYINGH_GLANCE_LEFT_LINK       = $0607C4E4; { Fallback Glance Left button }
+  DIBUTTON_FLYINGH_GLANCE_RIGHT_LINK      = $0607C4EC; { Fallback Glance Right button }
+  DIBUTTON_FLYINGH_GLANCE_UP_LINK         = $0607C4E0; { Fallback Glance Up button }
+  DIBUTTON_FLYINGH_GLANCE_DOWN_LINK       = $0607C4E8; { Fallback Glance Down button }
+  DIBUTTON_FLYINGH_DEVICE                 = $060044FE; { Show input device and controls }
+  DIBUTTON_FLYINGH_PAUSE                  = $060044FC; { Start / Pause / Restart game }
+
+(*--- Space Simulator - Combat
+      Space Simulator with weapons  ---*)
+  DIVIRTUAL_SPACESIM                      = $07000000;
+  DIAXIS_SPACESIM_LATERAL                 = $07008201; { Move ship left / right }
+  DIAXIS_SPACESIM_MOVE                    = $07010202; { Move ship forward/backward }
+  DIAXIS_SPACESIM_THROTTLE                = $07038203; { Throttle - Engine speed }
+  DIBUTTON_SPACESIM_FIRE                  = $07000401; { Fire }
+  DIBUTTON_SPACESIM_WEAPONS               = $07000402; { Select next weapon }
+  DIBUTTON_SPACESIM_TARGET                = $07000403; { Selects next available target }
+  DIBUTTON_SPACESIM_MENU                  = $070004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_SPACESIM_GLANCE             = $07004601; { Look around }
+  DIAXIS_SPACESIM_CLIMB                   = $0701C204; { Climb - Pitch ship up/down }
+  DIAXIS_SPACESIM_ROTATE                  = $07024205; { Rotate - Turn ship left/right }
+  DIBUTTON_SPACESIM_VIEW                  = $07004404; { Cycle through view options }
+  DIBUTTON_SPACESIM_DISPLAY               = $07004405; { Select next dashboard / heads up display option }
+  DIBUTTON_SPACESIM_RAISE                 = $07004406; { Raise ship while maintaining current pitch }
+  DIBUTTON_SPACESIM_LOWER                 = $07004407; { Lower ship while maintaining current pitch }
+  DIBUTTON_SPACESIM_GEAR                  = $07004408; { Gear up / down }
+  DIBUTTON_SPACESIM_FIRESECONDARY         = $07004409; { Alternative fire button }
+  DIBUTTON_SPACESIM_LEFT_LINK             = $0700C4E4; { Fallback move left button }
+  DIBUTTON_SPACESIM_RIGHT_LINK            = $0700C4EC; { Fallback move right button }
+  DIBUTTON_SPACESIM_FORWARD_LINK          = $070144E0; { Fallback move forward button }
+  DIBUTTON_SPACESIM_BACKWARD_LINK         = $070144E8; { Fallback move backwards button }
+  DIBUTTON_SPACESIM_FASTER_LINK           = $0703C4E0; { Fallback throttle up button }
+  DIBUTTON_SPACESIM_SLOWER_LINK           = $0703C4E8; { Fallback throttle down button }
+  DIBUTTON_SPACESIM_TURN_LEFT_LINK        = $070244E4; { Fallback turn left button }
+  DIBUTTON_SPACESIM_TURN_RIGHT_LINK       = $070244EC; { Fallback turn right button }
+  DIBUTTON_SPACESIM_GLANCE_LEFT_LINK      = $0707C4E4; { Fallback Glance Left button }
+  DIBUTTON_SPACESIM_GLANCE_RIGHT_LINK     = $0707C4EC; { Fallback Glance Right button }
+  DIBUTTON_SPACESIM_GLANCE_UP_LINK        = $0707C4E0; { Fallback Glance Up button }
+  DIBUTTON_SPACESIM_GLANCE_DOWN_LINK      = $0707C4E8; { Fallback Glance Down button }
+  DIBUTTON_SPACESIM_DEVICE                = $070044FE; { Show input device and controls }
+  DIBUTTON_SPACESIM_PAUSE                 = $070044FC; { Start / Pause / Restart game }
+
+(*--- Fighting - First Person
+      Hand to Hand combat is primary objective  ---*)
+  DIVIRTUAL_FIGHTING_HAND2HAND            = $08000000;
+  DIAXIS_FIGHTINGH_LATERAL                = $08008201; { Sidestep left/right }
+  DIAXIS_FIGHTINGH_MOVE                   = $08010202; { Move forward/backward }
+  DIBUTTON_FIGHTINGH_PUNCH                = $08000401; { Punch }
+  DIBUTTON_FIGHTINGH_KICK                 = $08000402; { Kick }
+  DIBUTTON_FIGHTINGH_BLOCK                = $08000403; { Block }
+  DIBUTTON_FIGHTINGH_CROUCH               = $08000404; { Crouch }
+  DIBUTTON_FIGHTINGH_JUMP                 = $08000405; { Jump }
+  DIBUTTON_FIGHTINGH_SPECIAL1             = $08000406; { Apply first special move }
+  DIBUTTON_FIGHTINGH_SPECIAL2             = $08000407; { Apply second special move }
+  DIBUTTON_FIGHTINGH_MENU                 = $080004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIBUTTON_FIGHTINGH_SELECT               = $08004408; { Select special move }
+  DIHATSWITCH_FIGHTINGH_SLIDE             = $08004601; { Look around }
+  DIBUTTON_FIGHTINGH_DISPLAY              = $08004409; { Shows next on-screen display option }
+  DIAXIS_FIGHTINGH_ROTATE                 = $08024203; { Rotate - Turn body left/right }
+  DIBUTTON_FIGHTINGH_DODGE                = $0800440A; { Dodge }
+  DIBUTTON_FIGHTINGH_LEFT_LINK            = $0800C4E4; { Fallback left sidestep button }
+  DIBUTTON_FIGHTINGH_RIGHT_LINK           = $0800C4EC; { Fallback right sidestep button }
+  DIBUTTON_FIGHTINGH_FORWARD_LINK         = $080144E0; { Fallback forward button }
+  DIBUTTON_FIGHTINGH_BACKWARD_LINK        = $080144E8; { Fallback backward button }
+  DIBUTTON_FIGHTINGH_DEVICE               = $080044FE; { Show input device and controls }
+  DIBUTTON_FIGHTINGH_PAUSE                = $080044FC; { Start / Pause / Restart game }
+
+(*--- Fighting - First Person Shooting
+      Navigation and combat are primary objectives  ---*)
+  DIVIRTUAL_FIGHTING_FPS                  = $09000000;
+  DIAXIS_FPS_ROTATE                       = $09008201; { Rotate character left/right }
+  DIAXIS_FPS_MOVE                         = $09010202; { Move forward/backward }
+  DIBUTTON_FPS_FIRE                       = $09000401; { Fire }
+  DIBUTTON_FPS_WEAPONS                    = $09000402; { Select next weapon }
+  DIBUTTON_FPS_APPLY                      = $09000403; { Use item }
+  DIBUTTON_FPS_SELECT                     = $09000404; { Select next inventory item }
+  DIBUTTON_FPS_CROUCH                     = $09000405; { Crouch/ climb down/ swim down }
+  DIBUTTON_FPS_JUMP                       = $09000406; { Jump/ climb up/ swim up }
+  DIAXIS_FPS_LOOKUPDOWN                   = $09018203; { Look up / down  }
+  DIBUTTON_FPS_STRAFE                     = $09000407; { Enable strafing while active }
+  DIBUTTON_FPS_MENU                       = $090004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_FPS_GLANCE                  = $09004601; { Look around }
+  DIBUTTON_FPS_DISPLAY                    = $09004408; { Shows next on-screen display option/ map }
+  DIAXIS_FPS_SIDESTEP                     = $09024204; { Sidestep }
+  DIBUTTON_FPS_DODGE                      = $09004409; { Dodge }
+  DIBUTTON_FPS_GLANCEL                    = $0900440A; { Glance Left }
+  DIBUTTON_FPS_GLANCER                    = $0900440B; { Glance Right }
+  DIBUTTON_FPS_FIRESECONDARY              = $0900440C; { Alternative fire button }
+  DIBUTTON_FPS_ROTATE_LEFT_LINK           = $0900C4E4; { Fallback rotate left button }
+  DIBUTTON_FPS_ROTATE_RIGHT_LINK          = $0900C4EC; { Fallback rotate right button }
+  DIBUTTON_FPS_FORWARD_LINK               = $090144E0; { Fallback forward button }
+  DIBUTTON_FPS_BACKWARD_LINK              = $090144E8; { Fallback backward button }
+  DIBUTTON_FPS_GLANCE_UP_LINK             = $0901C4E0; { Fallback look up button }
+  DIBUTTON_FPS_GLANCE_DOWN_LINK           = $0901C4E8; { Fallback look down button }
+  DIBUTTON_FPS_STEP_LEFT_LINK             = $090244E4; { Fallback step left button }
+  DIBUTTON_FPS_STEP_RIGHT_LINK            = $090244EC; { Fallback step right button }
+  DIBUTTON_FPS_DEVICE                     = $090044FE; { Show input device and controls }
+  DIBUTTON_FPS_PAUSE                      = $090044FC; { Start / Pause / Restart game }
+
+(*--- Fighting - Third Person action
+      Perspective of camera is behind the main character  ---*)
+  DIVIRTUAL_FIGHTING_THIRDPERSON          = $0A000000;
+  DIAXIS_TPS_TURN                         = $0A020201; { Turn left/right }
+  DIAXIS_TPS_MOVE                         = $0A010202; { Move forward/backward }
+  DIBUTTON_TPS_RUN                        = $0A000401; { Run or walk toggle switch }
+  DIBUTTON_TPS_ACTION                     = $0A000402; { Action Button }
+  DIBUTTON_TPS_SELECT                     = $0A000403; { Select next weapon }
+  DIBUTTON_TPS_USE                        = $0A000404; { Use inventory item currently selected }
+  DIBUTTON_TPS_JUMP                       = $0A000405; { Character Jumps }
+  DIBUTTON_TPS_MENU                       = $0A0004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_TPS_GLANCE                  = $0A004601; { Look around }
+  DIBUTTON_TPS_VIEW                       = $0A004406; { Select camera view }
+  DIBUTTON_TPS_STEPLEFT                   = $0A004407; { Character takes a left step }
+  DIBUTTON_TPS_STEPRIGHT                  = $0A004408; { Character takes a right step }
+  DIAXIS_TPS_STEP                         = $0A00C203; { Character steps left/right }
+  DIBUTTON_TPS_DODGE                      = $0A004409; { Character dodges or ducks }
+  DIBUTTON_TPS_INVENTORY                  = $0A00440A; { Cycle through inventory }
+  DIBUTTON_TPS_TURN_LEFT_LINK             = $0A0244E4; { Fallback turn left button }
+  DIBUTTON_TPS_TURN_RIGHT_LINK            = $0A0244EC; { Fallback turn right button }
+  DIBUTTON_TPS_FORWARD_LINK               = $0A0144E0; { Fallback forward button }
+  DIBUTTON_TPS_BACKWARD_LINK              = $0A0144E8; { Fallback backward button }
+  DIBUTTON_TPS_GLANCE_UP_LINK             = $0A07C4E0; { Fallback look up button }
+  DIBUTTON_TPS_GLANCE_DOWN_LINK           = $0A07C4E8; { Fallback look down button }
+  DIBUTTON_TPS_GLANCE_LEFT_LINK           = $0A07C4E4; { Fallback glance up button }
+  DIBUTTON_TPS_GLANCE_RIGHT_LINK          = $0A07C4EC; { Fallback glance right button }
+  DIBUTTON_TPS_DEVICE                     = $0A0044FE; { Show input device and controls }
+  DIBUTTON_TPS_PAUSE                      = $0A0044FC; { Start / Pause / Restart game }
+
+(*--- Strategy - Role Playing
+      Navigation and problem solving are primary actions  ---*)
+  DIVIRTUAL_STRATEGY_ROLEPLAYING          = $0B000000;
+  DIAXIS_STRATEGYR_LATERAL                = $0B008201; { sidestep - left/right }
+  DIAXIS_STRATEGYR_MOVE                   = $0B010202; { move forward/backward }
+  DIBUTTON_STRATEGYR_GET                  = $0B000401; { Acquire item }
+  DIBUTTON_STRATEGYR_APPLY                = $0B000402; { Use selected item }
+  DIBUTTON_STRATEGYR_SELECT               = $0B000403; { Select nextitem }
+  DIBUTTON_STRATEGYR_ATTACK               = $0B000404; { Attack }
+  DIBUTTON_STRATEGYR_CAST                 = $0B000405; { Cast Spell }
+  DIBUTTON_STRATEGYR_CROUCH               = $0B000406; { Crouch }
+  DIBUTTON_STRATEGYR_JUMP                 = $0B000407; { Jump }
+  DIBUTTON_STRATEGYR_MENU                 = $0B0004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_STRATEGYR_GLANCE            = $0B004601; { Look around }
+  DIBUTTON_STRATEGYR_MAP                  = $0B004408; { Cycle through map options }
+  DIBUTTON_STRATEGYR_DISPLAY              = $0B004409; { Shows next on-screen display option }
+  DIAXIS_STRATEGYR_ROTATE                 = $0B024203; { Turn body left/right }
+  DIBUTTON_STRATEGYR_LEFT_LINK            = $0B00C4E4; { Fallback sidestep left button }
+  DIBUTTON_STRATEGYR_RIGHT_LINK           = $0B00C4EC; { Fallback sidestep right button }
+  DIBUTTON_STRATEGYR_FORWARD_LINK         = $0B0144E0; { Fallback move forward button }
+  DIBUTTON_STRATEGYR_BACK_LINK            = $0B0144E8; { Fallback move backward button }
+  DIBUTTON_STRATEGYR_ROTATE_LEFT_LINK     = $0B0244E4; { Fallback turn body left button }
+  DIBUTTON_STRATEGYR_ROTATE_RIGHT_LINK    = $0B0244EC; { Fallback turn body right button }
+  DIBUTTON_STRATEGYR_DEVICE               = $0B0044FE; { Show input device and controls }
+  DIBUTTON_STRATEGYR_PAUSE                = $0B0044FC; { Start / Pause / Restart game }
+
+(*--- Strategy - Turn based
+      Navigation and problem solving are primary actions  ---*)
+  DIVIRTUAL_STRATEGY_TURN                 = $0C000000;
+  DIAXIS_STRATEGYT_LATERAL                = $0C008201; { Sidestep left/right }
+  DIAXIS_STRATEGYT_MOVE                   = $0C010202; { Move forward/backwards }
+  DIBUTTON_STRATEGYT_SELECT               = $0C000401; { Select unit or object }
+  DIBUTTON_STRATEGYT_INSTRUCT             = $0C000402; { Cycle through instructions }
+  DIBUTTON_STRATEGYT_APPLY                = $0C000403; { Apply selected instruction }
+  DIBUTTON_STRATEGYT_TEAM                 = $0C000404; { Select next team / cycle through all }
+  DIBUTTON_STRATEGYT_TURN                 = $0C000405; { Indicate turn over }
+  DIBUTTON_STRATEGYT_MENU                 = $0C0004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIBUTTON_STRATEGYT_ZOOM                 = $0C004406; { Zoom - in / out }
+  DIBUTTON_STRATEGYT_MAP                  = $0C004407; { cycle through map options }
+  DIBUTTON_STRATEGYT_DISPLAY              = $0C004408; { shows next on-screen display options }
+  DIBUTTON_STRATEGYT_LEFT_LINK            = $0C00C4E4; { Fallback sidestep left button }
+  DIBUTTON_STRATEGYT_RIGHT_LINK           = $0C00C4EC; { Fallback sidestep right button }
+  DIBUTTON_STRATEGYT_FORWARD_LINK         = $0C0144E0; { Fallback move forward button }
+  DIBUTTON_STRATEGYT_BACK_LINK            = $0C0144E8; { Fallback move back button }
+  DIBUTTON_STRATEGYT_DEVICE               = $0C0044FE; { Show input device and controls }
+  DIBUTTON_STRATEGYT_PAUSE                = $0C0044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Hunting
+      Hunting                ---*)
+  DIVIRTUAL_SPORTS_HUNTING                = $0D000000;
+  DIAXIS_HUNTING_LATERAL                  = $0D008201; { sidestep left/right }
+  DIAXIS_HUNTING_MOVE                     = $0D010202; { move forward/backwards }
+  DIBUTTON_HUNTING_FIRE                   = $0D000401; { Fire selected weapon }
+  DIBUTTON_HUNTING_AIM                    = $0D000402; { Select aim/move }
+  DIBUTTON_HUNTING_WEAPON                 = $0D000403; { Select next weapon }
+  DIBUTTON_HUNTING_BINOCULAR              = $0D000404; { Look through Binoculars }
+  DIBUTTON_HUNTING_CALL                   = $0D000405; { Make animal call }
+  DIBUTTON_HUNTING_MAP                    = $0D000406; { View Map }
+  DIBUTTON_HUNTING_SPECIAL                = $0D000407; { Special game operation }
+  DIBUTTON_HUNTING_MENU                   = $0D0004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_HUNTING_GLANCE              = $0D004601; { Look around }
+  DIBUTTON_HUNTING_DISPLAY                = $0D004408; { show next on-screen display option }
+  DIAXIS_HUNTING_ROTATE                   = $0D024203; { Turn body left/right }
+  DIBUTTON_HUNTING_CROUCH                 = $0D004409; { Crouch/ Climb / Swim down }
+  DIBUTTON_HUNTING_JUMP                   = $0D00440A; { Jump/ Climb up / Swim up }
+  DIBUTTON_HUNTING_FIRESECONDARY          = $0D00440B; { Alternative fire button }
+  DIBUTTON_HUNTING_LEFT_LINK              = $0D00C4E4; { Fallback sidestep left button }
+  DIBUTTON_HUNTING_RIGHT_LINK             = $0D00C4EC; { Fallback sidestep right button }
+  DIBUTTON_HUNTING_FORWARD_LINK           = $0D0144E0; { Fallback move forward button }
+  DIBUTTON_HUNTING_BACK_LINK              = $0D0144E8; { Fallback move back button }
+  DIBUTTON_HUNTING_ROTATE_LEFT_LINK       = $0D0244E4; { Fallback turn body left button }
+  DIBUTTON_HUNTING_ROTATE_RIGHT_LINK      = $0D0244EC; { Fallback turn body right button }
+  DIBUTTON_HUNTING_DEVICE                 = $0D0044FE; { Show input device and controls }
+  DIBUTTON_HUNTING_PAUSE                  = $0D0044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Fishing
+      Catching Fish is primary objective   ---*)
+  DIVIRTUAL_SPORTS_FISHING                = $0E000000;
+  DIAXIS_FISHING_LATERAL                  = $0E008201; { sidestep left/right }
+  DIAXIS_FISHING_MOVE                     = $0E010202; { move forward/backwards }
+  DIBUTTON_FISHING_CAST                   = $0E000401; { Cast line }
+  DIBUTTON_FISHING_TYPE                   = $0E000402; { Select cast type }
+  DIBUTTON_FISHING_BINOCULAR              = $0E000403; { Look through Binocular }
+  DIBUTTON_FISHING_BAIT                   = $0E000404; { Select type of Bait }
+  DIBUTTON_FISHING_MAP                    = $0E000405; { View Map }
+  DIBUTTON_FISHING_MENU                   = $0E0004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_FISHING_GLANCE              = $0E004601; { Look around }
+  DIBUTTON_FISHING_DISPLAY                = $0E004406; { Show next on-screen display option }
+  DIAXIS_FISHING_ROTATE                   = $0E024203; { Turn character left / right }
+  DIBUTTON_FISHING_CROUCH                 = $0E004407; { Crouch/ Climb / Swim down }
+  DIBUTTON_FISHING_JUMP                   = $0E004408; { Jump/ Climb up / Swim up }
+  DIBUTTON_FISHING_LEFT_LINK              = $0E00C4E4; { Fallback sidestep left button }
+  DIBUTTON_FISHING_RIGHT_LINK             = $0E00C4EC; { Fallback sidestep right button }
+  DIBUTTON_FISHING_FORWARD_LINK           = $0E0144E0; { Fallback move forward button }
+  DIBUTTON_FISHING_BACK_LINK              = $0E0144E8; { Fallback move back button }
+  DIBUTTON_FISHING_ROTATE_LEFT_LINK       = $0E0244E4; { Fallback turn body left button }
+  DIBUTTON_FISHING_ROTATE_RIGHT_LINK      = $0E0244EC; { Fallback turn body right button }
+  DIBUTTON_FISHING_DEVICE                 = $0E0044FE; { Show input device and controls }
+  DIBUTTON_FISHING_PAUSE                  = $0E0044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Baseball - Batting
+      Batter control is primary objective  ---*)
+  DIVIRTUAL_SPORTS_BASEBALL_BAT           = $0F000000;
+  DIAXIS_BASEBALLB_LATERAL                = $0F008201; { Aim left / right }
+  DIAXIS_BASEBALLB_MOVE                   = $0F010202; { Aim up / down }
+  DIBUTTON_BASEBALLB_SELECT               = $0F000401; { cycle through swing options }
+  DIBUTTON_BASEBALLB_NORMAL               = $0F000402; { normal swing }
+  DIBUTTON_BASEBALLB_POWER                = $0F000403; { swing for the fence }
+  DIBUTTON_BASEBALLB_BUNT                 = $0F000404; { bunt }
+  DIBUTTON_BASEBALLB_STEAL                = $0F000405; { Base runner attempts to steal a base }
+  DIBUTTON_BASEBALLB_BURST                = $0F000406; { Base runner invokes burst of speed }
+  DIBUTTON_BASEBALLB_SLIDE                = $0F000407; { Base runner slides into base }
+  DIBUTTON_BASEBALLB_CONTACT              = $0F000408; { Contact swing }
+  DIBUTTON_BASEBALLB_MENU                 = $0F0004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIBUTTON_BASEBALLB_NOSTEAL              = $0F004409; { Base runner goes back to a base }
+  DIBUTTON_BASEBALLB_BOX                  = $0F00440A; { Enter or exit batting box }
+  DIBUTTON_BASEBALLB_LEFT_LINK            = $0F00C4E4; { Fallback sidestep left button }
+  DIBUTTON_BASEBALLB_RIGHT_LINK           = $0F00C4EC; { Fallback sidestep right button }
+  DIBUTTON_BASEBALLB_FORWARD_LINK         = $0F0144E0; { Fallback move forward button }
+  DIBUTTON_BASEBALLB_BACK_LINK            = $0F0144E8; { Fallback move back button }
+  DIBUTTON_BASEBALLB_DEVICE               = $0F0044FE; { Show input device and controls }
+  DIBUTTON_BASEBALLB_PAUSE                = $0F0044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Baseball - Pitching
+      Pitcher control is primary objective   ---*)
+  DIVIRTUAL_SPORTS_BASEBALL_PITCH         = $10000000;
+  DIAXIS_BASEBALLP_LATERAL                = $10008201; { Aim left / right }
+  DIAXIS_BASEBALLP_MOVE                   = $10010202; { Aim up / down }
+  DIBUTTON_BASEBALLP_SELECT               = $10000401; { cycle through pitch selections }
+  DIBUTTON_BASEBALLP_PITCH                = $10000402; { throw pitch }
+  DIBUTTON_BASEBALLP_BASE                 = $10000403; { select base to throw to }
+  DIBUTTON_BASEBALLP_THROW                = $10000404; { throw to base }
+  DIBUTTON_BASEBALLP_FAKE                 = $10000405; { Fake a throw to a base }
+  DIBUTTON_BASEBALLP_MENU                 = $100004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIBUTTON_BASEBALLP_WALK                 = $10004406; { Throw intentional walk / pitch out }
+  DIBUTTON_BASEBALLP_LOOK                 = $10004407; { Look at runners on bases }
+  DIBUTTON_BASEBALLP_LEFT_LINK            = $1000C4E4; { Fallback sidestep left button }
+  DIBUTTON_BASEBALLP_RIGHT_LINK           = $1000C4EC; { Fallback sidestep right button }
+  DIBUTTON_BASEBALLP_FORWARD_LINK         = $100144E0; { Fallback move forward button }
+  DIBUTTON_BASEBALLP_BACK_LINK            = $100144E8; { Fallback move back button }
+  DIBUTTON_BASEBALLP_DEVICE               = $100044FE; { Show input device and controls }
+  DIBUTTON_BASEBALLP_PAUSE                = $100044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Baseball - Fielding
+      Fielder control is primary objective  ---*)
+  DIVIRTUAL_SPORTS_BASEBALL_FIELD         = $11000000;
+  DIAXIS_BASEBALLF_LATERAL                = $11008201; { Aim left / right }
+  DIAXIS_BASEBALLF_MOVE                   = $11010202; { Aim up / down }
+  DIBUTTON_BASEBALLF_NEAREST              = $11000401; { Switch to fielder nearest to the ball }
+  DIBUTTON_BASEBALLF_THROW1               = $11000402; { Make conservative throw }
+  DIBUTTON_BASEBALLF_THROW2               = $11000403; { Make aggressive throw }
+  DIBUTTON_BASEBALLF_BURST                = $11000404; { Invoke burst of speed }
+  DIBUTTON_BASEBALLF_JUMP                 = $11000405; { Jump to catch ball }
+  DIBUTTON_BASEBALLF_DIVE                 = $11000406; { Dive to catch ball }
+  DIBUTTON_BASEBALLF_MENU                 = $110004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIBUTTON_BASEBALLF_SHIFTIN              = $11004407; { Shift the infield positioning }
+  DIBUTTON_BASEBALLF_SHIFTOUT             = $11004408; { Shift the outfield positioning }
+  DIBUTTON_BASEBALLF_AIM_LEFT_LINK        = $1100C4E4; { Fallback aim left button }
+  DIBUTTON_BASEBALLF_AIM_RIGHT_LINK       = $1100C4EC; { Fallback aim right button }
+  DIBUTTON_BASEBALLF_FORWARD_LINK         = $110144E0; { Fallback move forward button }
+  DIBUTTON_BASEBALLF_BACK_LINK            = $110144E8; { Fallback move back button }
+  DIBUTTON_BASEBALLF_DEVICE               = $110044FE; { Show input device and controls }
+  DIBUTTON_BASEBALLF_PAUSE                = $110044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Basketball - Offense
+      Offense  ---*)
+  DIVIRTUAL_SPORTS_BASKETBALL_OFFENSE     = $12000000;
+  DIAXIS_BBALLO_LATERAL                   = $12008201; { left / right }
+  DIAXIS_BBALLO_MOVE                      = $12010202; { up / down }
+  DIBUTTON_BBALLO_SHOOT                   = $12000401; { shoot basket }
+  DIBUTTON_BBALLO_DUNK                    = $12000402; { dunk basket }
+  DIBUTTON_BBALLO_PASS                    = $12000403; { throw pass }
+  DIBUTTON_BBALLO_FAKE                    = $12000404; { fake shot or pass }
+  DIBUTTON_BBALLO_SPECIAL                 = $12000405; { apply special move }
+  DIBUTTON_BBALLO_PLAYER                  = $12000406; { select next player }
+  DIBUTTON_BBALLO_BURST                   = $12000407; { invoke burst }
+  DIBUTTON_BBALLO_CALL                    = $12000408; { call for ball / pass to me }
+  DIBUTTON_BBALLO_MENU                    = $120004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_BBALLO_GLANCE               = $12004601; { scroll view }
+  DIBUTTON_BBALLO_SCREEN                  = $12004409; { Call for screen }
+  DIBUTTON_BBALLO_PLAY                    = $1200440A; { Call for specific offensive play }
+  DIBUTTON_BBALLO_JAB                     = $1200440B; { Initiate fake drive to basket }
+  DIBUTTON_BBALLO_POST                    = $1200440C; { Perform post move }
+  DIBUTTON_BBALLO_TIMEOUT                 = $1200440D; { Time Out }
+  DIBUTTON_BBALLO_SUBSTITUTE              = $1200440E; { substitute one player for another }
+  DIBUTTON_BBALLO_LEFT_LINK               = $1200C4E4; { Fallback sidestep left button }
+  DIBUTTON_BBALLO_RIGHT_LINK              = $1200C4EC; { Fallback sidestep right button }
+  DIBUTTON_BBALLO_FORWARD_LINK            = $120144E0; { Fallback move forward button }
+  DIBUTTON_BBALLO_BACK_LINK               = $120144E8; { Fallback move back button }
+  DIBUTTON_BBALLO_DEVICE                  = $120044FE; { Show input device and controls }
+  DIBUTTON_BBALLO_PAUSE                   = $120044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Basketball - Defense
+      Defense  ---*)
+  DIVIRTUAL_SPORTS_BASKETBALL_DEFENSE     = $13000000;
+  DIAXIS_BBALLD_LATERAL                   = $13008201; { left / right }
+  DIAXIS_BBALLD_MOVE                      = $13010202; { up / down }
+  DIBUTTON_BBALLD_JUMP                    = $13000401; { jump to block shot }
+  DIBUTTON_BBALLD_STEAL                   = $13000402; { attempt to steal ball }
+  DIBUTTON_BBALLD_FAKE                    = $13000403; { fake block or steal }
+  DIBUTTON_BBALLD_SPECIAL                 = $13000404; { apply special move }
+  DIBUTTON_BBALLD_PLAYER                  = $13000405; { select next player }
+  DIBUTTON_BBALLD_BURST                   = $13000406; { invoke burst }
+  DIBUTTON_BBALLD_PLAY                    = $13000407; { call for specific defensive play }
+  DIBUTTON_BBALLD_MENU                    = $130004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_BBALLD_GLANCE               = $13004601; { scroll view }
+  DIBUTTON_BBALLD_TIMEOUT                 = $13004408; { Time Out }
+  DIBUTTON_BBALLD_SUBSTITUTE              = $13004409; { substitute one player for another }
+  DIBUTTON_BBALLD_LEFT_LINK               = $1300C4E4; { Fallback sidestep left button }
+  DIBUTTON_BBALLD_RIGHT_LINK              = $1300C4EC; { Fallback sidestep right button }
+  DIBUTTON_BBALLD_FORWARD_LINK            = $130144E0; { Fallback move forward button }
+  DIBUTTON_BBALLD_BACK_LINK               = $130144E8; { Fallback move back button }
+  DIBUTTON_BBALLD_DEVICE                  = $130044FE; { Show input device and controls }
+  DIBUTTON_BBALLD_PAUSE                   = $130044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Football - Play
+      Play selection  ---*)
+  DIVIRTUAL_SPORTS_FOOTBALL_FIELD         = $14000000;
+  DIBUTTON_FOOTBALLP_PLAY                 = $14000401; { cycle through available plays }
+  DIBUTTON_FOOTBALLP_SELECT               = $14000402; { select play }
+  DIBUTTON_FOOTBALLP_HELP                 = $14000403; { Bring up pop-up help }
+  DIBUTTON_FOOTBALLP_MENU                 = $140004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIBUTTON_FOOTBALLP_DEVICE               = $140044FE; { Show input device and controls }
+  DIBUTTON_FOOTBALLP_PAUSE                = $140044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Football - QB
+      Offense: Quarterback / Kicker  ---*)
+  DIVIRTUAL_SPORTS_FOOTBALL_QBCK          = $15000000;
+  DIAXIS_FOOTBALLQ_LATERAL                = $15008201; { Move / Aim: left / right }
+  DIAXIS_FOOTBALLQ_MOVE                   = $15010202; { Move / Aim: up / down }
+  DIBUTTON_FOOTBALLQ_SELECT               = $15000401; { Select }
+  DIBUTTON_FOOTBALLQ_SNAP                 = $15000402; { snap ball - start play }
+  DIBUTTON_FOOTBALLQ_JUMP                 = $15000403; { jump over defender }
+  DIBUTTON_FOOTBALLQ_SLIDE                = $15000404; { Dive/Slide }
+  DIBUTTON_FOOTBALLQ_PASS                 = $15000405; { throws pass to receiver }
+  DIBUTTON_FOOTBALLQ_FAKE                 = $15000406; { pump fake pass or fake kick }
+  DIBUTTON_FOOTBALLQ_MENU                 = $150004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIBUTTON_FOOTBALLQ_FAKESNAP             = $15004407; { Fake snap  }
+  DIBUTTON_FOOTBALLQ_MOTION               = $15004408; { Send receivers in motion }
+  DIBUTTON_FOOTBALLQ_AUDIBLE              = $15004409; { Change offensive play at line of scrimmage }
+  DIBUTTON_FOOTBALLQ_LEFT_LINK            = $1500C4E4; { Fallback sidestep left button }
+  DIBUTTON_FOOTBALLQ_RIGHT_LINK           = $1500C4EC; { Fallback sidestep right button }
+  DIBUTTON_FOOTBALLQ_FORWARD_LINK         = $150144E0; { Fallback move forward button }
+  DIBUTTON_FOOTBALLQ_BACK_LINK            = $150144E8; { Fallback move back button }
+  DIBUTTON_FOOTBALLQ_DEVICE               = $150044FE; { Show input device and controls }
+  DIBUTTON_FOOTBALLQ_PAUSE                = $150044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Football - Offense
+      Offense - Runner  ---*)
+  DIVIRTUAL_SPORTS_FOOTBALL_OFFENSE       = $16000000;
+  DIAXIS_FOOTBALLO_LATERAL                = $16008201; { Move / Aim: left / right }
+  DIAXIS_FOOTBALLO_MOVE                   = $16010202; { Move / Aim: up / down }
+  DIBUTTON_FOOTBALLO_JUMP                 = $16000401; { jump or hurdle over defender }
+  DIBUTTON_FOOTBALLO_LEFTARM              = $16000402; { holds out left arm }
+  DIBUTTON_FOOTBALLO_RIGHTARM             = $16000403; { holds out right arm }
+  DIBUTTON_FOOTBALLO_THROW                = $16000404; { throw pass or lateral ball to another runner }
+  DIBUTTON_FOOTBALLO_SPIN                 = $16000405; { Spin to avoid defenders }
+  DIBUTTON_FOOTBALLO_MENU                 = $160004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIBUTTON_FOOTBALLO_JUKE                 = $16004406; { Use special move to avoid defenders }
+  DIBUTTON_FOOTBALLO_SHOULDER             = $16004407; { Lower shoulder to run over defenders }
+  DIBUTTON_FOOTBALLO_TURBO                = $16004408; { Speed burst past defenders }
+  DIBUTTON_FOOTBALLO_DIVE                 = $16004409; { Dive over defenders }
+  DIBUTTON_FOOTBALLO_ZOOM                 = $1600440A; { Zoom view in / out }
+  DIBUTTON_FOOTBALLO_SUBSTITUTE           = $1600440B; { substitute one player for another }
+  DIBUTTON_FOOTBALLO_LEFT_LINK            = $1600C4E4; { Fallback sidestep left button }
+  DIBUTTON_FOOTBALLO_RIGHT_LINK           = $1600C4EC; { Fallback sidestep right button }
+  DIBUTTON_FOOTBALLO_FORWARD_LINK         = $160144E0; { Fallback move forward button }
+  DIBUTTON_FOOTBALLO_BACK_LINK            = $160144E8; { Fallback move back button }
+  DIBUTTON_FOOTBALLO_DEVICE               = $160044FE; { Show input device and controls }
+  DIBUTTON_FOOTBALLO_PAUSE                = $160044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Football - Defense
+      Defense     ---*)
+  DIVIRTUAL_SPORTS_FOOTBALL_DEFENSE       = $17000000;
+  DIAXIS_FOOTBALLD_LATERAL                = $17008201; { Move / Aim: left / right }
+  DIAXIS_FOOTBALLD_MOVE                   = $17010202; { Move / Aim: up / down }
+  DIBUTTON_FOOTBALLD_PLAY                 = $17000401; { cycle through available plays }
+  DIBUTTON_FOOTBALLD_SELECT               = $17000402; { select player closest to the ball }
+  DIBUTTON_FOOTBALLD_JUMP                 = $17000403; { jump to intercept or block }
+  DIBUTTON_FOOTBALLD_TACKLE               = $17000404; { tackler runner }
+  DIBUTTON_FOOTBALLD_FAKE                 = $17000405; { hold down to fake tackle or intercept }
+  DIBUTTON_FOOTBALLD_SUPERTACKLE          = $17000406; { Initiate special tackle }
+  DIBUTTON_FOOTBALLD_MENU                 = $170004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIBUTTON_FOOTBALLD_SPIN                 = $17004407; { Spin to beat offensive line }
+  DIBUTTON_FOOTBALLD_SWIM                 = $17004408; { Swim to beat the offensive line }
+  DIBUTTON_FOOTBALLD_BULLRUSH             = $17004409; { Bull rush the offensive line }
+  DIBUTTON_FOOTBALLD_RIP                  = $1700440A; { Rip the offensive line }
+  DIBUTTON_FOOTBALLD_AUDIBLE              = $1700440B; { Change defensive play at the line of scrimmage }
+  DIBUTTON_FOOTBALLD_ZOOM                 = $1700440C; { Zoom view in / out }
+  DIBUTTON_FOOTBALLD_SUBSTITUTE           = $1700440D; { substitute one player for another }
+  DIBUTTON_FOOTBALLD_LEFT_LINK            = $1700C4E4; { Fallback sidestep left button }
+  DIBUTTON_FOOTBALLD_RIGHT_LINK           = $1700C4EC; { Fallback sidestep right button }
+  DIBUTTON_FOOTBALLD_FORWARD_LINK         = $170144E0; { Fallback move forward button }
+  DIBUTTON_FOOTBALLD_BACK_LINK            = $170144E8; { Fallback move back button }
+  DIBUTTON_FOOTBALLD_DEVICE               = $170044FE; { Show input device and controls }
+  DIBUTTON_FOOTBALLD_PAUSE                = $170044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Golf
+                                ---*)
+  DIVIRTUAL_SPORTS_GOLF                   = $18000000;
+  DIAXIS_GOLF_LATERAL                     = $18008201; { Move / Aim: left / right }
+  DIAXIS_GOLF_MOVE                        = $18010202; { Move / Aim: up / down }
+  DIBUTTON_GOLF_SWING                     = $18000401; { swing club }
+  DIBUTTON_GOLF_SELECT                    = $18000402; { cycle between: club / swing strength / ball arc / ball spin }
+  DIBUTTON_GOLF_UP                        = $18000403; { increase selection }
+  DIBUTTON_GOLF_DOWN                      = $18000404; { decrease selection }
+  DIBUTTON_GOLF_TERRAIN                   = $18000405; { shows terrain detail }
+  DIBUTTON_GOLF_FLYBY                     = $18000406; { view the hole via a flyby }
+  DIBUTTON_GOLF_MENU                      = $180004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_GOLF_SCROLL                 = $18004601; { scroll view }
+  DIBUTTON_GOLF_ZOOM                      = $18004407; { Zoom view in / out }
+  DIBUTTON_GOLF_TIMEOUT                   = $18004408; { Call for time out }
+  DIBUTTON_GOLF_SUBSTITUTE                = $18004409; { substitute one player for another }
+  DIBUTTON_GOLF_LEFT_LINK                 = $1800C4E4; { Fallback sidestep left button }
+  DIBUTTON_GOLF_RIGHT_LINK                = $1800C4EC; { Fallback sidestep right button }
+  DIBUTTON_GOLF_FORWARD_LINK              = $180144E0; { Fallback move forward button }
+  DIBUTTON_GOLF_BACK_LINK                 = $180144E8; { Fallback move back button }
+  DIBUTTON_GOLF_DEVICE                    = $180044FE; { Show input device and controls }
+  DIBUTTON_GOLF_PAUSE                     = $180044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Hockey - Offense
+      Offense       ---*)
+  DIVIRTUAL_SPORTS_HOCKEY_OFFENSE         = $19000000;
+  DIAXIS_HOCKEYO_LATERAL                  = $19008201; { Move / Aim: left / right }
+  DIAXIS_HOCKEYO_MOVE                     = $19010202; { Move / Aim: up / down }
+  DIBUTTON_HOCKEYO_SHOOT                  = $19000401; { Shoot }
+  DIBUTTON_HOCKEYO_PASS                   = $19000402; { pass the puck }
+  DIBUTTON_HOCKEYO_BURST                  = $19000403; { invoke speed burst }
+  DIBUTTON_HOCKEYO_SPECIAL                = $19000404; { invoke special move }
+  DIBUTTON_HOCKEYO_FAKE                   = $19000405; { hold down to fake pass or kick }
+  DIBUTTON_HOCKEYO_MENU                   = $190004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_HOCKEYO_SCROLL              = $19004601; { scroll view }
+  DIBUTTON_HOCKEYO_ZOOM                   = $19004406; { Zoom view in / out }
+  DIBUTTON_HOCKEYO_STRATEGY               = $19004407; { Invoke coaching menu for strategy help }
+  DIBUTTON_HOCKEYO_TIMEOUT                = $19004408; { Call for time out }
+  DIBUTTON_HOCKEYO_SUBSTITUTE             = $19004409; { substitute one player for another }
+  DIBUTTON_HOCKEYO_LEFT_LINK              = $1900C4E4; { Fallback sidestep left button }
+  DIBUTTON_HOCKEYO_RIGHT_LINK             = $1900C4EC; { Fallback sidestep right button }
+  DIBUTTON_HOCKEYO_FORWARD_LINK           = $190144E0; { Fallback move forward button }
+  DIBUTTON_HOCKEYO_BACK_LINK              = $190144E8; { Fallback move back button }
+  DIBUTTON_HOCKEYO_DEVICE                 = $190044FE; { Show input device and controls }
+  DIBUTTON_HOCKEYO_PAUSE                  = $190044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Hockey - Defense
+      Defense       ---*)
+  DIVIRTUAL_SPORTS_HOCKEY_DEFENSE         = $1A000000;
+  DIAXIS_HOCKEYD_LATERAL                  = $1A008201; { Move / Aim: left / right }
+  DIAXIS_HOCKEYD_MOVE                     = $1A010202; { Move / Aim: up / down }
+  DIBUTTON_HOCKEYD_PLAYER                 = $1A000401; { control player closest to the puck }
+  DIBUTTON_HOCKEYD_STEAL                  = $1A000402; { attempt steal }
+  DIBUTTON_HOCKEYD_BURST                  = $1A000403; { speed burst or body check }
+  DIBUTTON_HOCKEYD_BLOCK                  = $1A000404; { block puck }
+  DIBUTTON_HOCKEYD_FAKE                   = $1A000405; { hold down to fake tackle or intercept }
+  DIBUTTON_HOCKEYD_MENU                   = $1A0004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_HOCKEYD_SCROLL              = $1A004601; { scroll view }
+  DIBUTTON_HOCKEYD_ZOOM                   = $1A004406; { Zoom view in / out }
+  DIBUTTON_HOCKEYD_STRATEGY               = $1A004407; { Invoke coaching menu for strategy help }
+  DIBUTTON_HOCKEYD_TIMEOUT                = $1A004408; { Call for time out }
+  DIBUTTON_HOCKEYD_SUBSTITUTE             = $1A004409; { substitute one player for another }
+  DIBUTTON_HOCKEYD_LEFT_LINK              = $1A00C4E4; { Fallback sidestep left button }
+  DIBUTTON_HOCKEYD_RIGHT_LINK             = $1A00C4EC; { Fallback sidestep right button }
+  DIBUTTON_HOCKEYD_FORWARD_LINK           = $1A0144E0; { Fallback move forward button }
+  DIBUTTON_HOCKEYD_BACK_LINK              = $1A0144E8; { Fallback move back button }
+  DIBUTTON_HOCKEYD_DEVICE                 = $1A0044FE; { Show input device and controls }
+  DIBUTTON_HOCKEYD_PAUSE                  = $1A0044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Hockey - Goalie
+      Goal tending  ---*)
+  DIVIRTUAL_SPORTS_HOCKEY_GOALIE          = $1B000000;
+  DIAXIS_HOCKEYG_LATERAL                  = $1B008201; { Move / Aim: left / right }
+  DIAXIS_HOCKEYG_MOVE                     = $1B010202; { Move / Aim: up / down }
+  DIBUTTON_HOCKEYG_PASS                   = $1B000401; { pass puck }
+  DIBUTTON_HOCKEYG_POKE                   = $1B000402; { poke / check / hack }
+  DIBUTTON_HOCKEYG_STEAL                  = $1B000403; { attempt steal }
+  DIBUTTON_HOCKEYG_BLOCK                  = $1B000404; { block puck }
+  DIBUTTON_HOCKEYG_MENU                   = $1B0004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_HOCKEYG_SCROLL              = $1B004601; { scroll view }
+  DIBUTTON_HOCKEYG_ZOOM                   = $1B004405; { Zoom view in / out }
+  DIBUTTON_HOCKEYG_STRATEGY               = $1B004406; { Invoke coaching menu for strategy help }
+  DIBUTTON_HOCKEYG_TIMEOUT                = $1B004407; { Call for time out }
+  DIBUTTON_HOCKEYG_SUBSTITUTE             = $1B004408; { substitute one player for another }
+  DIBUTTON_HOCKEYG_LEFT_LINK              = $1B00C4E4; { Fallback sidestep left button }
+  DIBUTTON_HOCKEYG_RIGHT_LINK             = $1B00C4EC; { Fallback sidestep right button }
+  DIBUTTON_HOCKEYG_FORWARD_LINK           = $1B0144E0; { Fallback move forward button }
+  DIBUTTON_HOCKEYG_BACK_LINK              = $1B0144E8; { Fallback move back button }
+  DIBUTTON_HOCKEYG_DEVICE                 = $1B0044FE; { Show input device and controls }
+  DIBUTTON_HOCKEYG_PAUSE                  = $1B0044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Mountain Biking
+                     ---*)
+  DIVIRTUAL_SPORTS_BIKING_MOUNTAIN        = $1C000000;
+  DIAXIS_BIKINGM_TURN                     = $1C008201; { left / right }
+  DIAXIS_BIKINGM_PEDAL                    = $1C010202; { Pedal faster / slower / brake }
+  DIBUTTON_BIKINGM_JUMP                   = $1C000401; { jump over obstacle }
+  DIBUTTON_BIKINGM_CAMERA                 = $1C000402; { switch camera view }
+  DIBUTTON_BIKINGM_SPECIAL1               = $1C000403; { perform first special move }
+  DIBUTTON_BIKINGM_SELECT                 = $1C000404; { Select }
+  DIBUTTON_BIKINGM_SPECIAL2               = $1C000405; { perform second special move }
+  DIBUTTON_BIKINGM_MENU                   = $1C0004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_BIKINGM_SCROLL              = $1C004601; { scroll view }
+  DIBUTTON_BIKINGM_ZOOM                   = $1C004406; { Zoom view in / out }
+  DIAXIS_BIKINGM_BRAKE                    = $1C044203; { Brake axis  }
+  DIBUTTON_BIKINGM_LEFT_LINK              = $1C00C4E4; { Fallback turn left button }
+  DIBUTTON_BIKINGM_RIGHT_LINK             = $1C00C4EC; { Fallback turn right button }
+  DIBUTTON_BIKINGM_FASTER_LINK            = $1C0144E0; { Fallback pedal faster button }
+  DIBUTTON_BIKINGM_SLOWER_LINK            = $1C0144E8; { Fallback pedal slower button }
+  DIBUTTON_BIKINGM_BRAKE_BUTTON_LINK      = $1C0444E8; { Fallback brake button }
+  DIBUTTON_BIKINGM_DEVICE                 = $1C0044FE; { Show input device and controls }
+  DIBUTTON_BIKINGM_PAUSE                  = $1C0044FC; { Start / Pause / Restart game }
+
+(*--- Sports: Skiing / Snowboarding / Skateboarding
+        ---*)
+  DIVIRTUAL_SPORTS_SKIING                 = $1D000000;
+  DIAXIS_SKIING_TURN                      = $1D008201; { left / right }
+  DIAXIS_SKIING_SPEED                     = $1D010202; { faster / slower }
+  DIBUTTON_SKIING_JUMP                    = $1D000401; { Jump }
+  DIBUTTON_SKIING_CROUCH                  = $1D000402; { crouch down }
+  DIBUTTON_SKIING_CAMERA                  = $1D000403; { switch camera view }
+  DIBUTTON_SKIING_SPECIAL1                = $1D000404; { perform first special move }
+  DIBUTTON_SKIING_SELECT                  = $1D000405; { Select }
+  DIBUTTON_SKIING_SPECIAL2                = $1D000406; { perform second special move }
+  DIBUTTON_SKIING_MENU                    = $1D0004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_SKIING_GLANCE               = $1D004601; { scroll view }
+  DIBUTTON_SKIING_ZOOM                    = $1D004407; { Zoom view in / out }
+  DIBUTTON_SKIING_LEFT_LINK               = $1D00C4E4; { Fallback turn left button }
+  DIBUTTON_SKIING_RIGHT_LINK              = $1D00C4EC; { Fallback turn right button }
+  DIBUTTON_SKIING_FASTER_LINK             = $1D0144E0; { Fallback increase speed button }
+  DIBUTTON_SKIING_SLOWER_LINK             = $1D0144E8; { Fallback decrease speed button }
+  DIBUTTON_SKIING_DEVICE                  = $1D0044FE; { Show input device and controls }
+  DIBUTTON_SKIING_PAUSE                   = $1D0044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Soccer - Offense
+      Offense       ---*)
+  DIVIRTUAL_SPORTS_SOCCER_OFFENSE         = $1E000000;
+  DIAXIS_SOCCERO_LATERAL                  = $1E008201; { Move / Aim: left / right }
+  DIAXIS_SOCCERO_MOVE                     = $1E010202; { Move / Aim: up / down }
+  DIAXIS_SOCCERO_BEND                     = $1E018203; { Bend to soccer shot/pass }
+  DIBUTTON_SOCCERO_SHOOT                  = $1E000401; { Shoot the ball }
+  DIBUTTON_SOCCERO_PASS                   = $1E000402; { Pass  }
+  DIBUTTON_SOCCERO_FAKE                   = $1E000403; { Fake }
+  DIBUTTON_SOCCERO_PLAYER                 = $1E000404; { Select next player }
+  DIBUTTON_SOCCERO_SPECIAL1               = $1E000405; { Apply special move }
+  DIBUTTON_SOCCERO_SELECT                 = $1E000406; { Select special move }
+  DIBUTTON_SOCCERO_MENU                   = $1E0004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_SOCCERO_GLANCE              = $1E004601; { scroll view }
+  DIBUTTON_SOCCERO_SUBSTITUTE             = $1E004407; { Substitute one player for another }
+  DIBUTTON_SOCCERO_SHOOTLOW               = $1E004408; { Shoot the ball low }
+  DIBUTTON_SOCCERO_SHOOTHIGH              = $1E004409; { Shoot the ball high }
+  DIBUTTON_SOCCERO_PASSTHRU               = $1E00440A; { Make a thru pass }
+  DIBUTTON_SOCCERO_SPRINT                 = $1E00440B; { Sprint / turbo boost }
+  DIBUTTON_SOCCERO_CONTROL                = $1E00440C; { Obtain control of the ball }
+  DIBUTTON_SOCCERO_HEAD                   = $1E00440D; { Attempt to head the ball }
+  DIBUTTON_SOCCERO_LEFT_LINK              = $1E00C4E4; { Fallback sidestep left button }
+  DIBUTTON_SOCCERO_RIGHT_LINK             = $1E00C4EC; { Fallback sidestep right button }
+  DIBUTTON_SOCCERO_FORWARD_LINK           = $1E0144E0; { Fallback move forward button }
+  DIBUTTON_SOCCERO_BACK_LINK              = $1E0144E8; { Fallback move back button }
+  DIBUTTON_SOCCERO_DEVICE                 = $1E0044FE; { Show input device and controls }
+  DIBUTTON_SOCCERO_PAUSE                  = $1E0044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Soccer - Defense
+      Defense       ---*)
+  DIVIRTUAL_SPORTS_SOCCER_DEFENSE         = $1F000000;
+  DIAXIS_SOCCERD_LATERAL                  = $1F008201; { Move / Aim: left / right }
+  DIAXIS_SOCCERD_MOVE                     = $1F010202; { Move / Aim: up / down }
+  DIBUTTON_SOCCERD_BLOCK                  = $1F000401; { Attempt to block shot }
+  DIBUTTON_SOCCERD_STEAL                  = $1F000402; { Attempt to steal ball }
+  DIBUTTON_SOCCERD_FAKE                   = $1F000403; { Fake a block or a steal }
+  DIBUTTON_SOCCERD_PLAYER                 = $1F000404; { Select next player }
+  DIBUTTON_SOCCERD_SPECIAL                = $1F000405; { Apply special move }
+  DIBUTTON_SOCCERD_SELECT                 = $1F000406; { Select special move }
+  DIBUTTON_SOCCERD_SLIDE                  = $1F000407; { Attempt a slide tackle }
+  DIBUTTON_SOCCERD_MENU                   = $1F0004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_SOCCERD_GLANCE              = $1F004601; { scroll view }
+  DIBUTTON_SOCCERD_FOUL                   = $1F004408; { Initiate a foul / hard-foul }
+  DIBUTTON_SOCCERD_HEAD                   = $1F004409; { Attempt a Header }
+  DIBUTTON_SOCCERD_CLEAR                  = $1F00440A; { Attempt to clear the ball down the field }
+  DIBUTTON_SOCCERD_GOALIECHARGE           = $1F00440B; { Make the goalie charge out of the box }
+  DIBUTTON_SOCCERD_SUBSTITUTE             = $1F00440C; { Substitute one player for another }
+  DIBUTTON_SOCCERD_LEFT_LINK              = $1F00C4E4; { Fallback sidestep left button }
+  DIBUTTON_SOCCERD_RIGHT_LINK             = $1F00C4EC; { Fallback sidestep right button }
+  DIBUTTON_SOCCERD_FORWARD_LINK           = $1F0144E0; { Fallback move forward button }
+  DIBUTTON_SOCCERD_BACK_LINK              = $1F0144E8; { Fallback move back button }
+  DIBUTTON_SOCCERD_DEVICE                 = $1F0044FE; { Show input device and controls }
+  DIBUTTON_SOCCERD_PAUSE                  = $1F0044FC; { Start / Pause / Restart game }
+
+(*--- Sports - Racquet
+      Tennis - Table-Tennis - Squash   ---*)
+  DIVIRTUAL_SPORTS_RACQUET                = $20000000;
+  DIAXIS_RACQUET_LATERAL                  = $20008201; { Move / Aim: left / right }
+  DIAXIS_RACQUET_MOVE                     = $20010202; { Move / Aim: up / down }
+  DIBUTTON_RACQUET_SWING                  = $20000401; { Swing racquet }
+  DIBUTTON_RACQUET_BACKSWING              = $20000402; { Swing backhand }
+  DIBUTTON_RACQUET_SMASH                  = $20000403; { Smash shot }
+  DIBUTTON_RACQUET_SPECIAL                = $20000404; { Special shot }
+  DIBUTTON_RACQUET_SELECT                 = $20000405; { Select special shot }
+  DIBUTTON_RACQUET_MENU                   = $200004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_RACQUET_GLANCE              = $20004601; { scroll view }
+  DIBUTTON_RACQUET_TIMEOUT                = $20004406; { Call for time out }
+  DIBUTTON_RACQUET_SUBSTITUTE             = $20004407; { Substitute one player for another }
+  DIBUTTON_RACQUET_LEFT_LINK              = $2000C4E4; { Fallback sidestep left button }
+  DIBUTTON_RACQUET_RIGHT_LINK             = $2000C4EC; { Fallback sidestep right button }
+  DIBUTTON_RACQUET_FORWARD_LINK           = $200144E0; { Fallback move forward button }
+  DIBUTTON_RACQUET_BACK_LINK              = $200144E8; { Fallback move back button }
+  DIBUTTON_RACQUET_DEVICE                 = $200044FE; { Show input device and controls }
+  DIBUTTON_RACQUET_PAUSE                  = $200044FC; { Start / Pause / Restart game }
+
+(*--- Arcade- 2D
+      Side to Side movement        ---*)
+  DIVIRTUAL_ARCADE_SIDE2SIDE              = $21000000;
+  DIAXIS_ARCADES_LATERAL                  = $21008201; { left / right }
+  DIAXIS_ARCADES_MOVE                     = $21010202; { up / down }
+  DIBUTTON_ARCADES_THROW                  = $21000401; { throw object }
+  DIBUTTON_ARCADES_CARRY                  = $21000402; { carry object }
+  DIBUTTON_ARCADES_ATTACK                 = $21000403; { attack }
+  DIBUTTON_ARCADES_SPECIAL                = $21000404; { apply special move }
+  DIBUTTON_ARCADES_SELECT                 = $21000405; { select special move }
+  DIBUTTON_ARCADES_MENU                   = $210004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_ARCADES_VIEW                = $21004601; { scroll view left / right / up / down }
+  DIBUTTON_ARCADES_LEFT_LINK              = $2100C4E4; { Fallback sidestep left button }
+  DIBUTTON_ARCADES_RIGHT_LINK             = $2100C4EC; { Fallback sidestep right button }
+  DIBUTTON_ARCADES_FORWARD_LINK           = $210144E0; { Fallback move forward button }
+  DIBUTTON_ARCADES_BACK_LINK              = $210144E8; { Fallback move back button }
+  DIBUTTON_ARCADES_VIEW_UP_LINK           = $2107C4E0; { Fallback scroll view up button }
+  DIBUTTON_ARCADES_VIEW_DOWN_LINK         = $2107C4E8; { Fallback scroll view down button }
+  DIBUTTON_ARCADES_VIEW_LEFT_LINK         = $2107C4E4; { Fallback scroll view left button }
+  DIBUTTON_ARCADES_VIEW_RIGHT_LINK        = $2107C4EC; { Fallback scroll view right button }
+  DIBUTTON_ARCADES_DEVICE                 = $210044FE; { Show input device and controls }
+  DIBUTTON_ARCADES_PAUSE                  = $210044FC; { Start / Pause / Restart game }
+
+(*--- Arcade - Platform Game
+      Character moves around on screen  ---*)
+  DIVIRTUAL_ARCADE_PLATFORM               = $22000000;
+  DIAXIS_ARCADEP_LATERAL                  = $22008201; { Left / right }
+  DIAXIS_ARCADEP_MOVE                     = $22010202; { Up / down }
+  DIBUTTON_ARCADEP_JUMP                   = $22000401; { Jump }
+  DIBUTTON_ARCADEP_FIRE                   = $22000402; { Fire }
+  DIBUTTON_ARCADEP_CROUCH                 = $22000403; { Crouch }
+  DIBUTTON_ARCADEP_SPECIAL                = $22000404; { Apply special move }
+  DIBUTTON_ARCADEP_SELECT                 = $22000405; { Select special move }
+  DIBUTTON_ARCADEP_MENU                   = $220004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_ARCADEP_VIEW                = $22004601; { Scroll view }
+  DIBUTTON_ARCADEP_FIRESECONDARY          = $22004406; { Alternative fire button }
+  DIBUTTON_ARCADEP_LEFT_LINK              = $2200C4E4; { Fallback sidestep left button }
+  DIBUTTON_ARCADEP_RIGHT_LINK             = $2200C4EC; { Fallback sidestep right button }
+  DIBUTTON_ARCADEP_FORWARD_LINK           = $220144E0; { Fallback move forward button }
+  DIBUTTON_ARCADEP_BACK_LINK              = $220144E8; { Fallback move back button }
+  DIBUTTON_ARCADEP_VIEW_UP_LINK           = $2207C4E0; { Fallback scroll view up button }
+  DIBUTTON_ARCADEP_VIEW_DOWN_LINK         = $2207C4E8; { Fallback scroll view down button }
+  DIBUTTON_ARCADEP_VIEW_LEFT_LINK         = $2207C4E4; { Fallback scroll view left button }
+  DIBUTTON_ARCADEP_VIEW_RIGHT_LINK        = $2207C4EC; { Fallback scroll view right button }
+  DIBUTTON_ARCADEP_DEVICE                 = $220044FE; { Show input device and controls }
+  DIBUTTON_ARCADEP_PAUSE                  = $220044FC; { Start / Pause / Restart game }
+
+(*--- CAD - 2D Object Control
+      Controls to select and move objects in 2D  ---*)
+  DIVIRTUAL_CAD_2DCONTROL                 = $23000000;
+  DIAXIS_2DCONTROL_LATERAL                = $23008201; { Move view left / right }
+  DIAXIS_2DCONTROL_MOVE                   = $23010202; { Move view up / down }
+  DIAXIS_2DCONTROL_INOUT                  = $23018203; { Zoom - in / out }
+  DIBUTTON_2DCONTROL_SELECT               = $23000401; { Select Object }
+  DIBUTTON_2DCONTROL_SPECIAL1             = $23000402; { Do first special operation }
+  DIBUTTON_2DCONTROL_SPECIAL              = $23000403; { Select special operation }
+  DIBUTTON_2DCONTROL_SPECIAL2             = $23000404; { Do second special operation }
+  DIBUTTON_2DCONTROL_MENU                 = $230004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_2DCONTROL_HATSWITCH         = $23004601; { Hat switch }
+  DIAXIS_2DCONTROL_ROTATEZ                = $23024204; { Rotate view clockwise / counterclockwise }
+  DIBUTTON_2DCONTROL_DISPLAY              = $23004405; { Shows next on-screen display options }
+  DIBUTTON_2DCONTROL_DEVICE               = $230044FE; { Show input device and controls }
+  DIBUTTON_2DCONTROL_PAUSE                = $230044FC; { Start / Pause / Restart game }
+
+(*--- CAD - 3D object control
+      Controls to select and move objects within a 3D environment  ---*)
+  DIVIRTUAL_CAD_3DCONTROL                 = $24000000;
+  DIAXIS_3DCONTROL_LATERAL                = $24008201; { Move view left / right }
+  DIAXIS_3DCONTROL_MOVE                   = $24010202; { Move view up / down }
+  DIAXIS_3DCONTROL_INOUT                  = $24018203; { Zoom - in / out }
+  DIBUTTON_3DCONTROL_SELECT               = $24000401; { Select Object }
+  DIBUTTON_3DCONTROL_SPECIAL1             = $24000402; { Do first special operation }
+  DIBUTTON_3DCONTROL_SPECIAL              = $24000403; { Select special operation }
+  DIBUTTON_3DCONTROL_SPECIAL2             = $24000404; { Do second special operation }
+  DIBUTTON_3DCONTROL_MENU                 = $240004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_3DCONTROL_HATSWITCH         = $24004601; { Hat switch }
+  DIAXIS_3DCONTROL_ROTATEX                = $24034204; { Rotate view forward or up / backward or down }
+  DIAXIS_3DCONTROL_ROTATEY                = $2402C205; { Rotate view clockwise / counterclockwise }
+  DIAXIS_3DCONTROL_ROTATEZ                = $24024206; { Rotate view left / right }
+  DIBUTTON_3DCONTROL_DISPLAY              = $24004405; { Show next on-screen display options }
+  DIBUTTON_3DCONTROL_DEVICE               = $240044FE; { Show input device and controls }
+  DIBUTTON_3DCONTROL_PAUSE                = $240044FC; { Start / Pause / Restart game }
+
+(*--- CAD - 3D Navigation - Fly through
+      Controls for 3D modeling  ---*)
+  DIVIRTUAL_CAD_FLYBY                     = $25000000;
+  DIAXIS_CADF_LATERAL                     = $25008201; { move view left / right }
+  DIAXIS_CADF_MOVE                        = $25010202; { move view up / down }
+  DIAXIS_CADF_INOUT                       = $25018203; { in / out }
+  DIBUTTON_CADF_SELECT                    = $25000401; { Select Object }
+  DIBUTTON_CADF_SPECIAL1                  = $25000402; { do first special operation }
+  DIBUTTON_CADF_SPECIAL                   = $25000403; { Select special operation }
+  DIBUTTON_CADF_SPECIAL2                  = $25000404; { do second special operation }
+  DIBUTTON_CADF_MENU                      = $250004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_CADF_HATSWITCH              = $25004601; { Hat switch }
+  DIAXIS_CADF_ROTATEX                     = $25034204; { Rotate view forward or up / backward or down }
+  DIAXIS_CADF_ROTATEY                     = $2502C205; { Rotate view clockwise / counterclockwise }
+  DIAXIS_CADF_ROTATEZ                     = $25024206; { Rotate view left / right }
+  DIBUTTON_CADF_DISPLAY                   = $25004405; { shows next on-screen display options }
+  DIBUTTON_CADF_DEVICE                    = $250044FE; { Show input device and controls }
+  DIBUTTON_CADF_PAUSE                     = $250044FC; { Start / Pause / Restart game }
+
+(*--- CAD - 3D Model Control
+      Controls for 3D modeling  ---*)
+  DIVIRTUAL_CAD_MODEL                     = $26000000;
+  DIAXIS_CADM_LATERAL                     = $26008201; { move view left / right }
+  DIAXIS_CADM_MOVE                        = $26010202; { move view up / down }
+  DIAXIS_CADM_INOUT                       = $26018203; { in / out }
+  DIBUTTON_CADM_SELECT                    = $26000401; { Select Object }
+  DIBUTTON_CADM_SPECIAL1                  = $26000402; { do first special operation }
+  DIBUTTON_CADM_SPECIAL                   = $26000403; { Select special operation }
+  DIBUTTON_CADM_SPECIAL2                  = $26000404; { do second special operation }
+  DIBUTTON_CADM_MENU                      = $260004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIHATSWITCH_CADM_HATSWITCH              = $26004601; { Hat switch }
+  DIAXIS_CADM_ROTATEX                     = $26034204; { Rotate view forward or up / backward or down }
+  DIAXIS_CADM_ROTATEY                     = $2602C205; { Rotate view clockwise / counterclockwise }
+  DIAXIS_CADM_ROTATEZ                     = $26024206; { Rotate view left / right }
+  DIBUTTON_CADM_DISPLAY                   = $26004405; { shows next on-screen display options }
+  DIBUTTON_CADM_DEVICE                    = $260044FE; { Show input device and controls }
+  DIBUTTON_CADM_PAUSE                     = $260044FC; { Start / Pause / Restart game }
+
+(*--- Control - Media Equipment
+      Remote        ---*)
+  DIVIRTUAL_REMOTE_CONTROL                = $27000000;
+  DIAXIS_REMOTE_SLIDER                    = $27050201; { Slider for adjustment: volume / color / bass / etc }
+  DIBUTTON_REMOTE_MUTE                    = $27000401; { Set volume on current device to zero }
+  DIBUTTON_REMOTE_SELECT                  = $27000402; { Next/previous: channel/ track / chapter / picture / station }
+  DIBUTTON_REMOTE_PLAY                    = $27002403; { Start or pause entertainment on current device }
+  DIBUTTON_REMOTE_CUE                     = $27002404; { Move through current media }
+  DIBUTTON_REMOTE_REVIEW                  = $27002405; { Move through current media }
+  DIBUTTON_REMOTE_CHANGE                  = $27002406; { Select next device }
+  DIBUTTON_REMOTE_RECORD                  = $27002407; { Start recording the current media }
+  DIBUTTON_REMOTE_MENU                    = $270004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIAXIS_REMOTE_SLIDER2                   = $27054202; { Slider for adjustment: volume }
+  DIBUTTON_REMOTE_TV                      = $27005C08; { Select TV }
+  DIBUTTON_REMOTE_CABLE                   = $27005C09; { Select cable box }
+  DIBUTTON_REMOTE_CD                      = $27005C0A; { Select CD player }
+  DIBUTTON_REMOTE_VCR                     = $27005C0B; { Select VCR }
+  DIBUTTON_REMOTE_TUNER                   = $27005C0C; { Select tuner }
+  DIBUTTON_REMOTE_DVD                     = $27005C0D; { Select DVD player }
+  DIBUTTON_REMOTE_ADJUST                  = $27005C0E; { Enter device adjustment menu }
+  DIBUTTON_REMOTE_DIGIT0                  = $2700540F; { Digit 0 }
+  DIBUTTON_REMOTE_DIGIT1                  = $27005410; { Digit 1 }
+  DIBUTTON_REMOTE_DIGIT2                  = $27005411; { Digit 2 }
+  DIBUTTON_REMOTE_DIGIT3                  = $27005412; { Digit 3 }
+  DIBUTTON_REMOTE_DIGIT4                  = $27005413; { Digit 4 }
+  DIBUTTON_REMOTE_DIGIT5                  = $27005414; { Digit 5 }
+  DIBUTTON_REMOTE_DIGIT6                  = $27005415; { Digit 6 }
+  DIBUTTON_REMOTE_DIGIT7                  = $27005416; { Digit 7 }
+  DIBUTTON_REMOTE_DIGIT8                  = $27005417; { Digit 8 }
+  DIBUTTON_REMOTE_DIGIT9                  = $27005418; { Digit 9 }
+  DIBUTTON_REMOTE_DEVICE                  = $270044FE; { Show input device and controls }
+  DIBUTTON_REMOTE_PAUSE                   = $270044FC; { Start / Pause / Restart game }
+
+(*--- Control- Web
+      Help or Browser            ---*)
+  DIVIRTUAL_BROWSER_CONTROL               = $28000000;
+  DIAXIS_BROWSER_LATERAL                  = $28008201; { Move on screen pointer }
+  DIAXIS_BROWSER_MOVE                     = $28010202; { Move on screen pointer }
+  DIBUTTON_BROWSER_SELECT                 = $28000401; { Select current item }
+  DIAXIS_BROWSER_VIEW                     = $28018203; { Move view up/down }
+  DIBUTTON_BROWSER_REFRESH                = $28000402; { Refresh }
+  DIBUTTON_BROWSER_MENU                   = $280004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIBUTTON_BROWSER_SEARCH                 = $28004403; { Use search tool }
+  DIBUTTON_BROWSER_STOP                   = $28004404; { Cease current update }
+  DIBUTTON_BROWSER_HOME                   = $28004405; { Go directly to "home" location }
+  DIBUTTON_BROWSER_FAVORITES              = $28004406; { Mark current site as favorite }
+  DIBUTTON_BROWSER_NEXT                   = $28004407; { Select Next page }
+  DIBUTTON_BROWSER_PREVIOUS               = $28004408; { Select Previous page }
+  DIBUTTON_BROWSER_HISTORY                = $28004409; { Show/Hide History }
+  DIBUTTON_BROWSER_PRINT                  = $2800440A; { Print current page }
+  DIBUTTON_BROWSER_DEVICE                 = $280044FE; { Show input device and controls }
+  DIBUTTON_BROWSER_PAUSE                  = $280044FC; { Start / Pause / Restart game }
+
+(*--- Driving Simulator - Giant Walking Robot
+      Walking tank with weapons  ---*)
+  DIVIRTUAL_DRIVING_MECHA                 = $29000000;
+  DIAXIS_MECHA_STEER                      = $29008201; { Turns mecha left/right }
+  DIAXIS_MECHA_TORSO                      = $29010202; { Tilts torso forward/backward }
+  DIAXIS_MECHA_ROTATE                     = $29020203; { Turns torso left/right }
+  DIAXIS_MECHA_THROTTLE                   = $29038204; { Engine Speed }
+  DIBUTTON_MECHA_FIRE                     = $29000401; { Fire }
+  DIBUTTON_MECHA_WEAPONS                  = $29000402; { Select next weapon group }
+  DIBUTTON_MECHA_TARGET                   = $29000403; { Select closest enemy available target }
+  DIBUTTON_MECHA_REVERSE                  = $29000404; { Toggles throttle in/out of reverse }
+  DIBUTTON_MECHA_ZOOM                     = $29000405; { Zoom in/out targeting reticule }
+  DIBUTTON_MECHA_JUMP                     = $29000406; { Fires jump jets }
+  DIBUTTON_MECHA_MENU                     = $290004FD; { Show menu options }
+(*--- Priority 2 controls                            ---*)
+
+  DIBUTTON_MECHA_CENTER                   = $29004407; { Center torso to legs }
+  DIHATSWITCH_MECHA_GLANCE                = $29004601; { Look around }
+  DIBUTTON_MECHA_VIEW                     = $29004408; { Cycle through view options }
+  DIBUTTON_MECHA_FIRESECONDARY            = $29004409; { Alternative fire button }
+  DIBUTTON_MECHA_LEFT_LINK                = $2900C4E4; { Fallback steer left button }
+  DIBUTTON_MECHA_RIGHT_LINK               = $2900C4EC; { Fallback steer right button }
+  DIBUTTON_MECHA_FORWARD_LINK             = $290144E0; { Fallback tilt torso forward button }
+  DIBUTTON_MECHA_BACK_LINK                = $290144E8; { Fallback tilt toroso backward button }
+  DIBUTTON_MECHA_ROTATE_LEFT_LINK         = $290244E4; { Fallback rotate toroso right button }
+  DIBUTTON_MECHA_ROTATE_RIGHT_LINK        = $290244EC; { Fallback rotate torso left button }
+  DIBUTTON_MECHA_FASTER_LINK              = $2903C4E0; { Fallback increase engine speed }
+  DIBUTTON_MECHA_SLOWER_LINK              = $2903C4E8; { Fallback decrease engine speed }
+  DIBUTTON_MECHA_DEVICE                   = $290044FE; { Show input device and controls }
+  DIBUTTON_MECHA_PAUSE                    = $290044FC; { Start / Pause / Restart game }
+
+(*
+ *  "ANY" semantics can be used as a last resort to get mappings for actions
+ *  that match nothing in the chosen virtual genre.  These semantics will be
+ *  mapped at a lower priority that virtual genre semantics.  Also, hardware
+ *  vendors will not be able to provide sensible mappings for these unless
+ *  they provide application specific mappings.
+ *)
+  DIAXIS_ANY_X_1                          = $FF00C201;
+  DIAXIS_ANY_X_2                          = $FF00C202;
+  DIAXIS_ANY_Y_1                          = $FF014201;
+  DIAXIS_ANY_Y_2                          = $FF014202;
+  DIAXIS_ANY_Z_1                          = $FF01C201;
+  DIAXIS_ANY_Z_2                          = $FF01C202;
+  DIAXIS_ANY_R_1                          = $FF024201;
+  DIAXIS_ANY_R_2                          = $FF024202;
+  DIAXIS_ANY_U_1                          = $FF02C201;
+  DIAXIS_ANY_U_2                          = $FF02C202;
+  DIAXIS_ANY_V_1                          = $FF034201;
+  DIAXIS_ANY_V_2                          = $FF034202;
+  DIAXIS_ANY_A_1                          = $FF03C201;
+  DIAXIS_ANY_A_2                          = $FF03C202;
+  DIAXIS_ANY_B_1                          = $FF044201;
+  DIAXIS_ANY_B_2                          = $FF044202;
+  DIAXIS_ANY_C_1                          = $FF04C201;
+  DIAXIS_ANY_C_2                          = $FF04C202;
+  DIAXIS_ANY_S_1                          = $FF054201;
+  DIAXIS_ANY_S_2                          = $FF054202;
+
+  DIAXIS_ANY_1                            = $FF004201;
+  DIAXIS_ANY_2                            = $FF004202;
+  DIAXIS_ANY_3                            = $FF004203;
+  DIAXIS_ANY_4                            = $FF004204;
+
+  DIPOV_ANY_1                             = $FF004601;
+  DIPOV_ANY_2                             = $FF004602;
+  DIPOV_ANY_3                             = $FF004603;
+  DIPOV_ANY_4                             = $FF004604;
+
+//#define DIBUTTON_ANY(instance)                  ( 0xFF004400 | instance )
+
+
+//#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
+//#pragma endregion
+
+//#ifdef __cplusplus
+//};
+//#endif
+
+//#endif  /* __DINPUT_INCLUDED__ */
+
+(****************************************************************************
+ *
+ *  Definitions for non-IDirectInput (VJoyD) features defined more recently
+ *  than the current sdk files
+ *
+ ****************************************************************************)
+
+{$IFDEF _INC_MMSYSTEM}
+{$IFNDEF MMNOJOY}
+
+{$IFNDEF __VJOYDX_INCLUDED__}
+{$DEFINE __VJOYDX_INCLUDED__}
+
+//#ifdef __cplusplus
+//extern "C" {
+//#endif
+
+//#pragma region Desktop Family
+//#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+
+(*
+ * Flag to indicate that the dwReserved2 field of the JOYINFOEX structure
+ * contains mini-driver specific data to be passed by VJoyD to the mini-
+ * driver instead of doing a poll.
+ *)
+const
+  JOY_PASSDRIVERDATA          = $10000000;
+
+(*
+ * Informs the joystick driver that the configuration has been changed
+ * and should be reloaded from the registery.
+ * dwFlags is reserved and should be set to zero
+ *)
+//WINMMAPI MMRESULT WINAPI joyConfigChanged( DWORD dwFlags );
+
+//#ifndef DIJ_RINGZERO
+(*
+ * Invoke the joystick control panel directly, using the passed window handle
+ * as the parent of the dialog.  This API is only supported for compatibility
+ * purposes; new applications should use the RunControlPanel method of a
+ * device interface for a game controller.
+ * The API is called by using the function pointer returned by
+ * GetProcAddress( hCPL, TEXT("ShowJoyCPL") ) where hCPL is a HMODULE returned
+ * by LoadLibrary( TEXT("joy.cpl") ).  The typedef is provided to allow
+ * declaration and casting of an appropriately typed variable.
+ *)
+//void WINAPI ShowJoyCPL( HWND hWnd );
+//typedef void (WINAPI* LPFNSHOWJOYCPL)( HWND hWnd );
+type
+  LPFNSHOWJOYCPL = procedure(hWnd: HWND); stdcall;
+//#endif
+
+(*
+ * Hardware Setting indicating that the device is a headtracker
+ *)
+const
+  JOY_HWS_ISHEADTRACKER       = $02000000;
+
+(*
+ * Hardware Setting indicating that the VxD is used to replace
+ * the standard analog polling
+ *)
+  JOY_HWS_ISGAMEPORTDRIVER    = $04000000;
+
+(*
+ * Hardware Setting indicating that the driver needs a standard
+ * gameport in order to communicate with the device.
+ *)
+  JOY_HWS_ISANALOGPORTDRIVER  = $08000000;
+
+(*
+ * Hardware Setting indicating that VJoyD should not load this
+ * driver, it will be loaded externally and will register with
+ * VJoyD of it's own accord.
+ *)
+  JOY_HWS_AUTOLOAD            = $10000000;
+
+(*
+ * Hardware Setting indicating that the driver acquires any
+ * resources needed without needing a devnode through VJoyD.
+ *)
+  JOY_HWS_NODEVNODE           = $20000000;
+
+
+(*
+ * Hardware Setting indicating that the device is a gameport bus
+ *)
+  JOY_HWS_ISGAMEPORTBUS       = $80000000;
+  JOY_HWS_GAMEPORTBUSBUSY     = $00000001;
+
+(*
+ * Usage Setting indicating that the settings are volatile and
+ * should be removed if still present on a reboot.
+ *)
+  JOY_US_VOLATILE             = $00000008;
+
+//#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
+//#pragma endregion
+
+//#ifdef __cplusplus
+//};
+//#endif
+
+{$ENDIF}  { __VJOYDX_INCLUDED__ }
+
+{$ENDIF}  { not MMNOJOY }
+{$ENDIF}  { _INC_MMSYSTEM }
+
+(****************************************************************************
+ *
+ *  Definitions for non-IDirectInput (VJoyD) features defined more recently
+ *  than the current ddk files
+ *
+ ****************************************************************************)
+
+//#ifndef DIJ_RINGZERO
+
+{$IFDEF _INC_MMDDK}
+{$IFNDEF MMNOJOYDEV}
+
+{$IFNDEF __VJOYDXD_INCLUDED__}
+{$DEFINE __VJOYDXD_INCLUDED__}
+(*
+ * Poll type in which the do_other field of the JOYOEMPOLLDATA
+ * structure contains mini-driver specific data passed from an app.
+ *)
+const
+  JOY_OEMPOLL_PASSDRIVERDATA = 7;
+
+{$ENDIF}  { __VJOYDXD_INCLUDED__ }
+
+{$ENDIF}  { not MMNOJOYDEV }
+{$ENDIF}  { _INC_MMDDK }
+
+//#endif /* DIJ_RINGZERO */
+
+function GET_DIDEVICE_SUBTYPE(dwDevType: DWORD): BYTE; inline;
+function DIDFT_MAKEINSTANCE(n: WORD): DWORD; inline;
+function DIDFT_GETINSTANCE(n: DWORD): WORD; inline;
+function DIDFT_ENUMCOLLECTION(n: WORD): DWORD; inline;
+{$IF DIRECTINPUT_VERSION >= $050a}
+function DIMAKEUSAGEDWORD(UsagePage, Usage: Word): DWORD; inline;
+{$ENDIF} { DIRECTINPUT_VERSION >= $050a }
+function DISEQUENCE_COMPARE(dwSequence1: DWORD; const cmp: string; dwSequence2: DWORD): Boolean; inline;
+function DIBUTTON_ANY(instance: Byte): DWORD; inline;
+
+implementation
+
+//#define GET_DIDEVICE_SUBTYPE(dwDevType) HIBYTE(dwDevType)
+function GET_DIDEVICE_SUBTYPE(dwDevType: DWORD): BYTE; inline;
+begin
+  Result := HIBYTE(dwDevType);
+end;
+
+//#define DIDFT_MAKEINSTANCE(n) ((WORD)(n) << 8)
+function DIDFT_MAKEINSTANCE(n: WORD): DWORD; inline;
+begin
+  Result := n shl 8;
+end;
+
+//#define DIDFT_GETINSTANCE(n) LOWORD((n) >> 8)
+function DIDFT_GETINSTANCE(n: DWORD): WORD; inline;
+begin
+  Result := LOWORD(n shr 8);
+end;
+
+//#define DIDFT_ENUMCOLLECTION(n) ((WORD)(n) << 8)
+function DIDFT_ENUMCOLLECTION(n: WORD): DWORD; inline;
+begin
+  Result := n shl 8;
+end;
+
+{$IF DIRECTINPUT_VERSION >= $050a}
+//#define DIMAKEUSAGEDWORD(UsagePage, Usage) \
+//                                (DWORD)MAKELONG(Usage, UsagePage)
+function DIMAKEUSAGEDWORD(UsagePage, Usage: Word): DWORD; inline;
+begin
+  Result := MAKELONG(Usage, UsagePage);
+end;
+{$ENDIF} { DIRECTINPUT_VERSION >= $050a }
+
+//#define DISEQUENCE_COMPARE(dwSequence1, cmp, dwSequence2) \
+//                        ((int)((dwSequence1) - (dwSequence2)) cmp 0)
+function DISEQUENCE_COMPARE(dwSequence1: DWORD; const cmp: string; dwSequence2: DWORD): Boolean; inline;
+begin
+{$PUSH}{$Q-,R-}
+  if (cmp = '==') or (cmp = '=') then
+    Result := LongInt(dwSequence1 - dwSequence2) = 0
+  else if (cmp = '!=') or (cmp = '<>') then
+    Result := LongInt(dwSequence1 - dwSequence2) <> 0
+  else if cmp = '<' then
+    Result := LongInt(dwSequence1 - dwSequence2) < 0
+  else if cmp = '>' then
+    Result := LongInt(dwSequence1 - dwSequence2) > 0
+  else if cmp = '<=' then
+    Result := LongInt(dwSequence1 - dwSequence2) <= 0
+  else if cmp = '>=' then
+    Result := LongInt(dwSequence1 - dwSequence2) >= 0;
+{$POP}
+end;
+
+//#define DIBUTTON_ANY(instance)                  ( 0xFF004400 | instance )
+function DIBUTTON_ANY(instance: Byte): DWORD; inline;
+begin
+  Result := $FF004400 or instance;
+end;
+
+end.

+ 2 - 1
packages/ptc/src/win32/directx/win32directxconsoled.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2003, 2006, 2007, 2009-2013  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2003, 2006, 2007, 2009-2013, 2016  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -180,4 +180,5 @@ type
     function GetInformation: string; override;
     function GetInformation: string; override;
     function NextEvent(out AEvent: IPTCEvent; AWait: Boolean; const AEventMask: TPTCEventMask): Boolean; override;
     function NextEvent(out AEvent: IPTCEvent; AWait: Boolean; const AEventMask: TPTCEventMask): Boolean; override;
     function PeekEvent(AWait: Boolean; const AEventMask: TPTCEventMask): IPTCEvent; override;
     function PeekEvent(AWait: Boolean; const AEventMask: TPTCEventMask): IPTCEvent; override;
+    function MoveMouseTo(X, Y: Integer): Boolean; override;
   end;
   end;

+ 8 - 2
packages/ptc/src/win32/directx/win32directxconsolei.inc

@@ -1,6 +1,6 @@
 {
 {
     Free Pascal port of the OpenPTC C++ library.
     Free Pascal port of the OpenPTC C++ library.
-    Copyright (C) 2001-2003, 2006, 2007, 2009-2013  Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2003, 2006, 2007, 2009-2013, 2016  Nikolay Nikolov ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
     Original C++ version by Glenn Fiedler ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -991,7 +991,7 @@ begin
   FKeyboard := TWin32Keyboard.Create(FWindow.handle, FWindow.thread, False, FEventQueue);
   FKeyboard := TWin32Keyboard.Create(FWindow.handle, FWindow.thread, False, FEventQueue);
   FMouse := TWin32Mouse.Create(FWindow.handle, FWindow.thread, False, FEventQueue, FPrimary.Fullscreen, FPrimary.width, FPrimary.height);
   FMouse := TWin32Mouse.Create(FWindow.handle, FWindow.thread, False, FEventQueue, FPrimary.Fullscreen, FPrimary.width, FPrimary.height);
   if FPrimary.Fullscreen then
   if FPrimary.Fullscreen then
-    FMouse.SetWindowArea(0, 0, FDisplay.Mode.Width, FDisplay.Mode.Height);
+    FMouse.SetWindowArea(0, 0, FDisplay.Mode.Width - 1, FDisplay.Mode.Height - 1);
   if not FPrimary.Fullscreen then
   if not FPrimary.Fullscreen then
     FResize := TWin32Resize.Create(FWindow.handle, FWindow.thread, FEventQueue);
     FResize := TWin32Resize.Create(FWindow.handle, FWindow.thread, FEventQueue);
   FWindow.update;
   FWindow.update;
@@ -1243,6 +1243,12 @@ begin
     FWindow.InterceptClose := AInterceptClose;
     FWindow.InterceptClose := AInterceptClose;
 end;
 end;
 
 
+function TDirectXConsole.MoveMouseTo(X, Y: Integer): Boolean;
+begin
+  CHECK_OPEN('TDirectXConsole.MoveMouseTo');
+  Result := FMouse.MoveMouseTo(X, Y);
+end;
+
 {$IFDEF DEBUG}
 {$IFDEF DEBUG}
 procedure TDirectXConsole.CHECK_OPEN(AMsg: String);
 procedure TDirectXConsole.CHECK_OPEN(AMsg: String);
 begin
 begin

+ 3 - 3
packages/ptc/src/win32/directx/win32directxdisplay.inc

@@ -119,8 +119,8 @@ begin
       if not found then
       if not found then
       begin
       begin
         LOG('adding 320x200x8 to mode list');
         LOG('adding 320x200x8 to mode list');
-	
-	Inc(FModesCount);
+
+        Inc(FModesCount);
         SetLength(FModes, FModesCount);
         SetLength(FModes, FModesCount);
         FModes[FModesCount - 1] := TPTCMode.Create(320, 200, format8);
         FModes[FModesCount - 1] := TPTCMode.Create(320, 200, format8);
       end;
       end;
@@ -133,7 +133,7 @@ begin
       begin
       begin
         LOG('adding 320x240x8 to mode list');
         LOG('adding 320x240x8 to mode list');
 
 
-	Inc(FModesCount);
+        Inc(FModesCount);
         SetLength(FModes, FModesCount);
         SetLength(FModes, FModesCount);
         FModes[FModesCount - 1] := TPTCMode.Create(320, 240, format8);
         FModes[FModesCount - 1] := TPTCMode.Create(320, 240, format8);
       end;
       end;

+ 12 - 12
packages/ptc/src/win32/directx/win32directxhook.inc

@@ -79,9 +79,9 @@ begin
       if active = False then
       if active = False then
       begin
       begin
         if FConsole.FGrabMouse and (not FFullscreen) then
         if FConsole.FGrabMouse and (not FFullscreen) then
-	begin
-	  FConsole.FWindow.ConfineCursor(False);
-	end;
+        begin
+          FConsole.FWindow.ConfineCursor(False);
+        end;
 
 
         { deactivate }
         { deactivate }
         Deactivate;
         Deactivate;
@@ -103,19 +103,19 @@ begin
         begin
         begin
           { check show command is not minimize }
           { check show command is not minimize }
           if placement.showCmd <> SW_SHOWMINIMIZED then
           if placement.showCmd <> SW_SHOWMINIMIZED then
-	  begin
+          begin
             {hide cursor}
             {hide cursor}
             FConsole.FWin32Cursor.Hide;
             FConsole.FWin32Cursor.Hide;
-	  end;
+          end;
         end;
         end;
 
 
-	if FConsole.FGrabMouse and (not FFullscreen) then
-	begin
+        if FConsole.FGrabMouse and (not FFullscreen) then
+        begin
           if placement.showCmd <> SW_SHOWMINIMIZED then
           if placement.showCmd <> SW_SHOWMINIMIZED then
-	  begin
+          begin
             FConsole.FWindow.ConfineCursor(True);
             FConsole.FWindow.ConfineCursor(True);
-	  end;
-	end;
+          end;
+        end;
 
 
         { activate }
         { activate }
         Activate;
         Activate;
@@ -130,13 +130,13 @@ begin
       if not FCursor then
       if not FCursor then
       begin
       begin
         if FFullscreen or (LOWORD(lParam) = HTCLIENT) then
         if FFullscreen or (LOWORD(lParam) = HTCLIENT) then
-	begin
+        begin
           { hide cursor }
           { hide cursor }
           SetCursor(0);
           SetCursor(0);
 
 
           { handled }
           { handled }
           Result := 1;
           Result := 1;
-	end;
+        end;
       end;
       end;
     end;
     end;
     WM_PALETTECHANGED:
     WM_PALETTECHANGED:

+ 5 - 3
packages/ptc/src/win32/gdi/win32gdiconsoled.inc

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the PTCPas framebuffer library
     This file is part of the PTCPas framebuffer library
-    Copyright (C) 2007, 2009-2013  Nikolay Nikolov ([email protected])
+    Copyright (C) 2007, 2009-2013, 2016  Nikolay Nikolov ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     modify it under the terms of the GNU Lesser General Public
@@ -154,7 +154,9 @@ type
     function NextEvent(out AEvent: IPTCEvent; AWait: Boolean; const AEventMask: TPTCEventMask): Boolean; override;
     function NextEvent(out AEvent: IPTCEvent; AWait: Boolean; const AEventMask: TPTCEventMask): Boolean; override;
     function PeekEvent(AWait: Boolean; const AEventMask: TPTCEventMask): IPTCEvent; override;
     function PeekEvent(AWait: Boolean; const AEventMask: TPTCEventMask): IPTCEvent; override;
 
 
+    function MoveMouseTo(X, Y: Integer): Boolean; override;
+
     procedure OpenGL_SwapBuffers; override;
     procedure OpenGL_SwapBuffers; override;
-	procedure OpenGL_SetSwapInterval(AInterval: Integer); override;
-	function OpenGL_GetSwapInterval: Integer; override;
+    procedure OpenGL_SetSwapInterval(AInterval: Integer); override;
+    function OpenGL_GetSwapInterval: Integer; override;
   end;
   end;

+ 9 - 3
packages/ptc/src/win32/gdi/win32gdiconsolei.inc

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the PTCPas framebuffer library
     This file is part of the PTCPas framebuffer library
-    Copyright (C) 2007, 2009-2013  Nikolay Nikolov ([email protected])
+    Copyright (C) 2007, 2009-2013, 2016  Nikolay Nikolov ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     modify it under the terms of the GNU Lesser General Public
@@ -225,7 +225,7 @@ begin
   FKeyboard := TWin32Keyboard.Create(FWindow.Handle, FWindow.Thread, False, FEventQueue);
   FKeyboard := TWin32Keyboard.Create(FWindow.Handle, FWindow.Thread, False, FEventQueue);
   FMouse := TWin32Mouse.Create(FWindow.Handle, FWindow.Thread, False, FEventQueue, FFullScreen, AWidth, AHeight);
   FMouse := TWin32Mouse.Create(FWindow.Handle, FWindow.Thread, False, FEventQueue, FFullScreen, AWidth, AHeight);
   if FFullscreen then
   if FFullscreen then
-    FMouse.SetWindowArea(0, 0, AWidth, AHeight);
+    FMouse.SetWindowArea(0, 0, AWidth - 1, AHeight - 1);
   if not FFullscreen and FResizable then
   if not FFullscreen and FResizable then
     FResize := TWin32Resize.Create(FWindow.Handle, FWindow.Thread, FEventQueue);
     FResize := TWin32Resize.Create(FWindow.Handle, FWindow.Thread, FEventQueue);
 
 
@@ -730,7 +730,7 @@ begin
     LOG('using WGL_EXT_swap_control');
     LOG('using WGL_EXT_swap_control');
     LOG('wglSwapIntervalEXT(' + IntToStr(AInterval) + ')');
     LOG('wglSwapIntervalEXT(' + IntToStr(AInterval) + ')');
     if not wglSwapIntervalEXT(AInterval) then
     if not wglSwapIntervalEXT(AInterval) then
-	  LOG('wglSwapIntervalEXT failed');
+      LOG('wglSwapIntervalEXT failed');
   end
   end
   else
   else
     LOG('no supported extensions found for setting the swap interval');
     LOG('no supported extensions found for setting the swap interval');
@@ -761,6 +761,12 @@ begin
     FWindow.InterceptClose := AInterceptClose;
     FWindow.InterceptClose := AInterceptClose;
 end;
 end;
 
 
+function TGDIConsole.MoveMouseTo(X, Y: Integer): Boolean;
+begin
+  CheckOpen('TGDIConsole.MoveMouseTo');
+  Result := FMouse.MoveMouseTo(X, Y);
+end;
+
 procedure TGDIConsole.CheckOpen(const AMessage: String);
 procedure TGDIConsole.CheckOpen(const AMessage: String);
 begin
 begin
   if not FOpen then
   if not FOpen then

+ 2 - 2
packages/ptc/src/win32/gdi/win32openglwindowd.inc

@@ -33,9 +33,9 @@ type
   TWin32OpenGLWindow = class(TWin32Window)
   TWin32OpenGLWindow = class(TWin32Window)
   private
   private
     FPixelFormatDescriptor: PIXELFORMATDESCRIPTOR;
     FPixelFormatDescriptor: PIXELFORMATDESCRIPTOR;
-	FChosenPixelFormatDescriptor: PIXELFORMATDESCRIPTOR;
+    FChosenPixelFormatDescriptor: PIXELFORMATDESCRIPTOR;
 
 
-	procedure SetOpenGLAttributes(const AOpenGLAttributes: IPTCOpenGLAttributes);
+    procedure SetOpenGLAttributes(const AOpenGLAttributes: IPTCOpenGLAttributes);
     function EnumerateAllPixelFormats(hdc: HDC): Boolean;
     function EnumerateAllPixelFormats(hdc: HDC): Boolean;
     function SetupOpenGLPixelFormat(hdc: HDC): Boolean;
     function SetupOpenGLPixelFormat(hdc: HDC): Boolean;
     procedure LogPixelFormatDescriptor(const pfd: PIXELFORMATDESCRIPTOR);
     procedure LogPixelFormatDescriptor(const pfd: PIXELFORMATDESCRIPTOR);

+ 2 - 2
packages/ptc/src/win32/gdi/win32openglwindowi.inc

@@ -160,13 +160,13 @@ begin
     Flags := Flags or PFD_DOUBLEBUFFER_DONTCARE
     Flags := Flags or PFD_DOUBLEBUFFER_DONTCARE
   else
   else
     if AOpenGLAttributes.DoubleBuffer then
     if AOpenGLAttributes.DoubleBuffer then
-	  Flags := Flags or PFD_DOUBLEBUFFER;
+      Flags := Flags or PFD_DOUBLEBUFFER;
 
 
   if AOpenGLAttributes.StereoDontCare then
   if AOpenGLAttributes.StereoDontCare then
     Flags := Flags or PFD_STEREO_DONTCARE
     Flags := Flags or PFD_STEREO_DONTCARE
   else
   else
     if AOpenGLAttributes.Stereo then
     if AOpenGLAttributes.Stereo then
-	  Flags := Flags or PFD_STEREO;
+      Flags := Flags or PFD_STEREO;
 
 
   FillChar(FPixelFormatDescriptor, SizeOf(FPixelFormatDescriptor), 0);
   FillChar(FPixelFormatDescriptor, SizeOf(FPixelFormatDescriptor), 0);
   FPixelFormatDescriptor.nSize := SizeOf(FPixelFormatDescriptor);
   FPixelFormatDescriptor.nSize := SizeOf(FPixelFormatDescriptor);

+ 4 - 1
packages/ptc/src/x11/x11consoled.inc

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the PTCPas framebuffer library
     This file is part of the PTCPas framebuffer library
-    Copyright (C) 2001-2013 Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2013, 2016 Nikolay Nikolov ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -40,6 +40,7 @@ type
 
 
     procedure UpdateCursor;
     procedure UpdateCursor;
     procedure UpdateMouseGrab;
     procedure UpdateMouseGrab;
+    function UpdateRelativeMouseMode: Boolean;
 
 
     function CreateDisplay: TX11Display; { Factory method }
     function CreateDisplay: TX11Display; { Factory method }
 
 
@@ -117,6 +118,8 @@ type
     function NextEvent(out AEvent: IPTCEvent; AWait: Boolean; const AEventMask: TPTCEventMask): Boolean; override;
     function NextEvent(out AEvent: IPTCEvent; AWait: Boolean; const AEventMask: TPTCEventMask): Boolean; override;
     function PeekEvent(AWait: Boolean; const AEventMask: TPTCEventMask): IPTCEvent; override;
     function PeekEvent(AWait: Boolean; const AEventMask: TPTCEventMask): IPTCEvent; override;
 
 
+    function MoveMouseTo(X, Y: Integer): Boolean; override;
+
     procedure OpenGL_SwapBuffers; override;
     procedure OpenGL_SwapBuffers; override;
     procedure OpenGL_SetSwapInterval(AInterval: Integer); override;
     procedure OpenGL_SetSwapInterval(AInterval: Integer); override;
     function OpenGL_GetSwapInterval: Integer; override;
     function OpenGL_GetSwapInterval: Integer; override;

+ 51 - 2
packages/ptc/src/x11/x11consolei.inc

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the PTCPas framebuffer library
     This file is part of the PTCPas framebuffer library
-    Copyright (C) 2001-2013 Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2013, 2016, 2017 Nikolay Nikolov ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -37,7 +37,8 @@ begin
   inherited Create;
   inherited Create;
 
 
   { default flags }
   { default flags }
-  FFlags := [PTC_X11_TRY_XSHM, PTC_X11_TRY_XF86VIDMODE];
+  FFlags := [PTC_X11_TRY_XSHM, PTC_X11_TRY_XF86VIDMODE, PTC_X11_TRY_XINPUT2,
+             PTC_X11_TRY_XIM];
 
 
   FTitle := '';
   FTitle := '';
 
 
@@ -170,6 +171,26 @@ begin
     FFlags := FFlags - [PTC_X11_TRY_XSHM];
     FFlags := FFlags - [PTC_X11_TRY_XSHM];
     exit;
     exit;
   end;
   end;
+  if (AOption = 'xinput2') or (AOption = 'xinput2 on') then
+  begin
+    FFlags := FFlags + [PTC_X11_TRY_XINPUT2];
+    exit;
+  end;
+  if AOption = 'xinput2 off' then
+  begin
+    FFlags := FFlags - [PTC_X11_TRY_XINPUT2];
+    exit;
+  end;
+  if (AOption = 'xim') or (AOption = 'xim on') then
+  begin
+    FFlags := FFlags + [PTC_X11_TRY_XIM];
+    exit;
+  end;
+  if AOption = 'xim off' then
+  begin
+    FFlags := FFlags - [PTC_X11_TRY_XIM];
+    exit;
+  end;
   if AOption = 'default cursor' then
   if AOption = 'default cursor' then
   begin
   begin
     FFlags := FFlags - [PTC_X11_FULLSCREEN_CURSOR_VISIBLE, PTC_X11_WINDOWED_CURSOR_INVISIBLE];
     FFlags := FFlags - [PTC_X11_FULLSCREEN_CURSOR_VISIBLE, PTC_X11_WINDOWED_CURSOR_INVISIBLE];
@@ -200,6 +221,18 @@ begin
     UpdateMouseGrab;
     UpdateMouseGrab;
     exit;
     exit;
   end;
   end;
+  if AOption = 'relative mouse on' then
+  begin
+    FFlags := FFlags + [PTC_X11_RELATIVE_MOUSE_MODE];
+    Result := UpdateRelativeMouseMode;
+    exit;
+  end;
+  if AOption = 'relative mouse off' then
+  begin
+    FFlags := FFlags - [PTC_X11_RELATIVE_MOUSE_MODE];
+    Result := UpdateRelativeMouseMode;
+    exit;
+  end;
   if AOption = 'intercept window close' then
   if AOption = 'intercept window close' then
   begin
   begin
     FFlags := FFlags + [PTC_X11_INTERCEPT_WINDOW_CLOSE];
     FFlags := FFlags + [PTC_X11_INTERCEPT_WINDOW_CLOSE];
@@ -575,6 +608,22 @@ begin
     FX11Display.SetMouseGrab(PTC_X11_GRAB_MOUSE in FFlags);
     FX11Display.SetMouseGrab(PTC_X11_GRAB_MOUSE in FFlags);
 end;
 end;
 
 
+function TX11Console.UpdateRelativeMouseMode: Boolean;
+begin
+  if Assigned(FX11Display) then
+    Result := FX11Display.SetRelativeMouseMode(PTC_X11_RELATIVE_MOUSE_MODE in FFlags)
+  else
+    Result := True;
+end;
+
+function TX11Console.MoveMouseTo(X, Y: Integer): Boolean;
+begin
+  if Assigned(FX11Display) then
+    Result := FX11Display.MoveMouseTo(X, Y)
+  else
+    Result := False;
+end;
+
 procedure TX11Console.OpenGL_SwapBuffers;
 procedure TX11Console.OpenGL_SwapBuffers;
 begin
 begin
   FX11Display.OpenGL_SwapBuffers;
   FX11Display.OpenGL_SwapBuffers;

+ 2 - 1
packages/ptc/src/x11/x11dga1displayd.inc

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the PTCPas framebuffer library
     This file is part of the PTCPas framebuffer library
-    Copyright (C) 2001-2012 Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2012, 2016 Nikolay Nikolov ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -76,6 +76,7 @@ type
     function IsOpen: Boolean; override;
     function IsOpen: Boolean; override;
     procedure SetCursor(AVisible: Boolean); override;
     procedure SetCursor(AVisible: Boolean); override;
     procedure SetMouseGrab(AGrabMouse: Boolean); override;
     procedure SetMouseGrab(AGrabMouse: Boolean); override;
+    function SetRelativeMouseMode(ARelativeMouseMode: Boolean): Boolean; override;
   end;
   end;
 
 
 {$ENDIF ENABLE_X11_EXTENSION_XF86DGA1}
 {$ENDIF ENABLE_X11_EXTENSION_XF86DGA1}

+ 7 - 1
packages/ptc/src/x11/x11dga1displayi.inc

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the PTCPas framebuffer library
     This file is part of the PTCPas framebuffer library
-    Copyright (C) 2001-2012 Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2012, 2016 Nikolay Nikolov ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -483,4 +483,10 @@ begin
   {...}
   {...}
 end;
 end;
 
 
+function TX11DGA1Display.SetRelativeMouseMode(ARelativeMouseMode: Boolean): Boolean;
+begin
+  {...}
+  Result := not ARelativeMouseMode;
+end;
+
 {$ENDIF ENABLE_X11_EXTENSION_XF86DGA1}
 {$ENDIF ENABLE_X11_EXTENSION_XF86DGA1}

+ 2 - 1
packages/ptc/src/x11/x11dga2displayd.inc

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the PTCPas framebuffer library
     This file is part of the PTCPas framebuffer library
-    Copyright (C) 2001-2012 Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2012, 2016 Nikolay Nikolov ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -78,6 +78,7 @@ type
     function IsOpen: Boolean; override;
     function IsOpen: Boolean; override;
     procedure SetCursor(visible: Boolean); override;
     procedure SetCursor(visible: Boolean); override;
     procedure SetMouseGrab(AGrabMouse: Boolean); override;
     procedure SetMouseGrab(AGrabMouse: Boolean); override;
+    function SetRelativeMouseMode(ARelativeMouseMode: Boolean): Boolean; override;
   end;
   end;
 
 
 {$ENDIF ENABLE_X11_EXTENSION_XF86DGA2}
 {$ENDIF ENABLE_X11_EXTENSION_XF86DGA2}

+ 7 - 1
packages/ptc/src/x11/x11dga2displayi.inc

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the PTCPas framebuffer library
     This file is part of the PTCPas framebuffer library
-    Copyright (C) 2001-2012 Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2012, 2016 Nikolay Nikolov ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -560,4 +560,10 @@ begin
   {...}
   {...}
 end;
 end;
 
 
+function TX11DGA2Display.SetRelativeMouseMode(ARelativeMouseMode: Boolean): Boolean;
+begin
+  {...}
+  Result := not ARelativeMouseMode;
+end;
+
 {$ENDIF ENABLE_X11_EXTENSION_XF86DGA2}
 {$ENDIF ENABLE_X11_EXTENSION_XF86DGA2}

+ 11 - 1
packages/ptc/src/x11/x11displayd.inc

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the PTCPas framebuffer library
     This file is part of the PTCPas framebuffer library
-    Copyright (C) 2001-2013 Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2013, 2016, 2017 Nikolay Nikolov ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -39,10 +39,13 @@ type
                    PTC_X11_TRY_XF86VIDMODE,
                    PTC_X11_TRY_XF86VIDMODE,
                    PTC_X11_TRY_XRANDR,
                    PTC_X11_TRY_XRANDR,
                    PTC_X11_TRY_XSHM,
                    PTC_X11_TRY_XSHM,
+                   PTC_X11_TRY_XINPUT2,
+                   PTC_X11_TRY_XIM,
                    PTC_X11_DITHER,
                    PTC_X11_DITHER,
                    PTC_X11_FULLSCREEN_CURSOR_VISIBLE,
                    PTC_X11_FULLSCREEN_CURSOR_VISIBLE,
                    PTC_X11_WINDOWED_CURSOR_INVISIBLE,
                    PTC_X11_WINDOWED_CURSOR_INVISIBLE,
                    PTC_X11_GRAB_MOUSE,
                    PTC_X11_GRAB_MOUSE,
+                   PTC_X11_RELATIVE_MOUSE_MODE,
                    PTC_X11_INTERCEPT_WINDOW_CLOSE,
                    PTC_X11_INTERCEPT_WINDOW_CLOSE,
                    PTC_X11_RESIZABLE_WINDOW,
                    PTC_X11_RESIZABLE_WINDOW,
                    PTC_X11_USE_OPENGL);
                    PTC_X11_USE_OPENGL);
@@ -74,6 +77,9 @@ type
     FFunctionKeys: PInteger;
     FFunctionKeys: PInteger;
     FNormalKeys: PInteger;
     FNormalKeys: PInteger;
 
 
+    FXIM: PXIM;
+    FXIC: PXIC;
+
     function GetInterceptClose: Boolean;
     function GetInterceptClose: Boolean;
     procedure SetInterceptClose(AInterceptClose: Boolean);
     procedure SetInterceptClose(AInterceptClose: Boolean);
 
 
@@ -148,6 +154,8 @@ type
     { mouse grab control }
     { mouse grab control }
     procedure SetMouseGrab(AGrabMouse: Boolean); virtual; abstract;
     procedure SetMouseGrab(AGrabMouse: Boolean); virtual; abstract;
 
 
+    function SetRelativeMouseMode(ARelativeMouseMode: Boolean): Boolean; virtual; abstract;
+
     { Data access }
     { Data access }
     function Clip: IPTCArea;
     function Clip: IPTCArea;
 
 
@@ -176,6 +184,8 @@ type
     property Area: IPTCArea read GetArea;
     property Area: IPTCArea read GetArea;
     property Format: IPTCFormat read GetFormat;
     property Format: IPTCFormat read GetFormat;
 
 
+    function MoveMouseTo(X, Y: Integer): Boolean; virtual;
+
     procedure OpenGL_SwapBuffers; virtual;
     procedure OpenGL_SwapBuffers; virtual;
     procedure OpenGL_SetSwapInterval(AInterval: Integer); virtual;
     procedure OpenGL_SetSwapInterval(AInterval: Integer); virtual;
     function OpenGL_GetSwapInterval: Integer; virtual;
     function OpenGL_GetSwapInterval: Integer; virtual;

+ 56 - 6
packages/ptc/src/x11/x11displayi.inc

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the PTCPas framebuffer library
     This file is part of the PTCPas framebuffer library
-    Copyright (C) 2001-2013 Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2013, 2015-2017 Nikolay Nikolov ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -452,11 +452,23 @@ var
   uni: Integer;
   uni: Integer;
   key: TPTCKeyEvent;
   key: TPTCKeyEvent;
   buf: array [1..16] of Char;
   buf: array [1..16] of Char;
+  lslen: cint;
+  status: TStatus;
+  eaten_by_im: Boolean = False;
 begin
 begin
-  sym := XLookupKeySym(@e, 0);
+  if Assigned(FXIM) and Assigned(FXIC) and (Self is TX11WindowDisplay) then
+  begin
+    eaten_by_im := XFilterEvent(@e, TX11WindowDisplay(Self).FWindow);
+  end;
   XLookupString(@e, @buf, SizeOf(buf), @sym_modded, nil);
   XLookupString(@e, @buf, SizeOf(buf), @sym_modded, nil);
+  if (e._type = KeyPress) and Assigned(FXIM) and Assigned(FXIC) then
+  begin
+    lslen := XmbLookupString(FXIC, @e, @buf, SizeOf(buf), @sym_modded, @status);
+//    Writeln(lslen, ' ', status, ' ', buf[1], ' ', XKeysymToString(sym_modded));
+  end;
+  sym := XLookupKeySym(@e, 0);
 //  Writeln('sym_modded = ', sym_modded);
 //  Writeln('sym_modded = ', sym_modded);
-  uni := X11ConvertKeySymToUnicode(sym_modded);
+//  Writeln(HexStr(e.state, 8));
   modkeys := [];
   modkeys := [];
   if (e.state and Mod1Mask) <> 0 then
   if (e.state and Mod1Mask) <> 0 then
     Include(modkeys, pmkAlt);
     Include(modkeys, pmkAlt);
@@ -464,10 +476,42 @@ begin
     Include(modkeys, pmkShift);
     Include(modkeys, pmkShift);
   if (e.state and ControlMask) <> 0 then
   if (e.state and ControlMask) <> 0 then
     Include(modkeys, pmkControl);
     Include(modkeys, pmkControl);
+  if (e.state and LockMask) <> 0 then
+    Include(modkeys, pmkCapsLockActive);
+  if (e.state and Mod2Mask) <> 0 then
+    Include(modkeys, pmkNumLockActive);
+  if X11IsDeadKey(sym_modded) then
+    Include(modkeys, pmkDeadKey);
   if e._type = KeyPress then
   if e._type = KeyPress then
-    press := True
+  begin
+    press := True;
+    uni := X11ConvertKeySymToUnicode(sym_modded);
+  end
   else
   else
+  begin
     press := False;
     press := False;
+    uni := -1;
+  end;
+  if (sym_modded = XK_KP_Insert) or
+     (sym_modded = XK_KP_Delete) or
+     (sym_modded = XK_KP_Home) or
+     (sym_modded = XK_KP_End) or
+     (sym_modded = XK_KP_Prior) or
+     (sym_modded = XK_KP_Next) or
+     (sym_modded = XK_KP_Begin) or
+     (sym_modded = XK_KP_Left) or
+     (sym_modded = XK_KP_Right) or
+     (sym_modded = XK_KP_Up) or
+     (sym_modded = XK_KP_Down) or
+     (sym_modded = XK_KP_Divide) or
+     (sym_modded = XK_KP_Multiply) or
+     (sym_modded = XK_KP_Subtract) or
+     (sym_modded = XK_KP_Add) or
+     (sym_modded = XK_KP_Enter) or
+     (sym_modded = XK_KP_Decimal) or
+     ((sym_modded >= XK_KP_0) and (sym_modded <= XK_KP_9)) or
+     (sym_modded = XK_Num_Lock) then
+    Include(modkeys, pmkNumPadKey);
 
 
   // XK_ISO_Left_Tab is Shift-Tab
   // XK_ISO_Left_Tab is Shift-Tab
   if sym_modded = XK_ISO_Left_Tab then
   if sym_modded = XK_ISO_Left_Tab then
@@ -496,9 +540,10 @@ begin
     0: key := TPTCKeyEvent.Create(FNormalKeys[sym_modded and $FF], uni, modkeys, press);
     0: key := TPTCKeyEvent.Create(FNormalKeys[sym_modded and $FF], uni, modkeys, press);
     $FF: key := TPTCKeyEvent.Create(FFunctionKeys[sym_modded and $FF], uni, modkeys, press);
     $FF: key := TPTCKeyEvent.Create(FFunctionKeys[sym_modded and $FF], uni, modkeys, press);
     else
     else
-      key := TPTCKeyEvent.Create;
+      key := TPTCKeyEvent.Create(PTCKEY_UNDEFINED, uni, modkeys, press);
   end;
   end;
-  FEventQueue.AddEvent(key);
+  if (not eaten_by_im) or (pmkDeadKey in modkeys) then
+    FEventQueue.AddEvent(key);
 end;
 end;
 
 
 function TX11Display.GetInterceptClose: Boolean;
 function TX11Display.GetInterceptClose: Boolean;
@@ -519,6 +564,11 @@ begin
   raise TPTCError.Create('Console not in windowed mode');
   raise TPTCError.Create('Console not in windowed mode');
 end;
 end;
 
 
+function TX11Display.MoveMouseTo(X, Y: Integer): Boolean;
+begin
+  Result := False;
+end;
+
 procedure TX11Display.OpenGL_SwapBuffers;
 procedure TX11Display.OpenGL_SwapBuffers;
 begin
 begin
   raise TPTCError.Create('Not in OpenGL mode');
   raise TPTCError.Create('Not in OpenGL mode');

+ 1 - 0
packages/ptc/src/x11/x11extensions.inc

@@ -5,3 +5,4 @@
 {$DEFINE ENABLE_X11_EXTENSION_XF86DGA2}
 {$DEFINE ENABLE_X11_EXTENSION_XF86DGA2}
 {$DEFINE ENABLE_X11_EXTENSION_XSHM}
 {$DEFINE ENABLE_X11_EXTENSION_XSHM}
 {$DEFINE ENABLE_X11_EXTENSION_GLX}
 {$DEFINE ENABLE_X11_EXTENSION_GLX}
+{$DEFINE ENABLE_X11_EXTENSION_XINPUT2}

+ 734 - 197
packages/ptc/src/x11/x11unikey.inc

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the PTCPas framebuffer library
     This file is part of the PTCPas framebuffer library
-    Copyright (C) 2001-2012 Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2012,2017 Nikolay Nikolov ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -30,6 +30,25 @@
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 }
 }
 
 
+function X11IsDeadKey(sym: TKeySym): Boolean;
+begin
+  case sym of
+    XK_dead_grave, XK_dead_acute, XK_dead_circumflex,
+    XK_dead_tilde, XK_dead_macron, XK_dead_breve, XK_dead_abovedot,
+    XK_dead_diaeresis, XK_dead_abovering, XK_dead_doubleacute, XK_dead_caron,
+    XK_dead_cedilla, XK_dead_ogonek, XK_dead_iota, XK_dead_voiced_sound,
+    XK_dead_semivoiced_sound, XK_dead_belowdot, XK_dead_hook, XK_dead_horn,
+    XK_dead_stroke, XK_dead_abovecomma, XK_dead_abovereversedcomma,
+    XK_dead_doublegrave, XK_dead_belowring, XK_dead_belowmacron,
+    XK_dead_belowcircumflex, XK_dead_belowtilde, XK_dead_belowbreve,
+    XK_dead_belowdiaeresis, XK_dead_invertedbreve, XK_dead_belowcomma,
+    XK_dead_currency:
+      Result := True;
+    else
+      Result := False;
+  end;
+end;
+
 function X11ConvertKeySymToUnicode(sym: TKeySym): Integer;
 function X11ConvertKeySymToUnicode(sym: TKeySym): Integer;
 begin
 begin
   if (sym >= 0) and (sym <= $FF) then
   if (sym >= 0) and (sym <= $FF) then
@@ -61,206 +80,724 @@ begin
     XK_Escape: exit(27);
     XK_Escape: exit(27);
   End;
   End;
   case sym of
   case sym of
-    XKc_Cyrillic_GHE_bar     : exit($492);
-    XK_Cyrillic_ghe_bar      : exit($493);
-    XKc_Cyrillic_ZHE_descender: exit($496);
-    XK_Cyrillic_zhe_descender: exit($497);
-    XKc_Cyrillic_KA_descender: exit($49A);
-    XK_Cyrillic_ka_descender : exit($49B);
-    XKc_Cyrillic_KA_vertstroke: exit($49C);
-    XK_Cyrillic_ka_vertstroke: exit($49D);
-    XKc_Cyrillic_EN_descender: exit($4A2);
-    XK_Cyrillic_en_descender : exit($4A3);
-    XKc_Cyrillic_U_straight  : exit($4AE);
-    XK_Cyrillic_u_straight   : exit($4AF);
-    XKc_Cyrillic_U_straight_bar: exit($4B0);
-    XK_Cyrillic_u_straight_bar: exit($4B1);
-    XKc_Cyrillic_HA_descender: exit($4B2);
-    XK_Cyrillic_ha_descender : exit($4B3);
-    XKc_Cyrillic_CHE_descender: exit($4B6);
-    XK_Cyrillic_che_descender: exit($4B7);
-    XKc_Cyrillic_CHE_vertstroke: exit($4B8);
-    XK_Cyrillic_che_vertstroke: exit($4B9);
-    XKc_Cyrillic_SHHA        : exit($4BA);
-    XK_Cyrillic_shha         : exit($4BB);
+    { Latin 2 }
+    XKc_Aogonek      : exit($0104);  { U+0104 LATIN CAPITAL LETTER A WITH OGONEK }
+    XK_breve         : exit($02D8);  { U+02D8 BREVE }
+    XKc_Lstroke      : exit($0141);  { U+0141 LATIN CAPITAL LETTER L WITH STROKE }
+    XKc_Lcaron       : exit($013D);  { U+013D LATIN CAPITAL LETTER L WITH CARON }
+    XKc_Sacute       : exit($015A);  { U+015A LATIN CAPITAL LETTER S WITH ACUTE }
+    XKc_Scaron       : exit($0160);  { U+0160 LATIN CAPITAL LETTER S WITH CARON }
+    XKc_Scedilla     : exit($015E);  { U+015E LATIN CAPITAL LETTER S WITH CEDILLA }
+    XKc_Tcaron       : exit($0164);  { U+0164 LATIN CAPITAL LETTER T WITH CARON }
+    XKc_Zacute       : exit($0179);  { U+0179 LATIN CAPITAL LETTER Z WITH ACUTE }
+    XKc_Zcaron       : exit($017D);  { U+017D LATIN CAPITAL LETTER Z WITH CARON }
+    XKc_Zabovedot    : exit($017B);  { U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE }
+    XK_aogonek       : exit($0105);  { U+0105 LATIN SMALL LETTER A WITH OGONEK }
+    XK_ogonek        : exit($02DB);  { U+02DB OGONEK }
+    XK_lstroke       : exit($0142);  { U+0142 LATIN SMALL LETTER L WITH STROKE }
+    XK_lcaron        : exit($013E);  { U+013E LATIN SMALL LETTER L WITH CARON }
+    XK_sacute        : exit($015B);  { U+015B LATIN SMALL LETTER S WITH ACUTE }
+    XK_caron         : exit($02C7);  { U+02C7 CARON }
+    XK_scaron        : exit($0161);  { U+0161 LATIN SMALL LETTER S WITH CARON }
+    XK_scedilla      : exit($015F);  { U+015F LATIN SMALL LETTER S WITH CEDILLA }
+    XK_tcaron        : exit($0165);  { U+0165 LATIN SMALL LETTER T WITH CARON }
+    XK_zacute        : exit($017A);  { U+017A LATIN SMALL LETTER Z WITH ACUTE }
+    XK_doubleacute   : exit($02DD);  { U+02DD DOUBLE ACUTE ACCENT }
+    XK_zcaron        : exit($017E);  { U+017E LATIN SMALL LETTER Z WITH CARON }
+    XK_zabovedot     : exit($017C);  { U+017C LATIN SMALL LETTER Z WITH DOT ABOVE }
+    XKc_Racute       : exit($0154);  { U+0154 LATIN CAPITAL LETTER R WITH ACUTE }
+    XKc_Abreve       : exit($0102);  { U+0102 LATIN CAPITAL LETTER A WITH BREVE }
+    XKc_Lacute       : exit($0139);  { U+0139 LATIN CAPITAL LETTER L WITH ACUTE }
+    XKc_Cacute       : exit($0106);  { U+0106 LATIN CAPITAL LETTER C WITH ACUTE }
+    XKc_Ccaron       : exit($010C);  { U+010C LATIN CAPITAL LETTER C WITH CARON }
+    XKc_Eogonek      : exit($0118);  { U+0118 LATIN CAPITAL LETTER E WITH OGONEK }
+    XKc_Ecaron       : exit($011A);  { U+011A LATIN CAPITAL LETTER E WITH CARON }
+    XKc_Dcaron       : exit($010E);  { U+010E LATIN CAPITAL LETTER D WITH CARON }
+    XKc_Dstroke      : exit($0110);  { U+0110 LATIN CAPITAL LETTER D WITH STROKE }
+    XKc_Nacute       : exit($0143);  { U+0143 LATIN CAPITAL LETTER N WITH ACUTE }
+    XKc_Ncaron       : exit($0147);  { U+0147 LATIN CAPITAL LETTER N WITH CARON }
+    XKc_Odoubleacute : exit($0150);  { U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE }
+    XKc_Rcaron       : exit($0158);  { U+0158 LATIN CAPITAL LETTER R WITH CARON }
+    XKc_Uring        : exit($016E);  { U+016E LATIN CAPITAL LETTER U WITH RING ABOVE }
+    XKc_Udoubleacute : exit($0170);  { U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE }
+    XKc_Tcedilla     : exit($0162);  { U+0162 LATIN CAPITAL LETTER T WITH CEDILLA }
+    XK_racute        : exit($0155);  { U+0155 LATIN SMALL LETTER R WITH ACUTE }
+    XK_abreve        : exit($0103);  { U+0103 LATIN SMALL LETTER A WITH BREVE }
+    XK_lacute        : exit($013A);  { U+013A LATIN SMALL LETTER L WITH ACUTE }
+    XK_cacute        : exit($0107);  { U+0107 LATIN SMALL LETTER C WITH ACUTE }
+    XK_ccaron        : exit($010D);  { U+010D LATIN SMALL LETTER C WITH CARON }
+    XK_eogonek       : exit($0119);  { U+0119 LATIN SMALL LETTER E WITH OGONEK }
+    XK_ecaron        : exit($011B);  { U+011B LATIN SMALL LETTER E WITH CARON }
+    XK_dcaron        : exit($010F);  { U+010F LATIN SMALL LETTER D WITH CARON }
+    XK_dstroke       : exit($0111);  { U+0111 LATIN SMALL LETTER D WITH STROKE }
+    XK_nacute        : exit($0144);  { U+0144 LATIN SMALL LETTER N WITH ACUTE }
+    XK_ncaron        : exit($0148);  { U+0148 LATIN SMALL LETTER N WITH CARON }
+    XK_odoubleacute  : exit($0151);  { U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE }
+    XK_rcaron        : exit($0159);  { U+0159 LATIN SMALL LETTER R WITH CARON }
+    XK_uring         : exit($016F);  { U+016F LATIN SMALL LETTER U WITH RING ABOVE }
+    XK_udoubleacute  : exit($0171);  { U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE }
+    XK_tcedilla      : exit($0163);  { U+0163 LATIN SMALL LETTER T WITH CEDILLA }
+    XK_abovedot      : exit($02D9);  { U+02D9 DOT ABOVE }
+
+    { Latin 3 }
+    XKc_Hstroke     : exit($0126);  { U+0126 LATIN CAPITAL LETTER H WITH STROKE }
+    XKc_Hcircumflex : exit($0124);  { U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX }
+    XKc_Iabovedot   : exit($0130);  { U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE }
+    XKc_Gbreve      : exit($011E);  { U+011E LATIN CAPITAL LETTER G WITH BREVE }
+    XKc_Jcircumflex : exit($0134);  { U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX }
+    XK_hstroke      : exit($0127);  { U+0127 LATIN SMALL LETTER H WITH STROKE }
+    XK_hcircumflex  : exit($0125);  { U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX }
+    XK_idotless     : exit($0131);  { U+0131 LATIN SMALL LETTER DOTLESS I }
+    XK_gbreve       : exit($011F);  { U+011F LATIN SMALL LETTER G WITH BREVE }
+    XK_jcircumflex  : exit($0135);  { U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX }
+    XKc_Cabovedot   : exit($010A);  { U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE }
+    XKc_Ccircumflex : exit($0108);  { U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX }
+    XKc_Gabovedot   : exit($0120);  { U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE }
+    XKc_Gcircumflex : exit($011C);  { U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX }
+    XKc_Ubreve      : exit($016C);  { U+016C LATIN CAPITAL LETTER U WITH BREVE }
+    XKc_Scircumflex : exit($015C);  { U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX }
+    XK_cabovedot    : exit($010B);  { U+010B LATIN SMALL LETTER C WITH DOT ABOVE }
+    XK_ccircumflex  : exit($0109);  { U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX }
+    XK_gabovedot    : exit($0121);  { U+0121 LATIN SMALL LETTER G WITH DOT ABOVE }
+    XK_gcircumflex  : exit($011D);  { U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX }
+    XK_ubreve       : exit($016D);  { U+016D LATIN SMALL LETTER U WITH BREVE }
+    XK_scircumflex  : exit($015D);  { U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX }
+
+    { Latin 4 }
+    XK_kra        : exit($0138);  { U+0138 LATIN SMALL LETTER KRA }
+    XKc_Rcedilla  : exit($0156);  { U+0156 LATIN CAPITAL LETTER R WITH CEDILLA }
+    XKc_Itilde    : exit($0128);  { U+0128 LATIN CAPITAL LETTER I WITH TILDE }
+    XKc_Lcedilla  : exit($013B);  { U+013B LATIN CAPITAL LETTER L WITH CEDILLA }
+    XKc_Emacron   : exit($0112);  { U+0112 LATIN CAPITAL LETTER E WITH MACRON }
+    XKc_Gcedilla  : exit($0122);  { U+0122 LATIN CAPITAL LETTER G WITH CEDILLA }
+    XKc_Tslash    : exit($0166);  { U+0166 LATIN CAPITAL LETTER T WITH STROKE }
+    XK_rcedilla   : exit($0157);  { U+0157 LATIN SMALL LETTER R WITH CEDILLA }
+    XK_itilde     : exit($0129);  { U+0129 LATIN SMALL LETTER I WITH TILDE }
+    XK_lcedilla   : exit($013C);  { U+013C LATIN SMALL LETTER L WITH CEDILLA }
+    XK_emacron    : exit($0113);  { U+0113 LATIN SMALL LETTER E WITH MACRON }
+    XK_gcedilla   : exit($0123);  { U+0123 LATIN SMALL LETTER G WITH CEDILLA }
+    XK_tslash     : exit($0167);  { U+0167 LATIN SMALL LETTER T WITH STROKE }
+    XKc_ENG       : exit($014A);  { U+014A LATIN CAPITAL LETTER ENG }
+    XK_eng        : exit($014B);  { U+014B LATIN SMALL LETTER ENG }
+    XKc_Amacron   : exit($0100);  { U+0100 LATIN CAPITAL LETTER A WITH MACRON }
+    XKc_Iogonek   : exit($012E);  { U+012E LATIN CAPITAL LETTER I WITH OGONEK }
+    XKc_Eabovedot : exit($0116);  { U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE }
+    XKc_Imacron   : exit($012A);  { U+012A LATIN CAPITAL LETTER I WITH MACRON }
+    XKc_Ncedilla  : exit($0145);  { U+0145 LATIN CAPITAL LETTER N WITH CEDILLA }
+    XKc_Omacron   : exit($014C);  { U+014C LATIN CAPITAL LETTER O WITH MACRON }
+    XKc_Kcedilla  : exit($0136);  { U+0136 LATIN CAPITAL LETTER K WITH CEDILLA }
+    XKc_Uogonek   : exit($0172);  { U+0172 LATIN CAPITAL LETTER U WITH OGONEK }
+    XKc_Utilde    : exit($0168);  { U+0168 LATIN CAPITAL LETTER U WITH TILDE }
+    XKc_Umacron   : exit($016A);  { U+016A LATIN CAPITAL LETTER U WITH MACRON }
+    XK_amacron    : exit($0101);  { U+0101 LATIN SMALL LETTER A WITH MACRON }
+    XK_iogonek    : exit($012F);  { U+012F LATIN SMALL LETTER I WITH OGONEK }
+    XK_eabovedot  : exit($0117);  { U+0117 LATIN SMALL LETTER E WITH DOT ABOVE }
+    XK_imacron    : exit($012B);  { U+012B LATIN SMALL LETTER I WITH MACRON }
+    XK_ncedilla   : exit($0146);  { U+0146 LATIN SMALL LETTER N WITH CEDILLA }
+    XK_omacron    : exit($014D);  { U+014D LATIN SMALL LETTER O WITH MACRON }
+    XK_kcedilla   : exit($0137);  { U+0137 LATIN SMALL LETTER K WITH CEDILLA }
+    XK_uogonek    : exit($0173);  { U+0173 LATIN SMALL LETTER U WITH OGONEK }
+    XK_utilde     : exit($0169);  { U+0169 LATIN SMALL LETTER U WITH TILDE }
+    XK_umacron    : exit($016B);  { U+016B LATIN SMALL LETTER U WITH MACRON }
+
+    { Latin 9 }
+    XKc_OE         : exit($0152);  { U+0152 LATIN CAPITAL LIGATURE OE }
+    XK_oe          : exit($0153);  { U+0153 LATIN SMALL LIGATURE OE }
+    XKc_Ydiaeresis : exit($0178);  { U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS }
+
+    { Katakana }
+    XK_overline            : exit($203E);  { U+203E OVERLINE }
+    XK_kana_fullstop       : exit($3002);  { U+3002 IDEOGRAPHIC FULL STOP }
+    XK_kana_openingbracket : exit($300C);  { U+300C LEFT CORNER BRACKET }
+    XK_kana_closingbracket : exit($300D);  { U+300D RIGHT CORNER BRACKET }
+    XK_kana_comma          : exit($3001);  { U+3001 IDEOGRAPHIC COMMA }
+    XK_kana_conjunctive    : exit($30FB);  { U+30FB KATAKANA MIDDLE DOT }
+    XKc_kana_WO            : exit($30F2);  { U+30F2 KATAKANA LETTER WO }
+    XK_kana_a              : exit($30A1);  { U+30A1 KATAKANA LETTER SMALL A }
+    XK_kana_i              : exit($30A3);  { U+30A3 KATAKANA LETTER SMALL I }
+    XK_kana_u              : exit($30A5);  { U+30A5 KATAKANA LETTER SMALL U }
+    XK_kana_e              : exit($30A7);  { U+30A7 KATAKANA LETTER SMALL E }
+    XK_kana_o              : exit($30A9);  { U+30A9 KATAKANA LETTER SMALL O }
+    XK_kana_ya             : exit($30E3);  { U+30E3 KATAKANA LETTER SMALL YA }
+    XK_kana_yu             : exit($30E5);  { U+30E5 KATAKANA LETTER SMALL YU }
+    XK_kana_yo             : exit($30E7);  { U+30E7 KATAKANA LETTER SMALL YO }
+    XK_kana_tsu            : exit($30C3);  { U+30C3 KATAKANA LETTER SMALL TU }
+    XK_prolongedsound      : exit($30FC);  { U+30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK }
+    XKc_kana_A             : exit($30A2);  { U+30A2 KATAKANA LETTER A }
+    XKc_kana_I             : exit($30A4);  { U+30A4 KATAKANA LETTER I }
+    XKc_kana_U             : exit($30A6);  { U+30A6 KATAKANA LETTER U }
+    XKc_kana_E             : exit($30A8);  { U+30A8 KATAKANA LETTER E }
+    XKc_kana_O             : exit($30AA);  { U+30AA KATAKANA LETTER O }
+    XKc_kana_KA            : exit($30AB);  { U+30AB KATAKANA LETTER KA }
+    XKc_kana_KI            : exit($30AD);  { U+30AD KATAKANA LETTER KI }
+    XKc_kana_KU            : exit($30AF);  { U+30AF KATAKANA LETTER KU }
+    XKc_kana_KE            : exit($30B1);  { U+30B1 KATAKANA LETTER KE }
+    XKc_kana_KO            : exit($30B3);  { U+30B3 KATAKANA LETTER KO }
+    XKc_kana_SA            : exit($30B5);  { U+30B5 KATAKANA LETTER SA }
+    XKc_kana_SHI           : exit($30B7);  { U+30B7 KATAKANA LETTER SI }
+    XKc_kana_SU            : exit($30B9);  { U+30B9 KATAKANA LETTER SU }
+    XKc_kana_SE            : exit($30BB);  { U+30BB KATAKANA LETTER SE }
+    XKc_kana_SO            : exit($30BD);  { U+30BD KATAKANA LETTER SO }
+    XKc_kana_TA            : exit($30BF);  { U+30BF KATAKANA LETTER TA }
+    XKc_kana_CHI           : exit($30C1);  { U+30C1 KATAKANA LETTER TI }
+    XKc_kana_TSU           : exit($30C4);  { U+30C4 KATAKANA LETTER TU }
+    XKc_kana_TE            : exit($30C6);  { U+30C6 KATAKANA LETTER TE }
+    XKc_kana_TO            : exit($30C8);  { U+30C8 KATAKANA LETTER TO }
+    XKc_kana_NA            : exit($30CA);  { U+30CA KATAKANA LETTER NA }
+    XKc_kana_NI            : exit($30CB);  { U+30CB KATAKANA LETTER NI }
+    XKc_kana_NU            : exit($30CC);  { U+30CC KATAKANA LETTER NU }
+    XKc_kana_NE            : exit($30CD);  { U+30CD KATAKANA LETTER NE }
+    XKc_kana_NO            : exit($30CE);  { U+30CE KATAKANA LETTER NO }
+    XKc_kana_HA            : exit($30CF);  { U+30CF KATAKANA LETTER HA }
+    XKc_kana_HI            : exit($30D2);  { U+30D2 KATAKANA LETTER HI }
+    XKc_kana_FU            : exit($30D5);  { U+30D5 KATAKANA LETTER HU }
+    XKc_kana_HE            : exit($30D8);  { U+30D8 KATAKANA LETTER HE }
+    XKc_kana_HO            : exit($30DB);  { U+30DB KATAKANA LETTER HO }
+    XKc_kana_MA            : exit($30DE);  { U+30DE KATAKANA LETTER MA }
+    XKc_kana_MI            : exit($30DF);  { U+30DF KATAKANA LETTER MI }
+    XKc_kana_MU            : exit($30E0);  { U+30E0 KATAKANA LETTER MU }
+    XKc_kana_ME            : exit($30E1);  { U+30E1 KATAKANA LETTER ME }
+    XKc_kana_MO            : exit($30E2);  { U+30E2 KATAKANA LETTER MO }
+    XKc_kana_YA            : exit($30E4);  { U+30E4 KATAKANA LETTER YA }
+    XKc_kana_YU            : exit($30E6);  { U+30E6 KATAKANA LETTER YU }
+    XKc_kana_YO            : exit($30E8);  { U+30E8 KATAKANA LETTER YO }
+    XKc_kana_RA            : exit($30E9);  { U+30E9 KATAKANA LETTER RA }
+    XKc_kana_RI            : exit($30EA);  { U+30EA KATAKANA LETTER RI }
+    XKc_kana_RU            : exit($30EB);  { U+30EB KATAKANA LETTER RU }
+    XKc_kana_RE            : exit($30EC);  { U+30EC KATAKANA LETTER RE }
+    XKc_kana_RO            : exit($30ED);  { U+30ED KATAKANA LETTER RO }
+    XKc_kana_WA            : exit($30EF);  { U+30EF KATAKANA LETTER WA }
+    XKc_kana_N             : exit($30F3);  { U+30F3 KATAKANA LETTER N }
+    XK_voicedsound         : exit($309B);  { U+309B KATAKANA-HIRAGANA VOICED SOUND MARK }
+    XK_semivoicedsound     : exit($309C);  { U+309C KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK }
 
 
-    XKc_Cyrillic_SCHWA       : exit($4D8);
-    XK_Cyrillic_schwa        : exit($4D9);
-    XKc_Cyrillic_I_macron    : exit($4E2);
-    XK_Cyrillic_i_macron     : exit($4E3);
-    XKc_Cyrillic_O_bar       : exit($4E8);
-    XK_Cyrillic_o_bar        : exit($4E9);
-    XKc_Cyrillic_U_macron    : exit($4EE);
-    XK_Cyrillic_u_macron     : exit($4EF);
+    { Arabic }
+    XK_Arabic_comma          : exit($060C);     { U+060C ARABIC COMMA }
+    XK_Arabic_semicolon      : exit($061B);     { U+061B ARABIC SEMICOLON }
+    XK_Arabic_question_mark  : exit($061F);     { U+061F ARABIC QUESTION MARK }
+    XK_Arabic_hamza          : exit($0621);     { U+0621 ARABIC LETTER HAMZA }
+    XK_Arabic_maddaonalef    : exit($0622);     { U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE }
+    XK_Arabic_hamzaonalef    : exit($0623);     { U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE }
+    XK_Arabic_hamzaonwaw     : exit($0624);     { U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE }
+    XK_Arabic_hamzaunderalef : exit($0625);     { U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW }
+    XK_Arabic_hamzaonyeh     : exit($0626);     { U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE }
+    XK_Arabic_alef           : exit($0627);     { U+0627 ARABIC LETTER ALEF }
+    XK_Arabic_beh            : exit($0628);     { U+0628 ARABIC LETTER BEH }
+    XK_Arabic_tehmarbuta     : exit($0629);     { U+0629 ARABIC LETTER TEH MARBUTA }
+    XK_Arabic_teh            : exit($062A);     { U+062A ARABIC LETTER TEH }
+    XK_Arabic_theh           : exit($062B);     { U+062B ARABIC LETTER THEH }
+    XK_Arabic_jeem           : exit($062C);     { U+062C ARABIC LETTER JEEM }
+    XK_Arabic_hah            : exit($062D);     { U+062D ARABIC LETTER HAH }
+    XK_Arabic_khah           : exit($062E);     { U+062E ARABIC LETTER KHAH }
+    XK_Arabic_dal            : exit($062F);     { U+062F ARABIC LETTER DAL }
+    XK_Arabic_thal           : exit($0630);     { U+0630 ARABIC LETTER THAL }
+    XK_Arabic_ra             : exit($0631);     { U+0631 ARABIC LETTER REH }
+    XK_Arabic_zain           : exit($0632);     { U+0632 ARABIC LETTER ZAIN }
+    XK_Arabic_seen           : exit($0633);     { U+0633 ARABIC LETTER SEEN }
+    XK_Arabic_sheen          : exit($0634);     { U+0634 ARABIC LETTER SHEEN }
+    XK_Arabic_sad            : exit($0635);     { U+0635 ARABIC LETTER SAD }
+    XK_Arabic_dad            : exit($0636);     { U+0636 ARABIC LETTER DAD }
+    XK_Arabic_tah            : exit($0637);     { U+0637 ARABIC LETTER TAH }
+    XK_Arabic_zah            : exit($0638);     { U+0638 ARABIC LETTER ZAH }
+    XK_Arabic_ain            : exit($0639);     { U+0639 ARABIC LETTER AIN }
+    XK_Arabic_ghain          : exit($063A);     { U+063A ARABIC LETTER GHAIN }
+    XK_Arabic_tatweel        : exit($0640);     { U+0640 ARABIC TATWEEL }
+    XK_Arabic_feh            : exit($0641);     { U+0641 ARABIC LETTER FEH }
+    XK_Arabic_qaf            : exit($0642);     { U+0642 ARABIC LETTER QAF }
+    XK_Arabic_kaf            : exit($0643);     { U+0643 ARABIC LETTER KAF }
+    XK_Arabic_lam            : exit($0644);     { U+0644 ARABIC LETTER LAM }
+    XK_Arabic_meem           : exit($0645);     { U+0645 ARABIC LETTER MEEM }
+    XK_Arabic_noon           : exit($0646);     { U+0646 ARABIC LETTER NOON }
+    XK_Arabic_ha             : exit($0647);     { U+0647 ARABIC LETTER HEH }
+    XK_Arabic_waw            : exit($0648);     { U+0648 ARABIC LETTER WAW }
+    XK_Arabic_alefmaksura    : exit($0649);     { U+0649 ARABIC LETTER ALEF MAKSURA }
+    XK_Arabic_yeh            : exit($064A);     { U+064A ARABIC LETTER YEH }
+    XK_Arabic_fathatan       : exit($064B);     { U+064B ARABIC FATHATAN }
+    XK_Arabic_dammatan       : exit($064C);     { U+064C ARABIC DAMMATAN }
+    XK_Arabic_kasratan       : exit($064D);     { U+064D ARABIC KASRATAN }
+    XK_Arabic_fatha          : exit($064E);     { U+064E ARABIC FATHA }
+    XK_Arabic_damma          : exit($064F);     { U+064F ARABIC DAMMA }
+    XK_Arabic_kasra          : exit($0650);     { U+0650 ARABIC KASRA }
+    XK_Arabic_shadda         : exit($0651);     { U+0651 ARABIC SHADDA }
+    XK_Arabic_sukun          : exit($0652);     { U+0652 ARABIC SUKUN }
 
 
-    XK_Serbian_dje           : exit($452);
-    XK_Macedonia_gje         : exit($453);
-    XK_Cyrillic_io           : exit($451);
-    XK_Ukrainian_ie          : exit($454);
-    XK_Macedonia_dse         : exit($455);
-    XK_Ukrainian_i           : exit($456);
-    XK_Ukrainian_yi          : exit($457);
-    XK_Cyrillic_je           : exit($458);
-    XK_Cyrillic_lje          : exit($459);
-    XK_Cyrillic_nje          : exit($45A);
-    XK_Serbian_tshe          : exit($45B);
-    XK_Macedonia_kje         : exit($45C);
-    XK_Ukrainian_ghe_with_upturn: exit($491);
-    XK_Byelorussian_shortu   : exit($45E);
-    XK_Cyrillic_dzhe         : exit($45F);
-    XK_numerosign            : exit($2116);
-    XKc_Serbian_DJE          : exit($402);
-    XKc_Macedonia_GJE        : exit($403);
-    XKc_Cyrillic_IO          : exit($401);
-    XKc_Ukrainian_IE         : exit($404);
-    XKc_Macedonia_DSE        : exit($405);
-    XKc_Ukrainian_I          : exit($406);
-    XKc_Ukrainian_YI         : exit($407);
-    XKc_Cyrillic_JE          : exit($408);
-    XKc_Cyrillic_LJE         : exit($409);
-    XKc_Cyrillic_NJE         : exit($40A);
-    XKc_Serbian_TSHE         : exit($40B);
-    XKc_Macedonia_KJE        : exit($40C);
-    XKc_Ukrainian_GHE_WITH_UPTURN: exit($490);
-    XKc_Byelorussian_SHORTU  : exit($40E);
-    XKc_Cyrillic_DZHE        : exit($40F);
-    XK_Cyrillic_yu           : exit($44E);
-    XK_Cyrillic_a            : exit($430);
-    XK_Cyrillic_be           : exit($431);
-    XK_Cyrillic_tse          : exit($446);
-    XK_Cyrillic_de           : exit($434);
-    XK_Cyrillic_ie           : exit($435);
-    XK_Cyrillic_ef           : exit($444);
-    XK_Cyrillic_ghe          : exit($433);
-    XK_Cyrillic_ha           : exit($445);
-    XK_Cyrillic_i            : exit($438);
-    XK_Cyrillic_shorti       : exit($439);
-    XK_Cyrillic_ka           : exit($43A);
-    XK_Cyrillic_el           : exit($43B);
-    XK_Cyrillic_em           : exit($43C);
-    XK_Cyrillic_en           : exit($43D);
-    XK_Cyrillic_o            : exit($43E);
-    XK_Cyrillic_pe           : exit($43F);
-    XK_Cyrillic_ya           : exit($44F);
-    XK_Cyrillic_er           : exit($440);
-    XK_Cyrillic_es           : exit($441);
-    XK_Cyrillic_te           : exit($442);
-    XK_Cyrillic_u            : exit($443);
-    XK_Cyrillic_zhe          : exit($436);
-    XK_Cyrillic_ve           : exit($432);
-    XK_Cyrillic_softsign     : exit($44C);
-    XK_Cyrillic_yeru         : exit($44B);
-    XK_Cyrillic_ze           : exit($437);
-    XK_Cyrillic_sha          : exit($448);
-    XK_Cyrillic_e            : exit($44D);
-    XK_Cyrillic_shcha        : exit($449);
-    XK_Cyrillic_che          : exit($447);
-    XK_Cyrillic_hardsign     : exit($44A);
-    XKc_Cyrillic_YU          : exit($42E);
-    XKc_Cyrillic_A           : exit($410);
-    XKc_Cyrillic_BE          : exit($411);
-    XKc_Cyrillic_TSE         : exit($426);
-    XKc_Cyrillic_DE          : exit($414);
-    XKc_Cyrillic_IE          : exit($415);
-    XKc_Cyrillic_EF          : exit($424);
-    XKc_Cyrillic_GHE         : exit($413);
-    XKc_Cyrillic_HA          : exit($425);
-    XKc_Cyrillic_I           : exit($418);
-    XKc_Cyrillic_SHORTI      : exit($419);
-    XKc_Cyrillic_KA          : exit($41A);
-    XKc_Cyrillic_EL          : exit($41B);
-    XKc_Cyrillic_EM          : exit($41C);
-    XKc_Cyrillic_EN          : exit($41D);
-    XKc_Cyrillic_O           : exit($41E);
-    XKc_Cyrillic_PE          : exit($41F);
-    XKc_Cyrillic_YA          : exit($42F);
-    XKc_Cyrillic_ER          : exit($420);
-    XKc_Cyrillic_ES          : exit($421);
-    XKc_Cyrillic_TE          : exit($422);
-    XKc_Cyrillic_U           : exit($423);
-    XKc_Cyrillic_ZHE         : exit($416);
-    XKc_Cyrillic_VE          : exit($412);
-    XKc_Cyrillic_SOFTSIGN    : exit($42C);
-    XKc_Cyrillic_YERU        : exit($42B);
-    XKc_Cyrillic_ZE          : exit($417);
-    XKc_Cyrillic_SHA         : exit($428);
-    XKc_Cyrillic_E           : exit($42D);
-    XKc_Cyrillic_SHCHA       : exit($429);
-    XKc_Cyrillic_CHE         : exit($427);
-    XKc_Cyrillic_HARDSIGN    : exit($42A);
+    { Cyrillic }
+    XK_Serbian_dje                : exit($0452);  { U+0452 CYRILLIC SMALL LETTER DJE }
+    XK_Macedonia_gje              : exit($0453);  { U+0453 CYRILLIC SMALL LETTER GJE }
+    XK_Cyrillic_io                : exit($0451);  { U+0451 CYRILLIC SMALL LETTER IO }
+    XK_Ukrainian_ie               : exit($0454);  { U+0454 CYRILLIC SMALL LETTER UKRAINIAN IE }
+    XK_Macedonia_dse              : exit($0455);  { U+0455 CYRILLIC SMALL LETTER DZE }
+    XK_Ukrainian_i                : exit($0456);  { U+0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I }
+    XK_Ukrainian_yi               : exit($0457);  { U+0457 CYRILLIC SMALL LETTER YI }
+    XK_Cyrillic_je                : exit($0458);  { U+0458 CYRILLIC SMALL LETTER JE }
+    XK_Cyrillic_lje               : exit($0459);  { U+0459 CYRILLIC SMALL LETTER LJE }
+    XK_Cyrillic_nje               : exit($045A);  { U+045A CYRILLIC SMALL LETTER NJE }
+    XK_Serbian_tshe               : exit($045B);  { U+045B CYRILLIC SMALL LETTER TSHE }
+    XK_Macedonia_kje              : exit($045C);  { U+045C CYRILLIC SMALL LETTER KJE }
+    XK_Ukrainian_ghe_with_upturn  : exit($0491);  { U+0491 CYRILLIC SMALL LETTER GHE WITH UPTURN }
+    XK_Byelorussian_shortu        : exit($045E);  { U+045E CYRILLIC SMALL LETTER SHORT U }
+    XK_Cyrillic_dzhe              : exit($045F);  { U+045F CYRILLIC SMALL LETTER DZHE }
+    XK_numerosign                 : exit($2116);  { U+2116 NUMERO SIGN }
+    XKc_Serbian_DJE               : exit($0402);  { U+0402 CYRILLIC CAPITAL LETTER DJE }
+    XKc_Macedonia_GJE             : exit($0403);  { U+0403 CYRILLIC CAPITAL LETTER GJE }
+    XKc_Cyrillic_IO               : exit($0401);  { U+0401 CYRILLIC CAPITAL LETTER IO }
+    XKc_Ukrainian_IE              : exit($0404);  { U+0404 CYRILLIC CAPITAL LETTER UKRAINIAN IE }
+    XKc_Macedonia_DSE             : exit($0405);  { U+0405 CYRILLIC CAPITAL LETTER DZE }
+    XKc_Ukrainian_I               : exit($0406);  { U+0406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I }
+    XKc_Ukrainian_YI              : exit($0407);  { U+0407 CYRILLIC CAPITAL LETTER YI }
+    XKc_Cyrillic_JE               : exit($0408);  { U+0408 CYRILLIC CAPITAL LETTER JE }
+    XKc_Cyrillic_LJE              : exit($0409);  { U+0409 CYRILLIC CAPITAL LETTER LJE }
+    XKc_Cyrillic_NJE              : exit($040A);  { U+040A CYRILLIC CAPITAL LETTER NJE }
+    XKc_Serbian_TSHE              : exit($040B);  { U+040B CYRILLIC CAPITAL LETTER TSHE }
+    XKc_Macedonia_KJE             : exit($040C);  { U+040C CYRILLIC CAPITAL LETTER KJE }
+    XKc_Ukrainian_GHE_WITH_UPTURN : exit($0490);  { U+0490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN }
+    XKc_Byelorussian_SHORTU       : exit($040E);  { U+040E CYRILLIC CAPITAL LETTER SHORT U }
+    XKc_Cyrillic_DZHE             : exit($040F);  { U+040F CYRILLIC CAPITAL LETTER DZHE }
+    XK_Cyrillic_yu                : exit($044E);  { U+044E CYRILLIC SMALL LETTER YU }
+    XK_Cyrillic_a                 : exit($0430);  { U+0430 CYRILLIC SMALL LETTER A }
+    XK_Cyrillic_be                : exit($0431);  { U+0431 CYRILLIC SMALL LETTER BE }
+    XK_Cyrillic_tse               : exit($0446);  { U+0446 CYRILLIC SMALL LETTER TSE }
+    XK_Cyrillic_de                : exit($0434);  { U+0434 CYRILLIC SMALL LETTER DE }
+    XK_Cyrillic_ie                : exit($0435);  { U+0435 CYRILLIC SMALL LETTER IE }
+    XK_Cyrillic_ef                : exit($0444);  { U+0444 CYRILLIC SMALL LETTER EF }
+    XK_Cyrillic_ghe               : exit($0433);  { U+0433 CYRILLIC SMALL LETTER GHE }
+    XK_Cyrillic_ha                : exit($0445);  { U+0445 CYRILLIC SMALL LETTER HA }
+    XK_Cyrillic_i                 : exit($0438);  { U+0438 CYRILLIC SMALL LETTER I }
+    XK_Cyrillic_shorti            : exit($0439);  { U+0439 CYRILLIC SMALL LETTER SHORT I }
+    XK_Cyrillic_ka                : exit($043A);  { U+043A CYRILLIC SMALL LETTER KA }
+    XK_Cyrillic_el                : exit($043B);  { U+043B CYRILLIC SMALL LETTER EL }
+    XK_Cyrillic_em                : exit($043C);  { U+043C CYRILLIC SMALL LETTER EM }
+    XK_Cyrillic_en                : exit($043D);  { U+043D CYRILLIC SMALL LETTER EN }
+    XK_Cyrillic_o                 : exit($043E);  { U+043E CYRILLIC SMALL LETTER O }
+    XK_Cyrillic_pe                : exit($043F);  { U+043F CYRILLIC SMALL LETTER PE }
+    XK_Cyrillic_ya                : exit($044F);  { U+044F CYRILLIC SMALL LETTER YA }
+    XK_Cyrillic_er                : exit($0440);  { U+0440 CYRILLIC SMALL LETTER ER }
+    XK_Cyrillic_es                : exit($0441);  { U+0441 CYRILLIC SMALL LETTER ES }
+    XK_Cyrillic_te                : exit($0442);  { U+0442 CYRILLIC SMALL LETTER TE }
+    XK_Cyrillic_u                 : exit($0443);  { U+0443 CYRILLIC SMALL LETTER U }
+    XK_Cyrillic_zhe               : exit($0436);  { U+0436 CYRILLIC SMALL LETTER ZHE }
+    XK_Cyrillic_ve                : exit($0432);  { U+0432 CYRILLIC SMALL LETTER VE }
+    XK_Cyrillic_softsign          : exit($044C);  { U+044C CYRILLIC SMALL LETTER SOFT SIGN }
+    XK_Cyrillic_yeru              : exit($044B);  { U+044B CYRILLIC SMALL LETTER YERU }
+    XK_Cyrillic_ze                : exit($0437);  { U+0437 CYRILLIC SMALL LETTER ZE }
+    XK_Cyrillic_sha               : exit($0448);  { U+0448 CYRILLIC SMALL LETTER SHA }
+    XK_Cyrillic_e                 : exit($044D);  { U+044D CYRILLIC SMALL LETTER E }
+    XK_Cyrillic_shcha             : exit($0449);  { U+0449 CYRILLIC SMALL LETTER SHCHA }
+    XK_Cyrillic_che               : exit($0447);  { U+0447 CYRILLIC SMALL LETTER CHE }
+    XK_Cyrillic_hardsign          : exit($044A);  { U+044A CYRILLIC SMALL LETTER HARD SIGN }
+    XKc_Cyrillic_YU               : exit($042E);  { U+042E CYRILLIC CAPITAL LETTER YU }
+    XKc_Cyrillic_A                : exit($0410);  { U+0410 CYRILLIC CAPITAL LETTER A }
+    XKc_Cyrillic_BE               : exit($0411);  { U+0411 CYRILLIC CAPITAL LETTER BE }
+    XKc_Cyrillic_TSE              : exit($0426);  { U+0426 CYRILLIC CAPITAL LETTER TSE }
+    XKc_Cyrillic_DE               : exit($0414);  { U+0414 CYRILLIC CAPITAL LETTER DE }
+    XKc_Cyrillic_IE               : exit($0415);  { U+0415 CYRILLIC CAPITAL LETTER IE }
+    XKc_Cyrillic_EF               : exit($0424);  { U+0424 CYRILLIC CAPITAL LETTER EF }
+    XKc_Cyrillic_GHE              : exit($0413);  { U+0413 CYRILLIC CAPITAL LETTER GHE }
+    XKc_Cyrillic_HA               : exit($0425);  { U+0425 CYRILLIC CAPITAL LETTER HA }
+    XKc_Cyrillic_I                : exit($0418);  { U+0418 CYRILLIC CAPITAL LETTER I }
+    XKc_Cyrillic_SHORTI           : exit($0419);  { U+0419 CYRILLIC CAPITAL LETTER SHORT I }
+    XKc_Cyrillic_KA               : exit($041A);  { U+041A CYRILLIC CAPITAL LETTER KA }
+    XKc_Cyrillic_EL               : exit($041B);  { U+041B CYRILLIC CAPITAL LETTER EL }
+    XKc_Cyrillic_EM               : exit($041C);  { U+041C CYRILLIC CAPITAL LETTER EM }
+    XKc_Cyrillic_EN               : exit($041D);  { U+041D CYRILLIC CAPITAL LETTER EN }
+    XKc_Cyrillic_O                : exit($041E);  { U+041E CYRILLIC CAPITAL LETTER O }
+    XKc_Cyrillic_PE               : exit($041F);  { U+041F CYRILLIC CAPITAL LETTER PE }
+    XKc_Cyrillic_YA               : exit($042F);  { U+042F CYRILLIC CAPITAL LETTER YA }
+    XKc_Cyrillic_ER               : exit($0420);  { U+0420 CYRILLIC CAPITAL LETTER ER }
+    XKc_Cyrillic_ES               : exit($0421);  { U+0421 CYRILLIC CAPITAL LETTER ES }
+    XKc_Cyrillic_TE               : exit($0422);  { U+0422 CYRILLIC CAPITAL LETTER TE }
+    XKc_Cyrillic_U                : exit($0423);  { U+0423 CYRILLIC CAPITAL LETTER U }
+    XKc_Cyrillic_ZHE              : exit($0416);  { U+0416 CYRILLIC CAPITAL LETTER ZHE }
+    XKc_Cyrillic_VE               : exit($0412);  { U+0412 CYRILLIC CAPITAL LETTER VE }
+    XKc_Cyrillic_SOFTSIGN         : exit($042C);  { U+042C CYRILLIC CAPITAL LETTER SOFT SIGN }
+    XKc_Cyrillic_YERU             : exit($042B);  { U+042B CYRILLIC CAPITAL LETTER YERU }
+    XKc_Cyrillic_ZE               : exit($0417);  { U+0417 CYRILLIC CAPITAL LETTER ZE }
+    XKc_Cyrillic_SHA              : exit($0428);  { U+0428 CYRILLIC CAPITAL LETTER SHA }
+    XKc_Cyrillic_E                : exit($042D);  { U+042D CYRILLIC CAPITAL LETTER E }
+    XKc_Cyrillic_SHCHA            : exit($0429);  { U+0429 CYRILLIC CAPITAL LETTER SHCHA }
+    XKc_Cyrillic_CHE              : exit($0427);  { U+0427 CYRILLIC CAPITAL LETTER CHE }
+    XKc_Cyrillic_HARDSIGN         : exit($042A);  { U+042A CYRILLIC CAPITAL LETTER HARD SIGN }
 
 
-{    XKc_Greek_ALPHAaccent    : exit($);
-    XKc_Greek_EPSILONaccent  : exit($);
-    XKc_Greek_ETAaccent      : exit($);
-    XKc_Greek_IOTAaccent     : exit($);
-    XKc_Greek_IOTAdieresis   : exit($);
-    XKc_Greek_OMICRONaccent  : exit($);
-    XKc_Greek_UPSILONaccent  : exit($);
-    XKc_Greek_UPSILONdieresis: exit($);
-    XKc_Greek_OMEGAaccent    : exit($);
-    XK_Greek_accentdieresis  : exit($);
-    XK_Greek_horizbar        : exit($);
-    XK_Greek_alphaaccent     : exit($);
-    XK_Greek_epsilonaccent   : exit($);
-    XK_Greek_etaaccent       : exit($);
-    XK_Greek_iotaaccent      : exit($);
-    XK_Greek_iotadieresis    : exit($);
-    XK_Greek_iotaaccentdieresis: exit($);
-    XK_Greek_omicronaccent   : exit($);
-    XK_Greek_upsilonaccent   : exit($);
-    XK_Greek_upsilondieresis : exit($);
-    XK_Greek_upsilonaccentdieresis: exit($);
-    XK_Greek_omegaaccent     : exit($);}
-    XKc_Greek_ALPHA          : exit($391);
-    XKc_Greek_BETA           : exit($392);
-    XKc_Greek_GAMMA          : exit($393);
-    XKc_Greek_DELTA          : exit($394);
-    XKc_Greek_EPSILON        : exit($395);
-    XKc_Greek_ZETA           : exit($396);
-    XKc_Greek_ETA            : exit($397);
-    XKc_Greek_THETA          : exit($398);
-    XKc_Greek_IOTA           : exit($399);
-    XKc_Greek_KAPPA          : exit($39A);
-    XKc_Greek_LAMDA          : exit($39B);
-    XKc_Greek_MU             : exit($39C);
-    XKc_Greek_NU             : exit($39D);
-    XKc_Greek_XI             : exit($39E);
-    XKc_Greek_OMICRON        : exit($39F);
-    XKc_Greek_PI             : exit($3A0);
-    XKc_Greek_RHO            : exit($3A1);
-    XKc_Greek_SIGMA          : exit($3A3);
-    XKc_Greek_TAU            : exit($3A4);
-    XKc_Greek_UPSILON        : exit($3A5);
-    XKc_Greek_PHI            : exit($3A6);
-    XKc_Greek_CHI            : exit($3A7);
-    XKc_Greek_PSI            : exit($3A8);
-    XKc_Greek_OMEGA          : exit($3A9);
-    XK_Greek_alpha           : exit($3B1);
-    XK_Greek_beta            : exit($3B2);
-    XK_Greek_gamma           : exit($3B3);
-    XK_Greek_delta           : exit($3B4);
-    XK_Greek_epsilon         : exit($3B5);
-    XK_Greek_zeta            : exit($3B6);
-    XK_Greek_eta             : exit($3B7);
-    XK_Greek_theta           : exit($3B8);
-    XK_Greek_iota            : exit($3B9);
-    XK_Greek_kappa           : exit($3BA);
-    XK_Greek_lamda           : exit($3BB);
-    XK_Greek_mu              : exit($3BC);
-    XK_Greek_nu              : exit($3BD);
-    XK_Greek_xi              : exit($3BE);
-    XK_Greek_omicron         : exit($3BF);
-    XK_Greek_pi              : exit($3C0);
-    XK_Greek_rho             : exit($3C1);
-    XK_Greek_sigma           : exit($3C2);
-    XK_Greek_finalsmallsigma : exit($3C3);
-    XK_Greek_tau             : exit($3C4);
-    XK_Greek_upsilon         : exit($3C5);
-    XK_Greek_phi             : exit($3C6);
-    XK_Greek_chi             : exit($3C7);
-    XK_Greek_psi             : exit($3C8);
-    XK_Greek_omega           : exit($3C9);
+    { Greek }
+    XKc_Greek_ALPHAaccent          : exit($0386);  { U+0386 GREEK CAPITAL LETTER ALPHA WITH TONOS }
+    XKc_Greek_EPSILONaccent        : exit($0388);  { U+0388 GREEK CAPITAL LETTER EPSILON WITH TONOS }
+    XKc_Greek_ETAaccent            : exit($0389);  { U+0389 GREEK CAPITAL LETTER ETA WITH TONOS }
+    XKc_Greek_IOTAaccent           : exit($038A);  { U+038A GREEK CAPITAL LETTER IOTA WITH TONOS }
+    XKc_Greek_IOTAdieresis         : exit($03AA);  { U+03AA GREEK CAPITAL LETTER IOTA WITH DIALYTIKA }
+    XKc_Greek_OMICRONaccent        : exit($038C);  { U+038C GREEK CAPITAL LETTER OMICRON WITH TONOS }
+    XKc_Greek_UPSILONaccent        : exit($038E);  { U+038E GREEK CAPITAL LETTER UPSILON WITH TONOS }
+    XKc_Greek_UPSILONdieresis      : exit($03AB);  { U+03AB GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA }
+    XKc_Greek_OMEGAaccent          : exit($038F);  { U+038F GREEK CAPITAL LETTER OMEGA WITH TONOS }
+    XK_Greek_accentdieresis        : exit($0385);  { U+0385 GREEK DIALYTIKA TONOS }
+    XK_Greek_horizbar              : exit($2015);  { U+2015 HORIZONTAL BAR }
+    XK_Greek_alphaaccent           : exit($03AC);  { U+03AC GREEK SMALL LETTER ALPHA WITH TONOS }
+    XK_Greek_epsilonaccent         : exit($03AD);  { U+03AD GREEK SMALL LETTER EPSILON WITH TONOS }
+    XK_Greek_etaaccent             : exit($03AE);  { U+03AE GREEK SMALL LETTER ETA WITH TONOS }
+    XK_Greek_iotaaccent            : exit($03AF);  { U+03AF GREEK SMALL LETTER IOTA WITH TONOS }
+    XK_Greek_iotadieresis          : exit($03CA);  { U+03CA GREEK SMALL LETTER IOTA WITH DIALYTIKA }
+    XK_Greek_iotaaccentdieresis    : exit($0390);  { U+0390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS }
+    XK_Greek_omicronaccent         : exit($03CC);  { U+03CC GREEK SMALL LETTER OMICRON WITH TONOS }
+    XK_Greek_upsilonaccent         : exit($03CD);  { U+03CD GREEK SMALL LETTER UPSILON WITH TONOS }
+    XK_Greek_upsilondieresis       : exit($03CB);  { U+03CB GREEK SMALL LETTER UPSILON WITH DIALYTIKA }
+    XK_Greek_upsilonaccentdieresis : exit($03B0);  { U+03B0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS }
+    XK_Greek_omegaaccent           : exit($03CE);  { U+03CE GREEK SMALL LETTER OMEGA WITH TONOS }
+    XKc_Greek_ALPHA                : exit($0391);  { U+0391 GREEK CAPITAL LETTER ALPHA }
+    XKc_Greek_BETA                 : exit($0392);  { U+0392 GREEK CAPITAL LETTER BETA }
+    XKc_Greek_GAMMA                : exit($0393);  { U+0393 GREEK CAPITAL LETTER GAMMA }
+    XKc_Greek_DELTA                : exit($0394);  { U+0394 GREEK CAPITAL LETTER DELTA }
+    XKc_Greek_EPSILON              : exit($0395);  { U+0395 GREEK CAPITAL LETTER EPSILON }
+    XKc_Greek_ZETA                 : exit($0396);  { U+0396 GREEK CAPITAL LETTER ZETA }
+    XKc_Greek_ETA                  : exit($0397);  { U+0397 GREEK CAPITAL LETTER ETA }
+    XKc_Greek_THETA                : exit($0398);  { U+0398 GREEK CAPITAL LETTER THETA }
+    XKc_Greek_IOTA                 : exit($0399);  { U+0399 GREEK CAPITAL LETTER IOTA }
+    XKc_Greek_KAPPA                : exit($039A);  { U+039A GREEK CAPITAL LETTER KAPPA }
+    XKc_Greek_LAMDA                : exit($039B);  { U+039B GREEK CAPITAL LETTER LAMDA }
+    XKc_Greek_MU                   : exit($039C);  { U+039C GREEK CAPITAL LETTER MU }
+    XKc_Greek_NU                   : exit($039D);  { U+039D GREEK CAPITAL LETTER NU }
+    XKc_Greek_XI                   : exit($039E);  { U+039E GREEK CAPITAL LETTER XI }
+    XKc_Greek_OMICRON              : exit($039F);  { U+039F GREEK CAPITAL LETTER OMICRON }
+    XKc_Greek_PI                   : exit($03A0);  { U+03A0 GREEK CAPITAL LETTER PI }
+    XKc_Greek_RHO                  : exit($03A1);  { U+03A1 GREEK CAPITAL LETTER RHO }
+    XKc_Greek_SIGMA                : exit($03A3);  { U+03A3 GREEK CAPITAL LETTER SIGMA }
+    XKc_Greek_TAU                  : exit($03A4);  { U+03A4 GREEK CAPITAL LETTER TAU }
+    XKc_Greek_UPSILON              : exit($03A5);  { U+03A5 GREEK CAPITAL LETTER UPSILON }
+    XKc_Greek_PHI                  : exit($03A6);  { U+03A6 GREEK CAPITAL LETTER PHI }
+    XKc_Greek_CHI                  : exit($03A7);  { U+03A7 GREEK CAPITAL LETTER CHI }
+    XKc_Greek_PSI                  : exit($03A8);  { U+03A8 GREEK CAPITAL LETTER PSI }
+    XKc_Greek_OMEGA                : exit($03A9);  { U+03A9 GREEK CAPITAL LETTER OMEGA }
+    XK_Greek_alpha                 : exit($03B1);  { U+03B1 GREEK SMALL LETTER ALPHA }
+    XK_Greek_beta                  : exit($03B2);  { U+03B2 GREEK SMALL LETTER BETA }
+    XK_Greek_gamma                 : exit($03B3);  { U+03B3 GREEK SMALL LETTER GAMMA }
+    XK_Greek_delta                 : exit($03B4);  { U+03B4 GREEK SMALL LETTER DELTA }
+    XK_Greek_epsilon               : exit($03B5);  { U+03B5 GREEK SMALL LETTER EPSILON }
+    XK_Greek_zeta                  : exit($03B6);  { U+03B6 GREEK SMALL LETTER ZETA }
+    XK_Greek_eta                   : exit($03B7);  { U+03B7 GREEK SMALL LETTER ETA }
+    XK_Greek_theta                 : exit($03B8);  { U+03B8 GREEK SMALL LETTER THETA }
+    XK_Greek_iota                  : exit($03B9);  { U+03B9 GREEK SMALL LETTER IOTA }
+    XK_Greek_kappa                 : exit($03BA);  { U+03BA GREEK SMALL LETTER KAPPA }
+    XK_Greek_lamda                 : exit($03BB);  { U+03BB GREEK SMALL LETTER LAMDA }
+    XK_Greek_mu                    : exit($03BC);  { U+03BC GREEK SMALL LETTER MU }
+    XK_Greek_nu                    : exit($03BD);  { U+03BD GREEK SMALL LETTER NU }
+    XK_Greek_xi                    : exit($03BE);  { U+03BE GREEK SMALL LETTER XI }
+    XK_Greek_omicron               : exit($03BF);  { U+03BF GREEK SMALL LETTER OMICRON }
+    XK_Greek_pi                    : exit($03C0);  { U+03C0 GREEK SMALL LETTER PI }
+    XK_Greek_rho                   : exit($03C1);  { U+03C1 GREEK SMALL LETTER RHO }
+    XK_Greek_sigma                 : exit($03C2);  { U+03C3 GREEK SMALL LETTER SIGMA }
+    XK_Greek_finalsmallsigma       : exit($03C3);  { U+03C2 GREEK SMALL LETTER FINAL SIGMA }
+    XK_Greek_tau                   : exit($03C4);  { U+03C4 GREEK SMALL LETTER TAU }
+    XK_Greek_upsilon               : exit($03C5);  { U+03C5 GREEK SMALL LETTER UPSILON }
+    XK_Greek_phi                   : exit($03C6);  { U+03C6 GREEK SMALL LETTER PHI }
+    XK_Greek_chi                   : exit($03C7);  { U+03C7 GREEK SMALL LETTER CHI }
+    XK_Greek_psi                   : exit($03C8);  { U+03C8 GREEK SMALL LETTER PSI }
+    XK_Greek_omega                 : exit($03C9);  { U+03C9 GREEK SMALL LETTER OMEGA }
+
+    { Technical }
+    XK_leftradical               : exit($23B7);  { U+23B7 RADICAL SYMBOL BOTTOM }
+    XK_topleftradical            : exit($250C);  {(U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT)}
+    XK_horizconnector            : exit($2500);  {(U+2500 BOX DRAWINGS LIGHT HORIZONTAL)}
+    XK_topintegral               : exit($2320);  { U+2320 TOP HALF INTEGRAL }
+    XK_botintegral               : exit($2321);  { U+2321 BOTTOM HALF INTEGRAL }
+    XK_vertconnector             : exit($2502);  {(U+2502 BOX DRAWINGS LIGHT VERTICAL)}
+    XK_topleftsqbracket          : exit($23A1);  { U+23A1 LEFT SQUARE BRACKET UPPER CORNER }
+    XK_botleftsqbracket          : exit($23A3);  { U+23A3 LEFT SQUARE BRACKET LOWER CORNER }
+    XK_toprightsqbracket         : exit($23A4);  { U+23A4 RIGHT SQUARE BRACKET UPPER CORNER }
+    XK_botrightsqbracket         : exit($23A6);  { U+23A6 RIGHT SQUARE BRACKET LOWER CORNER }
+    XK_topleftparens             : exit($239B);  { U+239B LEFT PARENTHESIS UPPER HOOK }
+    XK_botleftparens             : exit($239D);  { U+239D LEFT PARENTHESIS LOWER HOOK }
+    XK_toprightparens            : exit($239E);  { U+239E RIGHT PARENTHESIS UPPER HOOK }
+    XK_botrightparens            : exit($23A0);  { U+23A0 RIGHT PARENTHESIS LOWER HOOK }
+    XK_leftmiddlecurlybrace      : exit($23A8);  { U+23A8 LEFT CURLY BRACKET MIDDLE PIECE }
+    XK_rightmiddlecurlybrace     : exit($23AC);  { U+23AC RIGHT CURLY BRACKET MIDDLE PIECE }
+{    XK_topleftsummation          : exit($);
+    XK_botleftsummation          : exit($);
+    XK_topvertsummationconnector : exit($);
+    XK_botvertsummationconnector : exit($);
+    XK_toprightsummation         : exit($);
+    XK_botrightsummation         : exit($);
+    XK_rightmiddlesummation      : exit($);}
+    XK_lessthanequal             : exit($2264);  { U+2264 LESS-THAN OR EQUAL TO }
+    XK_notequal                  : exit($2260);  { U+2260 NOT EQUAL TO }
+    XK_greaterthanequal          : exit($2265);  { U+2265 GREATER-THAN OR EQUAL TO }
+    XK_integral                  : exit($222B);  { U+222B INTEGRAL }
+    XK_therefore                 : exit($2234);  { U+2234 THEREFORE }
+    XK_variation                 : exit($221D);  { U+221D PROPORTIONAL TO }
+    XK_infinity                  : exit($221E);  { U+221E INFINITY }
+    XK_nabla                     : exit($2207);  { U+2207 NABLA }
+    XK_approximate               : exit($223C);  { U+223C TILDE OPERATOR }
+    XK_similarequal              : exit($2243);  { U+2243 ASYMPTOTICALLY EQUAL TO }
+    XK_ifonlyif                  : exit($21D4);  { U+21D4 LEFT RIGHT DOUBLE ARROW }
+    XK_implies                   : exit($21D2);  { U+21D2 RIGHTWARDS DOUBLE ARROW }
+    XK_identical                 : exit($2261);  { U+2261 IDENTICAL TO }
+    XK_radical                   : exit($221A);  { U+221A SQUARE ROOT }
+    XK_includedin                : exit($2282);  { U+2282 SUBSET OF }
+    XK_includes                  : exit($2283);  { U+2283 SUPERSET OF }
+    XK_intersection              : exit($2229);  { U+2229 INTERSECTION }
+    XK_union                     : exit($222A);  { U+222A UNION }
+    XK_logicaland                : exit($2227);  { U+2227 LOGICAL AND }
+    XK_logicalor                 : exit($2228);  { U+2228 LOGICAL OR }
+    XK_partialderivative         : exit($2202);  { U+2202 PARTIAL DIFFERENTIAL }
+    XK_function                  : exit($0192);  { U+0192 LATIN SMALL LETTER F WITH HOOK }
+    XK_leftarrow                 : exit($2190);  { U+2190 LEFTWARDS ARROW }
+    XK_uparrow                   : exit($2191);  { U+2191 UPWARDS ARROW }
+    XK_rightarrow                : exit($2192);  { U+2192 RIGHTWARDS ARROW }
+    XK_downarrow                 : exit($2193);  { U+2193 DOWNWARDS ARROW }
+
+    { Special }
+{    XK_blank          : exit($);}
+    XK_soliddiamond   : exit($25C6);  { U+25C6 BLACK DIAMOND }
+    XK_checkerboard   : exit($2592);  { U+2592 MEDIUM SHADE }
+    XK_ht             : exit($2409);  { U+2409 SYMBOL FOR HORIZONTAL TABULATION }
+    XK_ff             : exit($240C);  { U+240C SYMBOL FOR FORM FEED }
+    XK_cr             : exit($240D);  { U+240D SYMBOL FOR CARRIAGE RETURN }
+    XK_lf             : exit($240A);  { U+240A SYMBOL FOR LINE FEED }
+    XK_nl             : exit($2424);  { U+2424 SYMBOL FOR NEWLINE }
+    XK_vt             : exit($240B);  { U+240B SYMBOL FOR VERTICAL TABULATION }
+    XK_lowrightcorner : exit($2518);  { U+2518 BOX DRAWINGS LIGHT UP AND LEFT }
+    XK_uprightcorner  : exit($2510);  { U+2510 BOX DRAWINGS LIGHT DOWN AND LEFT }
+    XK_upleftcorner   : exit($250C);  { U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT }
+    XK_lowleftcorner  : exit($2514);  { U+2514 BOX DRAWINGS LIGHT UP AND RIGHT }
+    XK_crossinglines  : exit($253C);  { U+253C BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL }
+    XK_horizlinescan1 : exit($23BA);  { U+23BA HORIZONTAL SCAN LINE-1 }
+    XK_horizlinescan3 : exit($23BB);  { U+23BB HORIZONTAL SCAN LINE-3 }
+    XK_horizlinescan5 : exit($2500);  { U+2500 BOX DRAWINGS LIGHT HORIZONTAL }
+    XK_horizlinescan7 : exit($23BC);  { U+23BC HORIZONTAL SCAN LINE-7 }
+    XK_horizlinescan9 : exit($23BD);  { U+23BD HORIZONTAL SCAN LINE-9 }
+    XK_leftt          : exit($251C);  { U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT }
+    XK_rightt         : exit($2524);  { U+2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT }
+    XK_bott           : exit($2534);  { U+2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL }
+    XK_topt           : exit($252C);  { U+252C BOX DRAWINGS LIGHT DOWN AND HORIZONTAL }
+    XK_vertbar        : exit($2502);  { U+2502 BOX DRAWINGS LIGHT VERTICAL }
+
+    { Publishing }
+    XK_emspace              : exit($2003);  { U+2003 EM SPACE }
+    XK_enspace              : exit($2002);  { U+2002 EN SPACE }
+    XK_em3space             : exit($2004);  { U+2004 THREE-PER-EM SPACE }
+    XK_em4space             : exit($2005);  { U+2005 FOUR-PER-EM SPACE }
+    XK_digitspace           : exit($2007);  { U+2007 FIGURE SPACE }
+    XK_punctspace           : exit($2008);  { U+2008 PUNCTUATION SPACE }
+    XK_thinspace            : exit($2009);  { U+2009 THIN SPACE }
+    XK_hairspace            : exit($200A);  { U+200A HAIR SPACE }
+    XK_emdash               : exit($2014);  { U+2014 EM DASH }
+    XK_endash               : exit($2013);  { U+2013 EN DASH }
+    XK_signifblank          : exit($2423);  {(U+2423 OPEN BOX)}
+    XK_ellipsis             : exit($2026);  { U+2026 HORIZONTAL ELLIPSIS }
+    XK_doubbaselinedot      : exit($2025);  { U+2025 TWO DOT LEADER }
+    XK_onethird             : exit($2153);  { U+2153 VULGAR FRACTION ONE THIRD }
+    XK_twothirds            : exit($2154);  { U+2154 VULGAR FRACTION TWO THIRDS }
+    XK_onefifth             : exit($2155);  { U+2155 VULGAR FRACTION ONE FIFTH }
+    XK_twofifths            : exit($2156);  { U+2156 VULGAR FRACTION TWO FIFTHS }
+    XK_threefifths          : exit($2157);  { U+2157 VULGAR FRACTION THREE FIFTHS }
+    XK_fourfifths           : exit($2158);  { U+2158 VULGAR FRACTION FOUR FIFTHS }
+    XK_onesixth             : exit($2159);  { U+2159 VULGAR FRACTION ONE SIXTH }
+    XK_fivesixths           : exit($215A);  { U+215A VULGAR FRACTION FIVE SIXTHS }
+    XK_careof               : exit($2105);  { U+2105 CARE OF }
+    XK_figdash              : exit($2012);  { U+2012 FIGURE DASH }
+    XK_leftanglebracket     : exit($27E8);  {(U+27E8 MATHEMATICAL LEFT ANGLE BRACKET)}
+    XK_decimalpoint         : exit($002E);  {(U+002E FULL STOP)}
+    XK_rightanglebracket    : exit($27E9);  {(U+27E9 MATHEMATICAL RIGHT ANGLE BRACKET)}
+{    XK_marker               : exit($);}
+    XK_oneeighth            : exit($215B);  { U+215B VULGAR FRACTION ONE EIGHTH }
+    XK_threeeighths         : exit($215C);  { U+215C VULGAR FRACTION THREE EIGHTHS }
+    XK_fiveeighths          : exit($215D);  { U+215D VULGAR FRACTION FIVE EIGHTHS }
+    XK_seveneighths         : exit($215E);  { U+215E VULGAR FRACTION SEVEN EIGHTHS }
+    XK_trademark            : exit($2122);  { U+2122 TRADE MARK SIGN }
+    XK_signaturemark        : exit($2613);  {(U+2613 SALTIRE)}
+{    XK_trademarkincircle    : exit($);}
+    XK_leftopentriangle     : exit($25C1);  {(U+25C1 WHITE LEFT-POINTING TRIANGLE)}
+    XK_rightopentriangle    : exit($25B7);  {(U+25B7 WHITE RIGHT-POINTING TRIANGLE)}
+    XK_emopencircle         : exit($25CB);  {(U+25CB WHITE CIRCLE)}
+    XK_emopenrectangle      : exit($25AF);  {(U+25AF WHITE VERTICAL RECTANGLE)}
+    XK_leftsinglequotemark  : exit($2018);  { U+2018 LEFT SINGLE QUOTATION MARK }
+    XK_rightsinglequotemark : exit($2019);  { U+2019 RIGHT SINGLE QUOTATION MARK }
+    XK_leftdoublequotemark  : exit($201C);  { U+201C LEFT DOUBLE QUOTATION MARK }
+    XK_rightdoublequotemark : exit($201D);  { U+201D RIGHT DOUBLE QUOTATION MARK }
+    XK_prescription         : exit($211E);  { U+211E PRESCRIPTION TAKE }
+    XK_permille             : exit($2030);  { U+2030 PER MILLE SIGN }
+    XK_minutes              : exit($2032);  { U+2032 PRIME }
+    XK_seconds              : exit($2033);  { U+2033 DOUBLE PRIME }
+    XK_latincross           : exit($271D);  { U+271D LATIN CROSS }
+{    XK_hexagram             : exit($);}
+    XK_filledrectbullet     : exit($25AC);  {(U+25AC BLACK RECTANGLE)}
+    XK_filledlefttribullet  : exit($25C0);  {(U+25C0 BLACK LEFT-POINTING TRIANGLE)}
+    XK_filledrighttribullet : exit($25B6);  {(U+25B6 BLACK RIGHT-POINTING TRIANGLE)}
+    XK_emfilledcircle       : exit($25CF);  {(U+25CF BLACK CIRCLE)}
+    XK_emfilledrect         : exit($25AE);  {(U+25AE BLACK VERTICAL RECTANGLE)}
+    XK_enopencircbullet     : exit($25E6);  {(U+25E6 WHITE BULLET)}
+    XK_enopensquarebullet   : exit($25AB);  {(U+25AB WHITE SMALL SQUARE)}
+    XK_openrectbullet       : exit($25AD);  {(U+25AD WHITE RECTANGLE)}
+    XK_opentribulletup      : exit($25B3);  {(U+25B3 WHITE UP-POINTING TRIANGLE)}
+    XK_opentribulletdown    : exit($25BD);  {(U+25BD WHITE DOWN-POINTING TRIANGLE)}
+    XK_openstar             : exit($2606);  {(U+2606 WHITE STAR)}
+    XK_enfilledcircbullet   : exit($2022);  {(U+2022 BULLET)}
+    XK_enfilledsqbullet     : exit($25AA);  {(U+25AA BLACK SMALL SQUARE)}
+    XK_filledtribulletup    : exit($25B2);  {(U+25B2 BLACK UP-POINTING TRIANGLE)}
+    XK_filledtribulletdown  : exit($25BC);  {(U+25BC BLACK DOWN-POINTING TRIANGLE)}
+    XK_leftpointer          : exit($261C);  {(U+261C WHITE LEFT POINTING INDEX)}
+    XK_rightpointer         : exit($261E);  {(U+261E WHITE RIGHT POINTING INDEX)}
+    XK_club                 : exit($2663);  { U+2663 BLACK CLUB SUIT }
+    XK_diamond              : exit($2666);  { U+2666 BLACK DIAMOND SUIT }
+    XK_heart                : exit($2665);  { U+2665 BLACK HEART SUIT }
+    XK_maltesecross         : exit($2720);  { U+2720 MALTESE CROSS }
+    XK_dagger               : exit($2020);  { U+2020 DAGGER }
+    XK_doubledagger         : exit($2021);  { U+2021 DOUBLE DAGGER }
+    XK_checkmark            : exit($2713);  { U+2713 CHECK MARK }
+    XK_ballotcross          : exit($2717);  { U+2717 BALLOT X }
+    XK_musicalsharp         : exit($266F);  { U+266F MUSIC SHARP SIGN }
+    XK_musicalflat          : exit($266D);  { U+266D MUSIC FLAT SIGN }
+    XK_malesymbol           : exit($2642);  { U+2642 MALE SIGN }
+    XK_femalesymbol         : exit($2640);  { U+2640 FEMALE SIGN }
+    XK_telephone            : exit($260E);  { U+260E BLACK TELEPHONE }
+    XK_telephonerecorder    : exit($2315);  { U+2315 TELEPHONE RECORDER }
+    XK_phonographcopyright  : exit($2117);  { U+2117 SOUND RECORDING COPYRIGHT }
+    XK_caret                : exit($2038);  { U+2038 CARET }
+    XK_singlelowquotemark   : exit($201A);  { U+201A SINGLE LOW-9 QUOTATION MARK }
+    XK_doublelowquotemark   : exit($201E);  { U+201E DOUBLE LOW-9 QUOTATION MARK }
+{    XK_cursor               : exit($);}
+
+    { APL }
+    XK_leftcaret  : exit($003C);  {(U+003C LESS-THAN SIGN)}
+    XK_rightcaret : exit($003E);  {(U+003E GREATER-THAN SIGN)}
+    XK_downcaret  : exit($2228);  {(U+2228 LOGICAL OR)}
+    XK_upcaret    : exit($2227);  {(U+2227 LOGICAL AND)}
+    XK_overbar    : exit($00AF);  {(U+00AF MACRON)}
+    XK_downtack   : exit($22A4);  { U+22A4 DOWN TACK }
+    XK_upshoe     : exit($2229);  {(U+2229 INTERSECTION)}
+    XK_downstile  : exit($230A);  { U+230A LEFT FLOOR }
+    XK_underbar   : exit($005F);  {(U+005F LOW LINE)}
+    XK_jot        : exit($2218);  { U+2218 RING OPERATOR }
+    XK_quad       : exit($2395);  { U+2395 APL FUNCTIONAL SYMBOL QUAD }
+    XK_uptack     : exit($22A5);  { U+22A5 UP TACK }
+    XK_circle     : exit($25CB);  { U+25CB WHITE CIRCLE }
+    XK_upstile    : exit($2308);  { U+2308 LEFT CEILING }
+    XK_downshoe   : exit($222A);  {(U+222A UNION)}
+    XK_rightshoe  : exit($2283);  {(U+2283 SUPERSET OF)}
+    XK_leftshoe   : exit($2282);  {(U+2282 SUBSET OF)}
+    XK_lefttack   : exit($22A3);  { U+22A3 LEFT TACK }
+    XK_righttack  : exit($22A2);  { U+22A2 RIGHT TACK }
+
+    { Hebrew }
+    XK_hebrew_doublelowline : exit($2017);  { U+2017 DOUBLE LOW LINE }
+    XK_hebrew_aleph         : exit($05D0);  { U+05D0 HEBREW LETTER ALEF }
+    XK_hebrew_bet           : exit($05D1);  { U+05D1 HEBREW LETTER BET }
+    XK_hebrew_gimel         : exit($05D2);  { U+05D2 HEBREW LETTER GIMEL }
+    XK_hebrew_dalet         : exit($05D3);  { U+05D3 HEBREW LETTER DALET }
+    XK_hebrew_he            : exit($05D4);  { U+05D4 HEBREW LETTER HE }
+    XK_hebrew_waw           : exit($05D5);  { U+05D5 HEBREW LETTER VAV }
+    XK_hebrew_zain          : exit($05D6);  { U+05D6 HEBREW LETTER ZAYIN }
+    XK_hebrew_chet          : exit($05D7);  { U+05D7 HEBREW LETTER HET }
+    XK_hebrew_tet           : exit($05D8);  { U+05D8 HEBREW LETTER TET }
+    XK_hebrew_yod           : exit($05D9);  { U+05D9 HEBREW LETTER YOD }
+    XK_hebrew_finalkaph     : exit($05DA);  { U+05DA HEBREW LETTER FINAL KAF }
+    XK_hebrew_kaph          : exit($05DB);  { U+05DB HEBREW LETTER KAF }
+    XK_hebrew_lamed         : exit($05DC);  { U+05DC HEBREW LETTER LAMED }
+    XK_hebrew_finalmem      : exit($05DD);  { U+05DD HEBREW LETTER FINAL MEM }
+    XK_hebrew_mem           : exit($05DE);  { U+05DE HEBREW LETTER MEM }
+    XK_hebrew_finalnun      : exit($05DF);  { U+05DF HEBREW LETTER FINAL NUN }
+    XK_hebrew_nun           : exit($05E0);  { U+05E0 HEBREW LETTER NUN }
+    XK_hebrew_samech        : exit($05E1);  { U+05E1 HEBREW LETTER SAMEKH }
+    XK_hebrew_ayin          : exit($05E2);  { U+05E2 HEBREW LETTER AYIN }
+    XK_hebrew_finalpe       : exit($05E3);  { U+05E3 HEBREW LETTER FINAL PE }
+    XK_hebrew_pe            : exit($05E4);  { U+05E4 HEBREW LETTER PE }
+    XK_hebrew_finalzade     : exit($05E5);  { U+05E5 HEBREW LETTER FINAL TSADI }
+    XK_hebrew_zade          : exit($05E6);  { U+05E6 HEBREW LETTER TSADI }
+    XK_hebrew_qoph          : exit($05E7);  { U+05E7 HEBREW LETTER QOF }
+    XK_hebrew_resh          : exit($05E8);  { U+05E8 HEBREW LETTER RESH }
+    XK_hebrew_shin          : exit($05E9);  { U+05E9 HEBREW LETTER SHIN }
+    XK_hebrew_taw           : exit($05EA);  { U+05EA HEBREW LETTER TAV }
+
+    { Thai }
+    XK_Thai_kokai             : exit($0E01);  { U+0E01 THAI CHARACTER KO KAI }
+    XK_Thai_khokhai           : exit($0E02);  { U+0E02 THAI CHARACTER KHO KHAI }
+    XK_Thai_khokhuat          : exit($0E03);  { U+0E03 THAI CHARACTER KHO KHUAT }
+    XK_Thai_khokhwai          : exit($0E04);  { U+0E04 THAI CHARACTER KHO KHWAI }
+    XK_Thai_khokhon           : exit($0E05);  { U+0E05 THAI CHARACTER KHO KHON }
+    XK_Thai_khorakhang        : exit($0E06);  { U+0E06 THAI CHARACTER KHO RAKHANG }
+    XK_Thai_ngongu            : exit($0E07);  { U+0E07 THAI CHARACTER NGO NGU }
+    XK_Thai_chochan           : exit($0E08);  { U+0E08 THAI CHARACTER CHO CHAN }
+    XK_Thai_choching          : exit($0E09);  { U+0E09 THAI CHARACTER CHO CHING }
+    XK_Thai_chochang          : exit($0E0A);  { U+0E0A THAI CHARACTER CHO CHANG }
+    XK_Thai_soso              : exit($0E0B);  { U+0E0B THAI CHARACTER SO SO }
+    XK_Thai_chochoe           : exit($0E0C);  { U+0E0C THAI CHARACTER CHO CHOE }
+    XK_Thai_yoying            : exit($0E0D);  { U+0E0D THAI CHARACTER YO YING }
+    XK_Thai_dochada           : exit($0E0E);  { U+0E0E THAI CHARACTER DO CHADA }
+    XK_Thai_topatak           : exit($0E0F);  { U+0E0F THAI CHARACTER TO PATAK }
+    XK_Thai_thothan           : exit($0E10);  { U+0E10 THAI CHARACTER THO THAN }
+    XK_Thai_thonangmontho     : exit($0E11);  { U+0E11 THAI CHARACTER THO NANGMONTHO }
+    XK_Thai_thophuthao        : exit($0E12);  { U+0E12 THAI CHARACTER THO PHUTHAO }
+    XK_Thai_nonen             : exit($0E13);  { U+0E13 THAI CHARACTER NO NEN }
+    XK_Thai_dodek             : exit($0E14);  { U+0E14 THAI CHARACTER DO DEK }
+    XK_Thai_totao             : exit($0E15);  { U+0E15 THAI CHARACTER TO TAO }
+    XK_Thai_thothung          : exit($0E16);  { U+0E16 THAI CHARACTER THO THUNG }
+    XK_Thai_thothahan         : exit($0E17);  { U+0E17 THAI CHARACTER THO THAHAN }
+    XK_Thai_thothong          : exit($0E18);  { U+0E18 THAI CHARACTER THO THONG }
+    XK_Thai_nonu              : exit($0E19);  { U+0E19 THAI CHARACTER NO NU }
+    XK_Thai_bobaimai          : exit($0E1A);  { U+0E1A THAI CHARACTER BO BAIMAI }
+    XK_Thai_popla             : exit($0E1B);  { U+0E1B THAI CHARACTER PO PLA }
+    XK_Thai_phophung          : exit($0E1C);  { U+0E1C THAI CHARACTER PHO PHUNG }
+    XK_Thai_fofa              : exit($0E1D);  { U+0E1D THAI CHARACTER FO FA }
+    XK_Thai_phophan           : exit($0E1E);  { U+0E1E THAI CHARACTER PHO PHAN }
+    XK_Thai_fofan             : exit($0E1F);  { U+0E1F THAI CHARACTER FO FAN }
+    XK_Thai_phosamphao        : exit($0E20);  { U+0E20 THAI CHARACTER PHO SAMPHAO }
+    XK_Thai_moma              : exit($0E21);  { U+0E21 THAI CHARACTER MO MA }
+    XK_Thai_yoyak             : exit($0E22);  { U+0E22 THAI CHARACTER YO YAK }
+    XK_Thai_rorua             : exit($0E23);  { U+0E23 THAI CHARACTER RO RUA }
+    XK_Thai_ru                : exit($0E24);  { U+0E24 THAI CHARACTER RU }
+    XK_Thai_loling            : exit($0E25);  { U+0E25 THAI CHARACTER LO LING }
+    XK_Thai_lu                : exit($0E26);  { U+0E26 THAI CHARACTER LU }
+    XK_Thai_wowaen            : exit($0E27);  { U+0E27 THAI CHARACTER WO WAEN }
+    XK_Thai_sosala            : exit($0E28);  { U+0E28 THAI CHARACTER SO SALA }
+    XK_Thai_sorusi            : exit($0E29);  { U+0E29 THAI CHARACTER SO RUSI }
+    XK_Thai_sosua             : exit($0E2A);  { U+0E2A THAI CHARACTER SO SUA }
+    XK_Thai_hohip             : exit($0E2B);  { U+0E2B THAI CHARACTER HO HIP }
+    XK_Thai_lochula           : exit($0E2C);  { U+0E2C THAI CHARACTER LO CHULA }
+    XK_Thai_oang              : exit($0E2D);  { U+0E2D THAI CHARACTER O ANG }
+    XK_Thai_honokhuk          : exit($0E2E);  { U+0E2E THAI CHARACTER HO NOKHUK }
+    XK_Thai_paiyannoi         : exit($0E2F);  { U+0E2F THAI CHARACTER PAIYANNOI }
+    XK_Thai_saraa             : exit($0E30);  { U+0E30 THAI CHARACTER SARA A }
+    XK_Thai_maihanakat        : exit($0E31);  { U+0E31 THAI CHARACTER MAI HAN-AKAT }
+    XK_Thai_saraaa            : exit($0E32);  { U+0E32 THAI CHARACTER SARA AA }
+    XK_Thai_saraam            : exit($0E33);  { U+0E33 THAI CHARACTER SARA AM }
+    XK_Thai_sarai             : exit($0E34);  { U+0E34 THAI CHARACTER SARA I }
+    XK_Thai_saraii            : exit($0E35);  { U+0E35 THAI CHARACTER SARA II }
+    XK_Thai_saraue            : exit($0E36);  { U+0E36 THAI CHARACTER SARA UE }
+    XK_Thai_sarauee           : exit($0E37);  { U+0E37 THAI CHARACTER SARA UEE }
+    XK_Thai_sarau             : exit($0E38);  { U+0E38 THAI CHARACTER SARA U }
+    XK_Thai_sarauu            : exit($0E39);  { U+0E39 THAI CHARACTER SARA UU }
+    XK_Thai_phinthu           : exit($0E3A);  { U+0E3A THAI CHARACTER PHINTHU }
+{    XK_Thai_maihanakat_maitho : exit($);}
+    XK_Thai_baht              : exit($0E3F);  { U+0E3F THAI CURRENCY SYMBOL BAHT }
+    XK_Thai_sarae             : exit($0E40);  { U+0E40 THAI CHARACTER SARA E }
+    XK_Thai_saraae            : exit($0E41);  { U+0E41 THAI CHARACTER SARA AE }
+    XK_Thai_sarao             : exit($0E42);  { U+0E42 THAI CHARACTER SARA O }
+    XK_Thai_saraaimaimuan     : exit($0E43);  { U+0E43 THAI CHARACTER SARA AI MAIMUAN }
+    XK_Thai_saraaimaimalai    : exit($0E44);  { U+0E44 THAI CHARACTER SARA AI MAIMALAI }
+    XK_Thai_lakkhangyao       : exit($0E45);  { U+0E45 THAI CHARACTER LAKKHANGYAO }
+    XK_Thai_maiyamok          : exit($0E46);  { U+0E46 THAI CHARACTER MAIYAMOK }
+    XK_Thai_maitaikhu         : exit($0E47);  { U+0E47 THAI CHARACTER MAITAIKHU }
+    XK_Thai_maiek             : exit($0E48);  { U+0E48 THAI CHARACTER MAI EK }
+    XK_Thai_maitho            : exit($0E49);  { U+0E49 THAI CHARACTER MAI THO }
+    XK_Thai_maitri            : exit($0E4A);  { U+0E4A THAI CHARACTER MAI TRI }
+    XK_Thai_maichattawa       : exit($0E4B);  { U+0E4B THAI CHARACTER MAI CHATTAWA }
+    XK_Thai_thanthakhat       : exit($0E4C);  { U+0E4C THAI CHARACTER THANTHAKHAT }
+    XK_Thai_nikhahit          : exit($0E4D);  { U+0E4D THAI CHARACTER NIKHAHIT }
+    XK_Thai_leksun            : exit($0E50);  { U+0E50 THAI DIGIT ZERO }
+    XK_Thai_leknung           : exit($0E51);  { U+0E51 THAI DIGIT ONE }
+    XK_Thai_leksong           : exit($0E52);  { U+0E52 THAI DIGIT TWO }
+    XK_Thai_leksam            : exit($0E53);  { U+0E53 THAI DIGIT THREE }
+    XK_Thai_leksi             : exit($0E54);  { U+0E54 THAI DIGIT FOUR }
+    XK_Thai_lekha             : exit($0E55);  { U+0E55 THAI DIGIT FIVE }
+    XK_Thai_lekhok            : exit($0E56);  { U+0E56 THAI DIGIT SIX }
+    XK_Thai_lekchet           : exit($0E57);  { U+0E57 THAI DIGIT SEVEN }
+    XK_Thai_lekpaet           : exit($0E58);  { U+0E58 THAI DIGIT EIGHT }
+    XK_Thai_lekkao            : exit($0E59);  { U+0E59 THAI DIGIT NINE }
+
+    { Korean }
+    XK_Korean_Won : exit($20A9);  {(U+20A9 WON SIGN)}
+
+    { Currency }
+    XK_EuroSign : exit($20ac);     { U+20AC EURO SIGN }
 
 
   end;
   end;
   X11ConvertKeySymToUnicode := -1;
   X11ConvertKeySymToUnicode := -1;
 end;
 end;
+

+ 11 - 1
packages/ptc/src/x11/x11windowdisplayd.inc

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the PTCPas framebuffer library
     This file is part of the PTCPas framebuffer library
-    Copyright (C) 2001-2013 Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2013, 2016 Nikolay Nikolov ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -44,6 +44,7 @@ type
     FCursorVisible: Boolean;
     FCursorVisible: Boolean;
     FGrabMouse: Boolean;
     FGrabMouse: Boolean;
     FMouseGrabbed: Boolean;
     FMouseGrabbed: Boolean;
+    FRelativeMouseMode: Boolean;
     FX11InvisibleCursor: TCursor; { Blank cursor }
     FX11InvisibleCursor: TCursor; { Blank cursor }
     FFullScreen: Boolean; { Keeps a snapshot of the PTC_X11_FULLSCREEN option
     FFullScreen: Boolean; { Keeps a snapshot of the PTC_X11_FULLSCREEN option
                              taken at the time 'open' was called }
                              taken at the time 'open' was called }
@@ -62,6 +63,13 @@ type
     FGLXFBConfig: TX11GLXFBConfig;
     FGLXFBConfig: TX11GLXFBConfig;
 {$ENDIF ENABLE_X11_EXTENSION_GLX}
 {$ENDIF ENABLE_X11_EXTENSION_GLX}
 
 
+{$IFDEF ENABLE_X11_EXTENSION_XINPUT2}
+    FXInput2Enabled: Boolean;
+    FXInput2MajorOpCode: cint;
+    FXInput2FirstEvent: cint;
+    FXInput2FirstError: cint;
+{$ENDIF ENABLE_X11_EXTENSION_XINPUT2}
+
     procedure EnterFullScreen;
     procedure EnterFullScreen;
     procedure LeaveFullScreen;
     procedure LeaveFullScreen;
     procedure internal_ShowCursor(AVisible: Boolean);
     procedure internal_ShowCursor(AVisible: Boolean);
@@ -99,6 +107,8 @@ type
     function IsOpen: Boolean; override;
     function IsOpen: Boolean; override;
     procedure SetCursor(AVisible: Boolean); override;
     procedure SetCursor(AVisible: Boolean); override;
     procedure SetMouseGrab(AGrabMouse: Boolean); override;
     procedure SetMouseGrab(AGrabMouse: Boolean); override;
+    function SetRelativeMouseMode(ARelativeMouseMode: Boolean): Boolean; override;
+    function MoveMouseTo(X, Y: Integer): Boolean; override;
 {$IFDEF ENABLE_X11_EXTENSION_GLX}
 {$IFDEF ENABLE_X11_EXTENSION_GLX}
     procedure OpenGL_SwapBuffers; override;
     procedure OpenGL_SwapBuffers; override;
     procedure OpenGL_SetSwapInterval(AInterval: Integer); override;
     procedure OpenGL_SetSwapInterval(AInterval: Integer); override;

+ 408 - 6
packages/ptc/src/x11/x11windowdisplayi.inc

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the PTCPas framebuffer library
     This file is part of the PTCPas framebuffer library
-    Copyright (C) 2001-2013 Nikolay Nikolov ([email protected])
+    Copyright (C) 2001-2013, 2016, 2017 Nikolay Nikolov ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
     Original C++ version by Christian Nentwich ([email protected])
 
 
     This library is free software; you can redistribute it and/or
     This library is free software; you can redistribute it and/or
@@ -31,6 +31,11 @@
 }
 }
 
 
 constructor TX11WindowDisplay.Create(ADisplay: PDisplay; AScreen: Integer; const AFlags: TX11Flags);
 constructor TX11WindowDisplay.Create(ADisplay: PDisplay; AScreen: Integer; const AFlags: TX11Flags);
+{$IFDEF ENABLE_X11_EXTENSION_XINPUT2}
+var
+  MajorVer, MinorVer: cint;
+  QueryVersionResult: TStatus;
+{$ENDIF ENABLE_X11_EXTENSION_XINPUT2}
 begin
 begin
   inherited;
   inherited;
   FFocus := True;
   FFocus := True;
@@ -38,6 +43,34 @@ begin
   FCursorVisible := True;
   FCursorVisible := True;
   FGrabMouse := False;
   FGrabMouse := False;
   FMouseGrabbed := False;
   FMouseGrabbed := False;
+{$IFDEF ENABLE_X11_EXTENSION_XINPUT2}
+  if PTC_X11_TRY_XINPUT2 in FFlags then
+  begin
+    LOG('Querying the XInput2 extension...');
+    if XQueryExtension(FDisplay, 'XInputExtension', @FXInput2MajorOpCode, @FXInput2FirstEvent, @FXInput2FirstError) then
+    begin
+      LOG('There is an XInput extension, now let''s query its version...');
+      MajorVer := 2;
+      MinorVer := 0;
+      LOG('We want version ' + IntToStr(MajorVer) + '.' + IntToStr(MinorVer));
+      QueryVersionResult := XIQueryVersion(FDisplay, @MajorVer, @MinorVer);
+      if QueryVersionResult = Success then
+      begin
+        LOG('XInput2 extension is available (version ' + IntToStr(MajorVer) + '.' + IntToStr(MinorVer) + ')');
+        FXInput2Enabled := True;
+      end
+      else
+      begin
+        LOG('The required XInput version is not available (version ' + IntToStr(MajorVer) + '.' + IntToStr(MinorVer) + ' only)');
+      end;
+    end
+    else
+    begin
+      LOG('XInput2 extension not available');
+      FXInput2Enabled := False;
+    end;
+  end;
+{$ENDIF ENABLE_X11_EXTENSION_XINPUT2}
 end;
 end;
 
 
 destructor TX11WindowDisplay.Destroy;
 destructor TX11WindowDisplay.Destroy;
@@ -46,6 +79,14 @@ begin
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
+{$warning remove, when fix added to xlib}
+function XGetIMValues(para1:PXIM; dotdotdot:array of const):Pchar;cdecl;external libX11;
+function XGetICValues(para1:PXIC; dotdotdot:array of const):Pchar;cdecl;external libX11;
+
+{function fpsetlocale(category: cint; locale: Pchar): PChar;cdecl;external 'c' name 'setlocale';
+const
+  LC_ALL = 6;}
+
 procedure TX11WindowDisplay.Open(ATitle: AnsiString; AWidth, AHeight: Integer; AFormat: IPTCFormat; const AOpenGLAttributes: IPTCOpenGLAttributes);
 procedure TX11WindowDisplay.Open(ATitle: AnsiString; AWidth, AHeight: Integer; AFormat: IPTCFormat; const AOpenGLAttributes: IPTCOpenGLAttributes);
 var
 var
   xgcv: TXGCValues;
   xgcv: TXGCValues;
@@ -62,6 +103,119 @@ var
   BlankCursorData: array [1..8] of Byte = (0, 0, 0, 0, 0, 0, 0, 0);
   BlankCursorData: array [1..8] of Byte = (0, 0, 0, 0, 0, 0, 0, 0);
   CreateWindow_Depth: cint;
   CreateWindow_Depth: cint;
   CreateWindow_Visual: PVisual;
   CreateWindow_Visual: PVisual;
+{$IFDEF ENABLE_X11_EXTENSION_XINPUT2}
+  XInput2EventMask: TXIEventMask;
+{$ENDIF ENABLE_X11_EXTENSION_XINPUT2}
+  selected_im_style: TXIMStyle = 0;
+  im_event_mask: clong = 0;
+
+  function IMStyleToStr(style: TXIMStyle): string;
+  begin
+    Result := '';
+    if (style and XIMPreeditArea) <> 0 then
+      Result := Result + ' XIMPreeditArea';
+    if (style and XIMPreeditCallbacks) <> 0 then
+      Result := Result + ' XIMPreeditCallbacks';
+    if (style and XIMPreeditPosition) <> 0 then
+      Result := Result + ' XIMPreeditPosition';
+    if (style and XIMPreeditNothing) <> 0 then
+      Result := Result + ' XIMPreeditNothing';
+    if (style and XIMPreeditNone) <> 0 then
+      Result := Result + ' XIMPreeditNone';
+    if (style and XIMStatusArea) <> 0 then
+      Result := Result + ' XIMStatusArea';
+    if (style and XIMStatusCallbacks) <> 0 then
+      Result := Result + ' XIMStatusCallbacks';
+    if (style and XIMStatusNothing) <> 0 then
+      Result := Result + ' XIMStatusNothing';
+    if (style and XIMStatusNone) <> 0 then
+      Result := Result + ' XIMStatusNone';
+    if Length(Result) > 0 then
+      Delete(Result, 1, 1);
+    Result := IntToStr(style) + ' (' + Result + ')';
+  end;
+
+  procedure TryCreateIM;
+  const
+    PreferredStyle = XIMPreeditNothing or XIMStatusNothing;
+{    PreferredStyle = XIMPreeditNone or XIMStatusNone;}
+  var
+    im_supported_styles: PXIMStyles;
+    locale_modifiers: PChar;
+    I: Integer;
+  begin
+{    LOG('setting locale');
+    if fpsetlocale(LC_ALL, '') = nil then
+      LOG('set locale failed');}
+
+    { Check if X11 supports the current locale }
+    LOG('checking X11 support for the current locale');
+    if XSupportsLocale = 0 then
+    begin
+      LOG('locale not supported');
+      exit;
+    end;
+    LOG('locale supported');
+
+    LOG('setting locale modifiers');
+    locale_modifiers := XSetLocaleModifiers('@im=none');
+    if locale_modifiers = nil then
+    begin
+      LOG('XSetLocaleModifiers failed');
+    end
+    else
+    begin
+      LOG('XSetLocaleModifiers success; returned', locale_modifiers);
+    end;
+
+    { Open IM }
+    LOG('opening input method');
+    FXIM := XOpenIM(FDisplay, nil, '', '');
+    LOG('input method (ptr)', HexStr(FXIM));
+
+    { Select IM input style }
+    if Assigned(FXIM) then
+    begin
+      LOG('querying the supported input styles');
+      XGetIMValues(FXIM, [XNQueryInputStyle, @im_supported_styles, nil]);
+
+      if Assigned(im_supported_styles) then
+      begin
+        LOG('number of styles', im_supported_styles^.count_styles);
+        for I := 0 to im_supported_styles^.count_styles - 1 do
+        begin
+          LOG('style', IMStyleToStr(im_supported_styles^.supported_styles[I]));
+          if (im_supported_styles^.supported_styles[I] and PreferredStyle) = PreferredStyle then
+            selected_im_style := im_supported_styles^.supported_styles[I];
+        end;
+        XFree(im_supported_styles);
+        LOG('selected style', IMStyleToStr(selected_im_style));
+      end;
+    end;
+  end;
+
+  procedure TryCreateIC;
+  begin
+    if Assigned(FXIM) and (selected_im_style <> 0) then
+    begin
+      LOG('creating input context');
+      FXIC := XCreateIC(FXIM, [XNInputStyle, selected_im_style,
+                               XNClientWindow, FWindow,
+                               XNFocusWindow, FWindow, nil]);
+      LOG('input context (ptr)', HexStr(FXIC));
+
+      if Assigned(FXIC) then
+      begin
+        LOG('setting input context focus');
+        XSetICFocus(FXIC);
+
+        LOG('getting the IM event mask');
+        XGetICValues(FXIC, [XNFilterEvents, @im_event_mask, nil]);
+        LOG('IM event mask', im_event_mask);
+      end;
+    end;
+  end;
+
 begin
 begin
   FHeight := AHeight;
   FHeight := AHeight;
   FWidth := AWidth;
   FWidth := AWidth;
@@ -82,6 +236,10 @@ begin
   BlackColor.green := 0;
   BlackColor.green := 0;
   BlackColor.blue := 0;
   BlackColor.blue := 0;
 
 
+  { Try to open an input method }
+  if PTC_X11_TRY_XIM in FFlags then
+    TryCreateIM;
+
   { Create the mode switcher object }
   { Create the mode switcher object }
   if (FModeSwitcher = Nil) and FFullScreen then
   if (FModeSwitcher = Nil) and FFullScreen then
     FModeSwitcher := CreateModeSwitcher;
     FModeSwitcher := CreateModeSwitcher;
@@ -205,13 +363,40 @@ begin
     if e._type = MapNotify then
     if e._type = MapNotify then
       Break;
       Break;
   until False;
   until False;
+
+  { Try to create an input context for the input method }
+  if PTC_X11_TRY_XIM in FFlags then
+    TryCreateIC;
+
   { Get keyboard input and sync }
   { Get keyboard input and sync }
   XSelectInput(FDisplay, FWindow, KeyPressMask or KeyReleaseMask or
   XSelectInput(FDisplay, FWindow, KeyPressMask or KeyReleaseMask or
                                   StructureNotifyMask or FocusChangeMask or
                                   StructureNotifyMask or FocusChangeMask or
                                   ButtonPressMask or ButtonReleaseMask or
                                   ButtonPressMask or ButtonReleaseMask or
-                                  PointerMotionMask or ExposureMask);
+                                  PointerMotionMask or ExposureMask or
+                                  EnterWindowMask or LeaveWindowMask or im_event_mask);
   XSync(FDisplay, False);
   XSync(FDisplay, False);
 
 
+{$IFDEF ENABLE_X11_EXTENSION_XINPUT2}
+  { enable XInput2 raw mouse input for the window as well }
+  if FXInput2Enabled then
+  begin
+    FillChar(XInput2EventMask, SizeOf(XInput2EventMask), 0);
+    XInput2EventMask.deviceid := XIAllMasterDevices;
+
+    XInput2EventMask.mask_len := XIMaskLen(XI_LASTEVENT);
+    XInput2EventMask.mask := AllocMem(XInput2EventMask.mask_len);
+    try
+      XISetMask(XInput2EventMask.mask, XI_RawMotion);
+      XISetMask(XInput2EventMask.mask, XI_RawButtonPress);
+      XISetMask(XInput2EventMask.mask, XI_RawButtonRelease);
+
+      XISelectEvents(FDisplay, RootWindow(FDisplay, FScreen){FWindow}, @XInput2EventMask, 1);
+    finally
+      FreeMem(XInput2EventMask.mask);
+    end;
+  end;
+{$ENDIF ENABLE_X11_EXTENSION_XINPUT2}
+
   if not (PTC_X11_USE_OPENGL in FFlags) then
   if not (PTC_X11_USE_OPENGL in FFlags) then
   begin
   begin
     { Create XImage using factory method }
     { Create XImage using factory method }
@@ -267,6 +452,20 @@ begin
   FreeAndNil(FGLXFBConfig);
   FreeAndNil(FGLXFBConfig);
 {$ENDIF ENABLE_X11_EXTENSION_GLX}
 {$ENDIF ENABLE_X11_EXTENSION_GLX}
 
 
+  if Assigned(FXIC) then
+  begin
+    LOG('destroying input context');
+    XDestroyIC(FXIC);
+    FXIC := nil;
+  end;
+
+  if Assigned(FXIM) then
+  begin
+    LOG('closing input method');
+    XCloseIM(FXIM);
+    FXIM := nil;
+  end;
+
   {pthreads?!}
   {pthreads?!}
   if FCMap <> 0 then
   if FCMap <> 0 then
   begin
   begin
@@ -392,6 +591,15 @@ begin
     internal_GrabMouse(FGrabMouse);
     internal_GrabMouse(FGrabMouse);
 end;
 end;
 
 
+function TX11WindowDisplay.SetRelativeMouseMode(ARelativeMouseMode: Boolean): Boolean;
+begin
+{$IFDEF ENABLE_X11_EXTENSION_XINPUT2}
+  if FXInput2Enabled then
+    FRelativeMouseMode := ARelativeMouseMode;
+{$ENDIF ENABLE_X11_EXTENSION_XINPUT2}
+  Result := ARelativeMouseMode = FRelativeMouseMode;
+end;
+
 procedure TX11WindowDisplay.EnterFullScreen;
 procedure TX11WindowDisplay.EnterFullScreen;
 begin
 begin
   { try to switch mode }
   { try to switch mode }
@@ -480,6 +688,22 @@ var
     before, after: Boolean;
     before, after: Boolean;
     cstate: TPTCMouseButtonState;
     cstate: TPTCMouseButtonState;
   begin
   begin
+{$IFDEF ENABLE_X11_EXTENSION_XINPUT2}
+    { if XInput2 is enabled, and we're in relative mouse mode, then don't handle
+    the regular mouse events -> use the XInput2 raw mouse events in this case }
+    if FXInput2Enabled and FRelativeMouseMode then
+      exit;
+{$ENDIF ENABLE_X11_EXTENSION_XINPUT2}
+    if not FPreviousMousePositionSaved then
+    begin
+      FPreviousMouseX := -1; { -1 indicates relative mouse mode }
+      FPreviousMouseY := -1; { -1 indicates relative mouse mode }
+      FPreviousMouseButtonState := [];
+      PTCMouseButtonState := [];
+    end
+    else
+      PTCMouseButtonState := FPreviousMouseButtonState
+        - [PTCMouseButton1, PTCMouseButton2, PTCMouseButton3, PTCMouseButton4, PTCMouseButton5];
     case e._type of
     case e._type of
       MotionNotify: begin
       MotionNotify: begin
         x := e.xmotion.x;
         x := e.xmotion.x;
@@ -498,6 +722,8 @@ var
             Button3: state := state or Button3Mask;
             Button3: state := state or Button3Mask;
             Button4: state := state or Button4Mask;
             Button4: state := state or Button4Mask;
             Button5: state := state or Button5Mask;
             Button5: state := state or Button5Mask;
+            6..Ord(High(TPTCMouseButton))+1:
+              Include(PTCMouseButtonState, TPTCMouseButton((Ord(PTCMouseButton6)-6)+e.xbutton.button));
           end;
           end;
         end
         end
         else
         else
@@ -508,6 +734,8 @@ var
             Button3: state := state and (not Button3Mask);
             Button3: state := state and (not Button3Mask);
             Button4: state := state and (not Button4Mask);
             Button4: state := state and (not Button4Mask);
             Button5: state := state and (not Button5Mask);
             Button5: state := state and (not Button5Mask);
+            6..Ord(High(TPTCMouseButton))+1:
+              Exclude(PTCMouseButtonState, TPTCMouseButton((Ord(PTCMouseButton6)-6)+e.xbutton.button));
           end;
           end;
         end;
         end;
       end;
       end;
@@ -515,10 +743,8 @@ var
         raise TPTCError.Create('Internal Error');
         raise TPTCError.Create('Internal Error');
     end;
     end;
 
 
-    if (state and Button1Mask) = 0 then
-      PTCMouseButtonState := []
-    else
-      PTCMouseButtonState := [PTCMouseButton1];
+    if (state and Button1Mask) <> 0 then
+      PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton1];
     if (state and Button2Mask) <> 0 then
     if (state and Button2Mask) <> 0 then
       PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton3];
       PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton3];
     if (state and Button3Mask) <> 0 then
     if (state and Button3Mask) <> 0 then
@@ -535,6 +761,12 @@ var
         FPreviousMouseX := x; { first DeltaX will be 0 }
         FPreviousMouseX := x; { first DeltaX will be 0 }
         FPreviousMouseY := y; { first DeltaY will be 0 }
         FPreviousMouseY := y; { first DeltaY will be 0 }
         FPreviousMouseButtonState := [];
         FPreviousMouseButtonState := [];
+      end
+      { there's a previous mouse state saved, but it was in relative mouse mode? }
+      else if (FPreviousMouseX = -1) or (FPreviousMouseY = -1) then
+      begin
+        FPreviousMouseX := x; { first DeltaX after relative mouse mode will be 0 }
+        FPreviousMouseY := y; { first DeltaY after relative mouse mode will be 0 }
       end;
       end;
 
 
       { movement? }
       { movement? }
@@ -581,11 +813,149 @@ var
     FPreviousHeight := e.xconfigure.height;
     FPreviousHeight := e.xconfigure.height;
   end;
   end;
 
 
+{$IFDEF ENABLE_X11_EXTENSION_XINPUT2}
+  procedure HandleXInput2RawEvent(const xi2e: TXIRawEvent);
+  var
+    I: Integer;
+    MovementXAccelerated: cdouble = 0;
+    MovementXRaw: cdouble = 0;
+    MovementXRawInt: Integer = 0;
+    MovementXAvailable: Boolean = False;
+    MovementYAccelerated: cdouble = 0;
+    MovementYRaw: cdouble = 0;
+    MovementYRawInt: Integer = 0;
+    MovementYAvailable: Boolean = False;
+    valptr, rawptr: Pcdouble;
+    PTCMouseButtonState: TPTCMouseButtonState;
+
+    button: TPTCMouseButton;
+    before, after: Boolean;
+    cstate: TPTCMouseButtonState;
+  begin
+{    Writeln(xi2e.evtype, ' ', xi2e.detail);
+    valptr := xi2e.valuators.values;
+    rawptr := xi2e.raw_values;
+    for I := 0 to xi2e.valuators.mask_len*8 - 1 do
+      if XIMaskIsSet(xi2e.valuators.mask, I) then
+      begin
+        Writeln('Valuator ', I, ' value=', valptr^:0:50, ' raw=', rawptr^:0:50);
+        Inc(valptr);
+        Inc(rawptr);
+      end;}
+
+    { when not in relative mouse mode, we use the regular X11 mouse events }
+    if not FRelativeMouseMode then
+      exit;
+
+    if not FPreviousMousePositionSaved then
+    begin
+      FPreviousMouseX := -1; { -1 indicates relative mouse mode }
+      FPreviousMouseY := -1; { -1 indicates relative mouse mode }
+      FPreviousMouseButtonState := [];
+    end;
+
+    if (xi2e.evtype = XI_RawButtonPress) or (xi2e.evtype = XI_RawButtonRelease) then
+    begin
+      PTCMouseButtonState := FPreviousMouseButtonState;
+      if xi2e.evtype = XI_RawButtonPress then
+        case xi2e.detail of
+          Button1: PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton1];
+          Button2: PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton3];
+          Button3: PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton2];
+          Button4: PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton4];
+          Button5: PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton5];
+          6..Ord(High(TPTCMouseButton))+1:
+            Include(PTCMouseButtonState, TPTCMouseButton((Ord(PTCMouseButton6)-6)+xi2e.detail));
+        end
+      else
+        case xi2e.detail of
+          Button1: PTCMouseButtonState := PTCMouseButtonState - [PTCMouseButton1];
+          Button2: PTCMouseButtonState := PTCMouseButtonState - [PTCMouseButton3];
+          Button3: PTCMouseButtonState := PTCMouseButtonState - [PTCMouseButton2];
+          Button4: PTCMouseButtonState := PTCMouseButtonState - [PTCMouseButton4];
+          Button5: PTCMouseButtonState := PTCMouseButtonState - [PTCMouseButton5];
+          6..Ord(High(TPTCMouseButton))+1:
+            Exclude(PTCMouseButtonState, TPTCMouseButton((Ord(PTCMouseButton6)-6)+xi2e.detail));
+        end;
+    end
+    else
+      PTCMouseButtonState := FPreviousMouseButtonState;
+
+    if xi2e.valuators.mask_len > 0 then
+    begin
+      valptr := xi2e.valuators.values;
+      rawptr := xi2e.raw_values;
+      if XIMaskIsSet(xi2e.valuators.mask, 0) then
+      begin
+        MovementXAccelerated := valptr^;
+        MovementXRaw := rawptr^;
+        MovementXRawInt := Round(MovementXRaw);
+        MovementXAvailable := True;
+        Inc(valptr);
+        Inc(rawptr);
+      end;
+      if XIMaskIsSet(xi2e.valuators.mask, 1) then
+      begin
+        MovementYAccelerated := valptr^;
+        MovementYRaw := rawptr^;
+        MovementYRawInt := Round(MovementYRaw);
+        MovementYAvailable := True;
+        Inc(valptr);
+        Inc(rawptr);
+      end;
+    end;
+
+    { movement? }
+    if (MovementXRawInt <> 0) or (MovementYRawInt <> 0) then
+      FEventQueue.AddEvent(TPTCMouseEvent.Create(-1, -1, MovementXRawInt, MovementYRawInt, FPreviousMouseButtonState));
+
+    { button presses/releases? }
+    cstate := FPreviousMouseButtonState;
+    for button := Low(button) to High(button) do
+    begin
+      before := button In FPreviousMouseButtonState;
+      after := button In PTCMouseButtonState;
+      if after and (not before) then
+      begin
+        { button was pressed }
+        cstate := cstate + [button];
+        FEventQueue.AddEvent(TPTCMouseButtonEvent.Create(-1, -1, 0, 0, cstate, True, button));
+      end
+      else
+        if before and (not after) then
+        begin
+          { button was released }
+          cstate := cstate - [button];
+          FEventQueue.AddEvent(TPTCMouseButtonEvent.Create(-1, -1, 0, 0, cstate, False, button));
+        end;
+    end;
+
+    FPreviousMouseX := -1;
+    FPreviousMouseY := -1;
+    FPreviousMouseButtonState := PTCMouseButtonState;
+    FPreviousMousePositionSaved := True;
+  end;
+{$ENDIF ENABLE_X11_EXTENSION_XINPUT2}
+
+var
+{$IFDEF ENABLE_X11_EXTENSION_XINPUT2}
+  XInput2Event: PXIDeviceEvent;
+{$ENDIF ENABLE_X11_EXTENSION_XINPUT2}
+  eaten_by_im: Boolean = False;
 begin
 begin
   NewFocusSpecified := False;
   NewFocusSpecified := False;
   while UsefulEventsPending do
   while UsefulEventsPending do
   begin
   begin
     XNextEvent(FDisplay, @e);
     XNextEvent(FDisplay, @e);
+    { maybe send the event to the Input Method for processing. Only non-key
+      events are sent here (key events are sent in HandleKeyEvent instead) }
+    if Assigned(FXIM) and Assigned(FXIC) and
+      (e._type <> KeyPress) and (e._type <> KeyRelease) then
+    begin
+      eaten_by_im := XFilterEvent(@e, FWindow);
+      if eaten_by_im then
+        exit;
+    end;
     case e._type of
     case e._type of
       FocusIn: begin
       FocusIn: begin
         NewFocus := True;
         NewFocus := True;
@@ -609,6 +979,30 @@ begin
       ConfigureNotify: HandleConfigureNotifyEvent;
       ConfigureNotify: HandleConfigureNotifyEvent;
       KeyPress, KeyRelease: HandleKeyEvent(e.xkey);
       KeyPress, KeyRelease: HandleKeyEvent(e.xkey);
       ButtonPress, ButtonRelease, MotionNotify: HandleMouseEvent;
       ButtonPress, ButtonRelease, MotionNotify: HandleMouseEvent;
+      EnterNotify: begin
+        { clear the high (>=6) numbered mouse buttons, because the mouse events contain no state information for them }
+        FPreviousMouseButtonState := FPreviousMouseButtonState
+          * [PTCMouseButton1, PTCMouseButton2, PTCMouseButton3, PTCMouseButton4, PTCMouseButton5];
+      end;
+{$IFDEF ENABLE_X11_EXTENSION_XINPUT2}
+      GenericEvent: begin
+        if e.xcookie.extension = FXInput2MajorOpCode then
+        begin
+          if XGetEventData(FDisplay, @e.xcookie) then
+            try
+              XInput2Event := e.xcookie.data;
+              case XInput2Event^.evtype of
+                XI_RawButtonPress,
+                XI_RawButtonRelease,
+                XI_RawMotion:
+                  HandleXInput2RawEvent(PXIRawEvent(XInput2Event)^);
+              end;
+            finally
+              XFreeEventData(FDisplay, @e.xcookie);
+            end;
+        end;
+      end;
+{$ENDIF ENABLE_X11_EXTENSION_XINPUT2}
     end;
     end;
   end;
   end;
   if NewFocusSpecified then
   if NewFocusSpecified then
@@ -618,6 +1012,14 @@ begin
     internal_GrabMouse(FGrabMouse);
     internal_GrabMouse(FGrabMouse);
 end;
 end;
 
 
+function TX11WindowDisplay.MoveMouseTo(X, Y: Integer): Boolean;
+begin
+  if not FOpen or (X < 0) or (Y < 0) or (X >= FWidth) or (Y >= FHeight) then
+    exit(False);
+  XWarpPointer(FDisplay, None, FWindow, 0, 0, 0, 0, X, Y);
+  Result := True;
+end;
+
 procedure TX11WindowDisplay.Draw;
 procedure TX11WindowDisplay.Draw;
 begin
 begin
   if not (PTC_X11_USE_OPENGL in FFlags) then
   if not (PTC_X11_USE_OPENGL in FFlags) then

+ 122 - 0
packages/ptc/tests/event.pp

@@ -0,0 +1,122 @@
+program event;
+
+{$MODE objfpc}{$H+}
+
+uses
+  SysUtils, ptc;
+
+function ButtonState2Str(const bs: TPTCMouseButtonState): string;
+var
+  I: TPTCMouseButton;
+begin
+  Result := '';
+  for I in TPTCMouseButton do
+    if I in bs then
+      WriteStr(Result, Result, ',', I);
+  if Result = '' then
+    Result := '[]'
+  else
+  begin
+    Result[1] := '[';
+    Result := Result + ']';
+  end;
+end;
+
+function ModifierKeys2Str(const mk: TPTCModifierKeys): string;
+var
+  I: TPTCModifierKey;
+begin
+  Result := '';
+  for I in TPTCModifierKey do
+    if I in mk then
+      WriteStr(Result, Result, ',', I);
+  if Result = '' then
+    Result := '[]'
+  else
+  begin
+    Result[1] := '[';
+    Result := Result + ']';
+  end;
+end;
+
+var
+  console: IPTCConsole;
+  ev: IPTCEvent;
+  Done: Boolean = False;
+  RX, RY: Integer;
+begin
+  try
+    try
+      console := TPTCConsoleFactory.CreateNew;
+
+      console.Option('intercept window close');
+  //    console.Option('resizable window');
+
+      console.Open('event test');
+
+      repeat
+        console.NextEvent(ev, True, PTCAnyEvent);
+        if Supports(ev, IPTCMouseButtonEvent) then
+          with ev as IPTCMouseButtonEvent do
+            Writeln('IPTCMouseButtonEvent(X=', X, '; Y=', Y, '; DeltaX=', DeltaX,
+            '; DeltaY=', DeltaY, '; ButtonState=', ButtonState2Str(ButtonState),
+            '; Press=', Press, '; Release=', Release, '; Button=', Button, ')')
+        else if Supports(ev, IPTCMouseEvent) then
+          with ev as IPTCMouseEvent do
+            Writeln('IPTCMouseEvent(X=', X, '; Y=', Y, '; DeltaX=', DeltaX,
+            '; DeltaY=', DeltaY, '; ButtonState=', ButtonState2Str(ButtonState),
+            ')')
+        else if Supports(ev, IPTCKeyEvent) then
+          with ev as IPTCKeyEvent do
+            Writeln('IPTCKeyEvent(Code=', Code, '; Unicode=', Unicode, '; Press=',
+              Press, '; Release=', Release, '; Alt=', Alt, '; Shift=', Shift,
+              '; Control=', Control, '; ModifierKeys=',
+              ModifierKeys2Str(ModifierKeys), ')')
+        else if Supports(ev, IPTCResizeEvent) then
+          with ev as IPTCResizeEvent do
+            Writeln('IPTCResizeEvent(Width=', Width, '; Height=', Height, ')')
+        else if Supports(ev, IPTCCloseEvent) then
+          with ev as IPTCCloseEvent do
+            Writeln('IPTCCloseEvent()')
+        else
+          Writeln('UNKNOWN EVENT TYPE');
+
+        if Supports(ev, IPTCKeyEvent) then
+          with ev as IPTCKeyEvent do
+            if Press then
+            begin
+              case Code of
+                PTCKEY_G:
+                  console.Option('grab mouse');
+                PTCKEY_U:
+                  console.Option('ungrab mouse');
+                PTCKEY_S:
+                  console.Option('show cursor');
+                PTCKEY_H:
+                  console.Option('hide cursor');
+                PTCKEY_R:
+                  console.Option('relative mouse on');
+                PTCKEY_A:
+                  console.Option('relative mouse off');
+                PTCKEY_M:
+                  begin
+                    RX := Random(console.Width);
+                    RY := Random(console.Height);
+                    Writeln('MoveMouseTo(', RX, ', ', RY, ')');
+                    if not console.MoveMouseTo(RX, RY) then
+                      writeln('MoveMouseTo FAILED (or is not supported by the console)');
+                  end;
+                PTCKEY_Q:
+                  Done := True;
+              end;
+            end;
+      until Done;
+    finally
+      if Assigned(console) then
+        console.Close;
+    end;
+  except
+    on error: TPTCError do
+      error.Report;
+  end;
+end.