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

git-svn-id: trunk@36507 -
This commit is contained in:
nickysn 2017-06-18 00:16:03 +00:00
parent 8b6563bef2
commit f2587b6061
49 changed files with 7425 additions and 1700 deletions

5
.gitattributes vendored
View File

@ -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/timerd.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/kbdd.inc 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/vgaconsolei.inc 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/ptcwrapper/ptceventqueue.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/windows.ico -text
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/win32directxconsoled.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/tests/convtest.pp 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/pthreads/Makefile svneol=native#text/plain
packages/pthreads/Makefile.fpc svneol=native#text/plain

View File

@ -120,6 +120,7 @@ const
FullscreenGraph: Boolean = False;
var
WindowTitle: AnsiString;
PTCWrapperObject: TPTCWrapperThread;
{******************************************************************************}
@ -128,6 +129,8 @@ var
const
InternalDriverName = 'PTCPas';
FirstNonStandardModeNumber = $200;
NonStandardModeNumberMaxLimit = $7FFF;
var
Has320x200: Boolean;
@ -617,7 +620,7 @@ begin
LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 16 colours');
{$ENDIF logging}
{ open the console }
ptc_InternalOpen(ParamStr(0), XResolution, YResolution, PTCFormat8, Pages);
ptc_InternalOpen(WindowTitle, XResolution, YResolution, PTCFormat8, Pages);
PTCWidth := XResolution;
PTCHeight := YResolution;
CurrentActivePage := 0;
@ -642,7 +645,7 @@ begin
LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 256 colours');
{$ENDIF logging}
{ open the console }
ptc_InternalOpen(ParamStr(0), XResolution, YResolution, PTCFormat8, Pages);
ptc_InternalOpen(WindowTitle, XResolution, YResolution, PTCFormat8, Pages);
PTCWidth := XResolution;
PTCHeight := YResolution;
CurrentActivePage := 0;
@ -657,7 +660,7 @@ begin
LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 4 colours, palette ' + strf(CGAPalette));
{$ENDIF logging}
{ open the console }
ptc_InternalOpen(ParamStr(0), XResolution, YResolution, PTCFormat8, 1);
ptc_InternalOpen(WindowTitle, XResolution, YResolution, PTCFormat8, 1);
PTCWidth := XResolution;
PTCHeight := YResolution;
CurrentActivePage := 0;
@ -672,7 +675,7 @@ begin
LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 2 colours');
{$ENDIF logging}
{ open the console }
ptc_InternalOpen(ParamStr(0), XResolution, YResolution, PTCFormat8, Pages);
ptc_InternalOpen(WindowTitle, XResolution, YResolution, PTCFormat8, Pages);
PTCWidth := XResolution;
PTCHeight := YResolution;
CurrentActivePage := 0;
@ -687,7 +690,7 @@ begin
LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 2 colours');
{$ENDIF logging}
{ open the console }
ptc_InternalOpen(ParamStr(0), XResolution, YResolution, PTCFormat8, Pages);
ptc_InternalOpen(WindowTitle, XResolution, YResolution, PTCFormat8, Pages);
PTCWidth := XResolution;
PTCHeight := YResolution;
CurrentActivePage := 0;
@ -702,7 +705,7 @@ begin
LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 32768 colours');
{$ENDIF logging}
{ open the console }
ptc_InternalOpen(ParamStr(0), XResolution, YResolution, PTCFormat15, Pages);
ptc_InternalOpen(WindowTitle, XResolution, YResolution, PTCFormat15, Pages);
PTCWidth := XResolution;
PTCHeight := YResolution;
CurrentActivePage := 0;
@ -715,7 +718,7 @@ begin
LogLn('Initializing mode ' + strf(XResolution) + ', ' + strf(YResolution) + ' 65536 colours');
{$ENDIF logging}
{ open the console }
ptc_InternalOpen(ParamStr(0), XResolution, YResolution, PTCFormat16, Pages);
ptc_InternalOpen(WindowTitle, XResolution, YResolution, PTCFormat16, Pages);
PTCWidth := XResolution;
PTCHeight := YResolution;
CurrentActivePage := 0;
@ -869,6 +872,26 @@ begin
ptc_InitMode64k(1280, 1024, 2);
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);
begin
if page > HardwarePages then
@ -1409,8 +1432,64 @@ end;
ContainsAtLeast := False;
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
graphmode:Tmodeinfo;
I: Integer;
NextNonStandardModeNumber: SmallInt;
begin
QueryAdapterInfo := ModeList;
{ If the mode listing already exists... }
@ -1419,7 +1498,8 @@ end;
if assigned(ModeList) then
exit;
PTCModeList := PTCWrapperObject.Modes;
PTCModeList := Copy(PTCWrapperObject.Modes);
SortModes(Low(PTCModeList), High(PTCModeList));
Has320x200 := ContainsExactResolution(320, 200);
Has320x240 := ContainsExactResolution(320, 240);
@ -2567,9 +2647,147 @@ end;
end;
AddMode(graphmode);
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;
initialization
WindowTitle := ParamStr(0);
PTCFormat8 := TPTCFormatFactory.CreateNew(8);
PTCFormat15 := TPTCFormatFactory.CreateNew(16, $7C00, $03E0, $001F);
PTCFormat16 := TPTCFormatFactory.CreateNew(16, $F800, $07E0, $001F);

View File

@ -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
- 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

View File

@ -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
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:
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:

View File

@ -1,4 +1,4 @@
PTCPas 0.99.14.1
PTCPas 0.99.15
Nikolay Nikolov (nickysn@users.sourceforge.net)
PTCPas is a free, portable framebuffer library, written in Free Pascal. It is

View File

@ -10,11 +10,143 @@ program KeyboardExample3;
uses
ptc;
procedure DumpKey(AKey: IPTCKeyEvent);
function KeyCode2String(ACode: Integer): string;
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);
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);
var
mk: TPTCModifierKey;
first: Boolean;
begin
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;
var

View File

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

View File

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

View File

@ -1,6 +1,6 @@
{
Free Pascal port of the OpenPTC C++ library.
Copyright (C) 2001-2003, 2006, 2007, 2009-2013 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2001-2003, 2006, 2007, 2009-2013, 2016, 2017 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C++ version by Glenn Fiedler (ptc@gaffer.org)
This library is free software; you can redistribute it and/or
@ -117,6 +117,9 @@ type
procedure ReadKey;
property KeyReleaseEnabled: Boolean read GetKeyReleaseEnabled write SetKeyReleaseEnabled;
{ mouse handling }
function MoveMouseTo(X, Y: Integer): Boolean; virtual;
property Pages: Integer read GetPages;
property Name: string read GetName;
property Title: string read GetTitle;
@ -212,6 +215,12 @@ begin
Result := FReleaseEnabled;
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;
begin
Result := False;

View File

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

View File

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

View File

@ -1,6 +1,6 @@
{
Free Pascal port of the OpenPTC C++ library.
Copyright (C) 2001-2003, 2006, 2007, 2009-2011, 2015 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2001-2003, 2006, 2007, 2009-2011, 2015, 2017 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C++ version by Glenn Fiedler (ptc@gaffer.org)
This library is free software; you can redistribute it and/or
@ -31,7 +31,12 @@
}
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;
IPTCKeyEvent = interface(IPTCEvent)
['{9BD1CD41-1DF6-4392-99DC-885EADB6D85A}']

View File

@ -1,6 +1,6 @@
{
Free Pascal port of the OpenPTC C++ library.
Copyright (C) 2001-2007, 2009-2011 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2001-2007, 2009-2011, 2016 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C++ version by Glenn Fiedler (ptc@gaffer.org)
This library is free software; you can redistribute it and/or
@ -34,11 +34,37 @@ type
{todo TPTCMouseCursor = (PTCMouseCursorDefault,
PTCMouseCursorAlwaysVisible,
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;
IPTCMouseEvent = interface(IPTCEvent)
['{4D093608-6F27-4578-B41E-3492A4C7FEED}']

File diff suppressed because it is too large Load Diff

View File

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

View File

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

240
packages/ptc/src/ptclaz.lpi Normal file
View File

@ -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>

View File

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

View File

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

View File

@ -1,6 +1,6 @@
{
Free Pascal port of the OpenPTC C++ library.
Copyright (C) 2001-2003, 2006, 2007, 2009, 2010, 2012 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2001-2003, 2006, 2007, 2009, 2010, 2012, 2017 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C++ version by Glenn Fiedler (ptc@gaffer.org)
This library is free software; you can redistribute it and/or
@ -104,7 +104,10 @@ begin
if result = 0 then
begin
{ 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;
{ leave monitor }
@ -189,7 +192,10 @@ begin
{$ENDIF}
{ 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;
{ leave monitor }
@ -236,7 +242,10 @@ begin
if TWin32Hook_m_registry[index].count = 0 then
begin
{ 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...) }
for i := index to TWin32Hook_Count - 2 do

View File

@ -1,6 +1,6 @@
{
Free Pascal port of the OpenPTC C++ library.
Copyright (C) 2001-2003, 2006, 2007, 2009-2012 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2001-2003, 2006, 2007, 2009-2012, 2017 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C++ version by Glenn Fiedler (ptc@gaffer.org)
This library is free software; you can redistribute it and/or
@ -38,11 +38,6 @@ begin
FMonitor := TWin32Monitor.Create;
FEvent := TWin32Event.Create;
{ setup defaults }
FAlt := False;
FShift := False;
FControl := False;
{ setup data }
FEventQueue := AEventQueue;
FMultithreaded := AMultithreaded;
@ -71,9 +66,15 @@ begin
end;
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
i: Integer;
scancode: Integer;
scancode: UINT;
KeyStateArray: array [0..255] of Byte;
AsciiBuf: Word;
press: Boolean;
@ -81,6 +82,8 @@ var
TranslatedCharacters, TranslatedWideCharacters: Integer;
WideStr: WideString;
KeyCode: Integer;
ExtendedKey, DeadKey: Boolean;
ModifierKeys: TPTCModifierKeys;
begin
Result := 0;
{ 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
begin
press := (message = WM_KEYDOWN) or (message = WM_SYSKEYDOWN);
ExtendedKey := (lParam and (1 shl 24)) <> 0;
ModifierKeys := [];
{ 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 }
if FMultithreaded then
@ -114,25 +152,48 @@ begin
if GetKeyboardState(@KeyStateArray) then
begin
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
TranslatedWideCharacters := MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, @AsciiBuf, TranslatedCharacters, nil, 0);
if TranslatedWideCharacters <> 0 then
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
TranslatedCharacters := ToAscii(wParam, scancode, @KeyStateArray, @AsciiBuf, 0);
if TranslatedCharacters > 0 then
begin
TranslatedWideCharacters := MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, @AsciiBuf, TranslatedCharacters, nil, 0);
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;
if Length(WideStr) = 1 then
uni := Ord(WideStr[1]);
end;
KeyCode := wParam;
if wParam = VK_RETURN then
begin
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
KeyCode := PTCKEY_INSERT;
if wParam = VK_DELETE then
@ -145,7 +206,7 @@ begin
{ handle key repeat count }
for i := 1 to lParam and $FFFF do
{ 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 }
if FMultithreaded then
@ -157,18 +218,4 @@ begin
FMonitor.Leave;
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;

View File

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

View File

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

View File

@ -1,6 +1,6 @@
{
Free Pascal port of the OpenPTC C++ library.
Copyright (C) 2001-2007, 2009, 2010, 2013 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2001-2007, 2009, 2010, 2013, 2016 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C++ version by Glenn Fiedler (ptc@gaffer.org)
This library is free software; you can redistribute it and/or
@ -73,18 +73,48 @@ begin
FEnabled := False;
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;
var
fwKeys: Integer;
xPos, yPos: Integer;
LButton, MButton, RButton: Boolean;
CurPos: POINT;
LButton, MButton, RButton, XButton1, XButton2: Boolean;
TranslatedXPos, TranslatedYPos: Integer;
PTCMouseButtonState: TPTCMouseButtonState;
WindowRect: RECT;
ScrollAmount: Integer;
button: TPTCMouseButton;
before, after: Boolean;
cstate: TPTCMouseButtonState;
I: Integer;
begin
Result := 0;
{ check enabled flag }
@ -94,15 +124,27 @@ begin
if (message = WM_MOUSEMOVE) 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_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
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;
MButton := (fwKeys and MK_MBUTTON) <> 0;
RButton := (fwKeys and MK_RBUTTON) <> 0;
XButton1 := (fwKeys and MK_XBUTTON1) <> 0;
XButton2 := (fwKeys and MK_XBUTTON2) <> 0;
if not FFullScreen then
begin
@ -114,16 +156,16 @@ begin
FWindowY2 := WindowRect.bottom - 1;
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
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 }
TranslatedXPos := 0;
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 }
TranslatedYPos := 0;
@ -141,12 +183,14 @@ begin
PTCMouseButtonState := []
else
PTCMouseButtonState := [PTCMouseButton1];
if RButton then
PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton2];
if MButton then
PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton3];
if XButton1 then
PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton8];
if XButton2 then
PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton9];
if not FPreviousMousePositionSaved then
begin
@ -180,6 +224,34 @@ begin
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;
FPreviousMouseY := TranslatedYPos;
FPreviousMouseButtonState := PTCMouseButtonState;

View File

@ -1,6 +1,6 @@
{
Free Pascal port of the OpenPTC C++ library.
Copyright (C) 2001-2003, 2006, 2007, 2009-2012 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2001-2003, 2006, 2007, 2009-2012, 2016, 2017 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C++ version by Glenn Fiedler (ptc@gaffer.org)
This library is free software; you can redistribute it and/or
@ -46,6 +46,8 @@ begin
defaults;
FWindow := window;
FManaged := False;
FIsUnicode := IsWindowUnicode(window);
LOG('IsUnicode', IsUnicode);
end;
function WndProcSingleThreaded(hWnd: HWND; message: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; forward;
@ -59,33 +61,73 @@ var
rectangle: RECT;
display_width, display_height: Integer;
wc: WNDCLASSEXA;
wcw: WNDCLASSEXW;
WinVer: OSVERSIONINFO;
AWndClassW, ATitleW: WideString;
begin
LOG('creating managed window');
Defaults;
FMultithreaded := AMultithreaded;
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;
program_instance := GetModuleHandle(nil);
{ 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
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
wc.lpfnWndProc := @WndProcSingleThreaded;
if ACursor then
wc.hCursor := LoadCursor(0, IDC_ARROW)
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
begin
left := 0;
@ -117,7 +159,10 @@ begin
end
else
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
raise TPTCError.Create('could not create window');
ShowWindow(FWindow, FShow);
@ -140,16 +185,20 @@ end;
procedure TWin32Window.Cursor(AFlag: Boolean);
begin
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
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;
procedure TWin32Window.ConfineCursor(AFlag: Boolean);
@ -216,18 +265,43 @@ begin
{ updated to pump all window messages, and not just for our FWindow;
this fixes keyboard layout switching and maybe other bugs and side effects...
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
begin
GetMessage(message, {FWindow}0, 0, 0);
TranslateMessage(message);
DispatchMessage(message);
if IsUnicode then
begin
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
else
while PeekMessage(message, {FWindow}0, 0, 0, PM_REMOVE) do
begin
TranslateMessage(message);
DispatchMessage(message);
end;
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
else
Sleep(0);
@ -251,7 +325,10 @@ begin
begin
pCreate := PCREATESTRUCT(lParam);
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);
end;
WM_DESTROY:
@ -259,22 +336,35 @@ begin
WindowObject := TWin32Window(GetWindowLongPtr(hWnd, GWLP_USERDATA));
Result := WindowObject.WMDestroy(hWnd, message, wParam, lParam);
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:
begin
{ this fixes the pausing of the application when the Alt or F10 key is pressed }
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;
WM_SETCURSOR: begin
if (LOWORD(lParam) = HTCLIENT) and (GetClassLongPtr(hWnd, GCLP_HCURSOR) = 0) then
begin
SetCursor(0);
Result := 1;
Result := 1;
end
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;
WM_CLOSE: begin
LOG('TWin32Window WM_CLOSE');
@ -285,7 +375,10 @@ begin
Halt(0);
end;
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;
@ -297,18 +390,24 @@ begin
begin
{ this fixes the pausing of the application when the Alt or F10 key is pressed }
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;
WM_SETCURSOR: begin
if (LOWORD(lParam) = HTCLIENT) and (GetClassLongPtr(hWnd, GCLP_HCURSOR) = 0) then
begin
SetCursor(0);
Result := 1;
Result := 1;
end
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;
WM_DESTROY: begin
LOG('TWin32Window WM_DESTROY');
@ -319,7 +418,10 @@ begin
Halt(0);
end;
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;
@ -406,10 +508,16 @@ end;
function TWin32Window.WMCreate(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
Result := DefWindowProcA(hWnd, uMsg, wParam, lParam);
if IsUnicode then
Result := DefWindowProcW(hWnd, uMsg, wParam, lParam)
else
Result := DefWindowProcA(hWnd, uMsg, wParam, lParam);
end;
function TWin32Window.WMDestroy(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
Result := DefWindowProcA(hWnd, uMsg, wParam, lParam);
if IsUnicode then
Result := DefWindowProcW(hWnd, uMsg, wParam, lParam)
else
Result := DefWindowProcA(hWnd, uMsg, wParam, lParam);
end;

View File

@ -1,6 +1,6 @@
{
Free Pascal port of the OpenPTC C++ library.
Copyright (C) 2001-2003, 2006, 2007, 2009, 2010, 2012 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2001-2003, 2006, 2007, 2009, 2010, 2012, 2017 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C++ version by Glenn Fiedler (ptc@gaffer.org)
This library is free software; you can redistribute it and/or
@ -48,6 +48,7 @@ type
FMultithreaded: Boolean;
FCursorConfineInEffect: Boolean;
FInterceptClose: Boolean;
FIsUnicode: Boolean;
{ 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;}
@ -73,4 +74,5 @@ type
property Managed: Boolean read FManaged;
property Multithreaded: Boolean read FMultithreaded;
property InterceptClose: Boolean read FInterceptClose write FInterceptClose;
property IsUnicode: Boolean read FIsUnicode;
end;

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,6 +1,6 @@
{
Free Pascal port of the OpenPTC C++ library.
Copyright (C) 2001-2003, 2006, 2007, 2009-2013 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2001-2003, 2006, 2007, 2009-2013, 2016 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C++ version by Glenn Fiedler (ptc@gaffer.org)
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);
FMouse := TWin32Mouse.Create(FWindow.handle, FWindow.thread, False, FEventQueue, FPrimary.Fullscreen, FPrimary.width, FPrimary.height);
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
FResize := TWin32Resize.Create(FWindow.handle, FWindow.thread, FEventQueue);
FWindow.update;
@ -1243,6 +1243,12 @@ begin
FWindow.InterceptClose := AInterceptClose;
end;
function TDirectXConsole.MoveMouseTo(X, Y: Integer): Boolean;
begin
CHECK_OPEN('TDirectXConsole.MoveMouseTo');
Result := FMouse.MoveMouseTo(X, Y);
end;
{$IFDEF DEBUG}
procedure TDirectXConsole.CHECK_OPEN(AMsg: String);
begin

View File

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

View File

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

View File

@ -1,6 +1,6 @@
{
This file is part of the PTCPas framebuffer library
Copyright (C) 2007, 2009-2013 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2007, 2009-2013, 2016 Nikolay Nikolov (nickysn@users.sourceforge.net)
This library is free software; you can redistribute it and/or
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 PeekEvent(AWait: Boolean; const AEventMask: TPTCEventMask): IPTCEvent; override;
function MoveMouseTo(X, Y: Integer): Boolean; 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;

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
{
This file is part of the PTCPas framebuffer library
Copyright (C) 2001-2013 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2001-2013, 2016, 2017 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C++ version by Christian Nentwich (c.nentwich@cs.ucl.ac.uk)
This library is free software; you can redistribute it and/or
@ -37,7 +37,8 @@ begin
inherited Create;
{ 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 := '';
@ -170,6 +171,26 @@ begin
FFlags := FFlags - [PTC_X11_TRY_XSHM];
exit;
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
begin
FFlags := FFlags - [PTC_X11_FULLSCREEN_CURSOR_VISIBLE, PTC_X11_WINDOWED_CURSOR_INVISIBLE];
@ -200,6 +221,18 @@ begin
UpdateMouseGrab;
exit;
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
begin
FFlags := FFlags + [PTC_X11_INTERCEPT_WINDOW_CLOSE];
@ -575,6 +608,22 @@ begin
FX11Display.SetMouseGrab(PTC_X11_GRAB_MOUSE in FFlags);
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;
begin
FX11Display.OpenGL_SwapBuffers;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
{
This file is part of the PTCPas framebuffer library
Copyright (C) 2001-2013 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2001-2013, 2015-2017 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C++ version by Christian Nentwich (c.nentwich@cs.ucl.ac.uk)
This library is free software; you can redistribute it and/or
@ -452,11 +452,23 @@ var
uni: Integer;
key: TPTCKeyEvent;
buf: array [1..16] of Char;
lslen: cint;
status: TStatus;
eaten_by_im: Boolean = False;
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);
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);
uni := X11ConvertKeySymToUnicode(sym_modded);
// Writeln(HexStr(e.state, 8));
modkeys := [];
if (e.state and Mod1Mask) <> 0 then
Include(modkeys, pmkAlt);
@ -464,10 +476,42 @@ begin
Include(modkeys, pmkShift);
if (e.state and ControlMask) <> 0 then
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
press := True
begin
press := True;
uni := X11ConvertKeySymToUnicode(sym_modded);
end
else
begin
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
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);
$FF: key := TPTCKeyEvent.Create(FFunctionKeys[sym_modded and $FF], uni, modkeys, press);
else
key := TPTCKeyEvent.Create;
key := TPTCKeyEvent.Create(PTCKEY_UNDEFINED, uni, modkeys, press);
end;
FEventQueue.AddEvent(key);
if (not eaten_by_im) or (pmkDeadKey in modkeys) then
FEventQueue.AddEvent(key);
end;
function TX11Display.GetInterceptClose: Boolean;
@ -519,6 +564,11 @@ begin
raise TPTCError.Create('Console not in windowed mode');
end;
function TX11Display.MoveMouseTo(X, Y: Integer): Boolean;
begin
Result := False;
end;
procedure TX11Display.OpenGL_SwapBuffers;
begin
raise TPTCError.Create('Not in OpenGL mode');

View File

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

View File

@ -1,6 +1,6 @@
{
This file is part of the PTCPas framebuffer library
Copyright (C) 2001-2012 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2001-2012,2017 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C++ version by Christian Nentwich (c.nentwich@cs.ucl.ac.uk)
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
}
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;
begin
if (sym >= 0) and (sym <= $FF) then
@ -61,206 +80,724 @@ begin
XK_Escape: exit(27);
End;
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 }
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);
{ 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 }
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);
{ 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 }
{ 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);
{ 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 }
{ 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 }
{ 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 }
{ 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;
X11ConvertKeySymToUnicode := -1;
end;

View File

@ -1,6 +1,6 @@
{
This file is part of the PTCPas framebuffer library
Copyright (C) 2001-2013 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2001-2013, 2016 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C++ version by Christian Nentwich (c.nentwich@cs.ucl.ac.uk)
This library is free software; you can redistribute it and/or
@ -44,6 +44,7 @@ type
FCursorVisible: Boolean;
FGrabMouse: Boolean;
FMouseGrabbed: Boolean;
FRelativeMouseMode: Boolean;
FX11InvisibleCursor: TCursor; { Blank cursor }
FFullScreen: Boolean; { Keeps a snapshot of the PTC_X11_FULLSCREEN option
taken at the time 'open' was called }
@ -62,6 +63,13 @@ type
FGLXFBConfig: TX11GLXFBConfig;
{$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 LeaveFullScreen;
procedure internal_ShowCursor(AVisible: Boolean);
@ -99,6 +107,8 @@ type
function IsOpen: Boolean; override;
procedure SetCursor(AVisible: 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}
procedure OpenGL_SwapBuffers; override;
procedure OpenGL_SetSwapInterval(AInterval: Integer); override;

View File

@ -1,6 +1,6 @@
{
This file is part of the PTCPas framebuffer library
Copyright (C) 2001-2013 Nikolay Nikolov (nickysn@users.sourceforge.net)
Copyright (C) 2001-2013, 2016, 2017 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C++ version by Christian Nentwich (c.nentwich@cs.ucl.ac.uk)
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);
{$IFDEF ENABLE_X11_EXTENSION_XINPUT2}
var
MajorVer, MinorVer: cint;
QueryVersionResult: TStatus;
{$ENDIF ENABLE_X11_EXTENSION_XINPUT2}
begin
inherited;
FFocus := True;
@ -38,6 +43,34 @@ begin
FCursorVisible := True;
FGrabMouse := 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;
destructor TX11WindowDisplay.Destroy;
@ -46,6 +79,14 @@ begin
inherited Destroy;
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);
var
xgcv: TXGCValues;
@ -62,6 +103,119 @@ var
BlankCursorData: array [1..8] of Byte = (0, 0, 0, 0, 0, 0, 0, 0);
CreateWindow_Depth: cint;
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
FHeight := AHeight;
FWidth := AWidth;
@ -82,6 +236,10 @@ begin
BlackColor.green := 0;
BlackColor.blue := 0;
{ Try to open an input method }
if PTC_X11_TRY_XIM in FFlags then
TryCreateIM;
{ Create the mode switcher object }
if (FModeSwitcher = Nil) and FFullScreen then
FModeSwitcher := CreateModeSwitcher;
@ -205,13 +363,40 @@ begin
if e._type = MapNotify then
Break;
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 }
XSelectInput(FDisplay, FWindow, KeyPressMask or KeyReleaseMask or
StructureNotifyMask or FocusChangeMask or
ButtonPressMask or ButtonReleaseMask or
PointerMotionMask or ExposureMask);
PointerMotionMask or ExposureMask or
EnterWindowMask or LeaveWindowMask or im_event_mask);
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
begin
{ Create XImage using factory method }
@ -267,6 +452,20 @@ begin
FreeAndNil(FGLXFBConfig);
{$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?!}
if FCMap <> 0 then
begin
@ -392,6 +591,15 @@ begin
internal_GrabMouse(FGrabMouse);
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;
begin
{ try to switch mode }
@ -480,6 +688,22 @@ var
before, after: Boolean;
cstate: TPTCMouseButtonState;
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
MotionNotify: begin
x := e.xmotion.x;
@ -498,6 +722,8 @@ var
Button3: state := state or Button3Mask;
Button4: state := state or Button4Mask;
Button5: state := state or Button5Mask;
6..Ord(High(TPTCMouseButton))+1:
Include(PTCMouseButtonState, TPTCMouseButton((Ord(PTCMouseButton6)-6)+e.xbutton.button));
end;
end
else
@ -508,6 +734,8 @@ var
Button3: state := state and (not Button3Mask);
Button4: state := state and (not Button4Mask);
Button5: state := state and (not Button5Mask);
6..Ord(High(TPTCMouseButton))+1:
Exclude(PTCMouseButtonState, TPTCMouseButton((Ord(PTCMouseButton6)-6)+e.xbutton.button));
end;
end;
end;
@ -515,10 +743,8 @@ var
raise TPTCError.Create('Internal Error');
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
PTCMouseButtonState := PTCMouseButtonState + [PTCMouseButton3];
if (state and Button3Mask) <> 0 then
@ -535,6 +761,12 @@ var
FPreviousMouseX := x; { first DeltaX will be 0 }
FPreviousMouseY := y; { first DeltaY will be 0 }
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;
{ movement? }
@ -581,11 +813,149 @@ var
FPreviousHeight := e.xconfigure.height;
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
NewFocusSpecified := False;
while UsefulEventsPending do
begin
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
FocusIn: begin
NewFocus := True;
@ -609,6 +979,30 @@ begin
ConfigureNotify: HandleConfigureNotifyEvent;
KeyPress, KeyRelease: HandleKeyEvent(e.xkey);
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;
if NewFocusSpecified then
@ -618,6 +1012,14 @@ begin
internal_GrabMouse(FGrabMouse);
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;
begin
if not (PTC_X11_USE_OPENGL in FFlags) then

122
packages/ptc/tests/event.pp Normal file
View File

@ -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.