Commit 5b5fe394 authored by cutealien's avatar cutealien

Add support for changing cursors.

We use multicolor hardware cursors, but so far only Linux and Windows 32 are supported.
For Linux application must now link additionally with Xcursor unless they disable _IRR_LINUX_XCURSOR_.
Example 24 is added to show how to use those cursors and also as a general test for mouse-behavior.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3302 dfc29bdd-3216-0410-991c-e03cc46cb475
parent a5046f4b
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -33,7 +33,7 @@ all: all_linux ...@@ -33,7 +33,7 @@ all: all_linux
# target specific settings # target specific settings
all_linux all_win32 static_win32: LDFLAGS += -L$(IrrlichtHome)/lib/$(SYSTEM) -lIrrlicht all_linux all_win32 static_win32: LDFLAGS += -L$(IrrlichtHome)/lib/$(SYSTEM) -lIrrlicht
all_linux: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32 clean_win32 static_win32: SYSTEM=Win32-gcc all_win32 clean_win32 static_win32: SYSTEM=Win32-gcc
all_win32 clean_win32 static_win32: SUF=.exe all_win32 clean_win32 static_win32: SUF=.exe
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht
static_win32: LDFLAGS += -lgdi32 -lopengl32 -ld3dx9d -lwinmm -lm static_win32: LDFLAGS += -lgdi32 -lopengl32 -ld3dx9d -lwinmm -lm
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux/" /> <Add directory="../../lib/Linux/" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32: CPPFLAGS += -D__GNUWIN32__ -D_WIN32 -DWIN32 -D_WINDOWS -D_MBCS -D_USRDLL all_win32: CPPFLAGS += -D__GNUWIN32__ -D_WIN32 -DWIN32 -D_WINDOWS -D_MBCS -D_USRDLL
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="..\..\lib\Linux" /> <Add directory="..\..\lib\Linux" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
<Add option="-W" /> <Add option="-W" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" />
<Add directory="..\..\lib\Linux" /> <Add directory="..\..\lib\Linux" />
</Linker> </Linker>
</Target> </Target>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/gcc" /> <Add directory="../../lib/gcc" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32: CPPFLAGS += -D__GNUWIN32__ -D_WIN32 -DWIN32 -D_WINDOWS -D_MBCS -D_USRDLL all_win32: CPPFLAGS += -D__GNUWIN32__ -D_WIN32 -DWIN32 -D_WINDOWS -D_MBCS -D_USRDLL
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32: CPPFLAGS += -D__GNUWIN32__ -D_WIN32 -DWIN32 -D_WINDOWS -D_MBCS -D_USRDLL all_win32: CPPFLAGS += -D__GNUWIN32__ -D_WIN32 -DWIN32 -D_WINDOWS -D_MBCS -D_USRDLL
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
......
...@@ -17,7 +17,7 @@ LIBSELECT=64 ...@@ -17,7 +17,7 @@ LIBSELECT=64
endif endif
# target specific settings # target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
......
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="Irrlicht Example 24 Cursor Control" />
<Option pch_mode="0" />
<Option compiler="gcc" />
<Build>
<Target title="Linux">
<Option platforms="Unix;" />
<Option output="../../bin/Linux/CursorControl" prefix_auto="0" extension_auto="0" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-W" />
<Add option="-g" />
<Add option="-D_IRR_STATIC_LIB_" />
</Compiler>
<Linker>
<Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" />
<Add directory="../../lib/Linux" />
</Linker>
</Target>
<Target title="Windows">
<Option platforms="Windows;" />
<Option output="../../bin/Win32-gcc/CursorControl" prefix_auto="0" extension_auto="1" />
<Option type="1" />
<Option compiler="gcc" />
<Option projectResourceIncludeDirsRelation="1" />
<Compiler>
<Add option="-W" />
<Add option="-g" />
<Add directory="../../lib/Win32-gcc" />
</Compiler>
<Linker>
<Add directory="../../lib/Win32-gcc/" />
</Linker>
</Target>
</Build>
<VirtualTargets>
<Add alias="All" targets="Windows;" />
</VirtualTargets>
<Compiler>
<Add option="-W" />
<Add option="-g" />
<Add directory="../../include" />
</Compiler>
<Linker>
<Add library="Irrlicht" />
</Linker>
<Unit filename="main.cpp" />
<Extensions>
<code_completion />
<debugger />
<envvars />
</Extensions>
</Project>
</CodeBlocks_project_file>
# Makefile for Irrlicht Examples
# It's usually sufficient to change just the target name and source file list
# and be sure that CXX is set to a valid compiler
# Name of the executable created (.exe will be added automatically if necessary)
Target := 24.CursorControl
# List of source files, separated by spaces
Sources := main.cpp
# Path to Irrlicht directory, should contain include/ and lib/
IrrlichtHome := ../..
# Path for the executable. Note that Irrlicht.dll should usually also be there for win32 systems
BinPath = ../../bin/$(SYSTEM)
# general compiler settings (might need to be set when compiling the lib, too)
# preprocessor flags, e.g. defines and include paths
USERCPPFLAGS =
# compiler flags such as optimization flags
USERCXXFLAGS = -O3 -ffast-math
#USERCXXFLAGS = -g -Wall
# linker flags such as additional libraries and link paths
USERLDFLAGS =
####
#no changes necessary below this line
####
CPPFLAGS = -I$(IrrlichtHome)/include -I/usr/X11R6/include $(USERCPPFLAGS)
CXXFLAGS = $(USERCXXFLAGS)
LDFLAGS = $(USERLDFLAGS)
#default target is Linux
all: all_linux
# target specific settings
all_linux all_win32 static_win32: LDFLAGS += -L$(IrrlichtHome)/lib/$(SYSTEM) -lIrrlicht
all_linux: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux
all_win32 clean_win32 static_win32: SYSTEM=Win32-gcc
all_win32 clean_win32 static_win32: SUF=.exe
static_win32: CPPFLAGS += -D_IRR_STATIC_LIB_
all_win32: LDFLAGS += -lopengl32 -lm
static_win32: LDFLAGS += -lgdi32 -lwinspool -lcomdlg32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lopengl32
# name of the binary - only valid for targets which set SYSTEM
DESTPATH = $(BinPath)/$(Target)$(SUF)
all_linux all_win32 static_win32:
$(warning Building...)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(Sources) -o $(DESTPATH) $(LDFLAGS)
clean: clean_linux clean_win32
$(warning Cleaning...)
clean_linux clean_win32:
@$(RM) $(DESTPATH)
.PHONY: all all_win32 static_win32 clean clean_linux clean_win32
#multilib handling
ifeq ($(HOSTTYPE), x86_64)
LIBSELECT=64
endif
#solaris real-time features
ifeq ($(HOSTTYPE), sun4)
LDFLAGS += -lrt
endif
/** Example 024 Cursor Control
Show how to modify cursors and offer some useful tool-functions for creating cursors.
It can also be used for experiments with the mouse in general.
*/
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif
const int DELAY_TIME = 3000;
enum ETimerAction
{
ETA_MOUSE_VISIBLE,
ETA_MOUSE_INVISIBLE,
};
struct TimerAction
{
u32 TargetTime;
ETimerAction Action;
};
struct SAppContext
{
SAppContext()
: Device(0), InfoStatic(0), EventBox(0), CursorBox(0), SpriteBox(0)
, ButtonSetVisible(0), ButtonSetInvisible(0), ButtonSimulateBadFps(0)
, ButtonChangeIcon(0)
, SimulateBadFps(false)
{
}
void update()
{
if (!Device)
return;
u32 timeNow = Device->getTimer()->getTime();
for ( irr::u32 i=0; i < TimerActions.size(); ++i )
{
if ( timeNow >= TimerActions[i].TargetTime )
{
runTimerAction(TimerActions[i]);
TimerActions.erase(i);
}
else
{
++i;
}
}
}
void runTimerAction(const TimerAction& action)
{
if (ETA_MOUSE_VISIBLE == action.Action)
{
Device->getCursorControl()->setVisible(true);
ButtonSetVisible->setEnabled(true);
}
else if ( ETA_MOUSE_INVISIBLE == action.Action)
{
Device->getCursorControl()->setVisible(false);
ButtonSetInvisible->setEnabled(true);
}
}
IrrlichtDevice * Device;
irr::gui::IGUIStaticText * InfoStatic;
irr::gui::IGUIListBox * EventBox;
irr::gui::IGUIListBox * CursorBox;
irr::gui::IGUIListBox * SpriteBox;
irr::gui::IGUIButton * ButtonSetVisible;
irr::gui::IGUIButton * ButtonSetInvisible;
irr::gui::IGUIButton * ButtonSimulateBadFps;
irr::gui::IGUIButton * ButtonChangeIcon;
irr::core::array<TimerAction> TimerActions;
bool SimulateBadFps;
irr::core::array<SCursorSprite> Sprites;
};
void PrintMouseEventName(const SEvent& event, irr::core::stringw &result)
{
switch ( event.MouseInput.Event )
{
case EMIE_LMOUSE_PRESSED_DOWN: result += stringw(L"EMIE_LMOUSE_PRESSED_DOWN"); break;
case EMIE_RMOUSE_PRESSED_DOWN: result += stringw(L"EMIE_RMOUSE_PRESSED_DOWN"); break;
case EMIE_MMOUSE_PRESSED_DOWN: result += stringw(L"EMIE_MMOUSE_PRESSED_DOWN"); break;
case EMIE_LMOUSE_LEFT_UP: result += stringw(L"EMIE_LMOUSE_LEFT_UP"); break;
case EMIE_RMOUSE_LEFT_UP: result += stringw(L"EMIE_RMOUSE_LEFT_UP"); break;
case EMIE_MMOUSE_LEFT_UP: result += stringw(L"EMIE_MMOUSE_LEFT_UP"); break;
case EMIE_MOUSE_MOVED: result += stringw(L"EMIE_MOUSE_MOVED"); break;
case EMIE_MOUSE_WHEEL: result += stringw(L"EMIE_MOUSE_WHEEL"); break;
case EMIE_LMOUSE_DOUBLE_CLICK: result += stringw(L"EMIE_LMOUSE_DOUBLE_CLICK"); break;
case EMIE_RMOUSE_DOUBLE_CLICK: result += stringw(L"EMIE_RMOUSE_DOUBLE_CLICK"); break;
case EMIE_MMOUSE_DOUBLE_CLICK: result += stringw(L"EMIE_MMOUSE_DOUBLE_CLICK"); break;
case EMIE_LMOUSE_TRIPLE_CLICK: result += stringw(L"EMIE_LMOUSE_TRIPLE_CLICK"); break;
case EMIE_RMOUSE_TRIPLE_CLICK: result += stringw(L"EMIE_RMOUSE_TRIPLE_CLICK"); break;
case EMIE_MMOUSE_TRIPLE_CLICK: result += stringw(L"EMIE_MMOUSE_TRIPLE_CLICK"); break;
default:
break;
}
}
void PrintMouseState(const SEvent& event, irr::core::stringw &result)
{
result += stringw(L"X: ");
result += stringw(event.MouseInput.X);
result += stringw(L"\n");
result += stringw(L"Y: ");
result += stringw(event.MouseInput.Y);
result += stringw(L"\n");
result += stringw(L"Wheel: ");
result += stringw(event.MouseInput.Wheel);
result += stringw(L"\n");
result += stringw(L"Shift: ");
if ( event.MouseInput.Shift )
result += stringw(L"true\n");
else
result += stringw(L"false\n");
result += stringw(L"Control: ");
if ( event.MouseInput.Control )
result += stringw(L"true\n");
else
result += stringw(L"false\n");
result += stringw(L"ButtonStates: ");
result += stringw(event.MouseInput.ButtonStates);
result += stringw(L"\n");
result += stringw(L"isLeftPressed: ");
if ( event.MouseInput.isLeftPressed() )
result += stringw(L"true\n");
else
result += stringw(L"false\n");
result += stringw(L"isRightPressed: ");
if ( event.MouseInput.isRightPressed() )
result += stringw(L"true\n");
else
result += stringw(L"false\n");
result += stringw(L"isMiddlePressed: ");
if ( event.MouseInput.isMiddlePressed() )
result += stringw(L"true\n");
else
result += stringw(L"false\n");
result += stringw(L"Event: ");
PrintMouseEventName(event, result);
result += stringw(L"\n");
}
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(SAppContext & context) : Context(context) { }
virtual bool OnEvent(const SEvent& event)
{
if (event.EventType == EET_GUI_EVENT )
{
switch ( event.GUIEvent.EventType )
{
case EGET_BUTTON_CLICKED:
{
u32 timeNow = Context.Device->getTimer()->getTime();
TimerAction action;
action.TargetTime = timeNow + DELAY_TIME;
if ( event.GUIEvent.Caller == Context.ButtonSetVisible )
{
action.Action = ETA_MOUSE_VISIBLE;
Context.TimerActions.push_back(action);
Context.ButtonSetVisible->setEnabled(false);
}
else if ( event.GUIEvent.Caller == Context.ButtonSetInvisible )
{
action.Action = ETA_MOUSE_INVISIBLE;
Context.TimerActions.push_back(action);
Context.ButtonSetInvisible->setEnabled(false);
}
else if ( event.GUIEvent.Caller == Context.ButtonSimulateBadFps )
{
Context.SimulateBadFps = Context.ButtonSimulateBadFps->isPressed();
}
else if ( event.GUIEvent.Caller == Context.ButtonChangeIcon )
{
irr::s32 selectedCursor = Context.CursorBox->getSelected();
irr::s32 selectedSprite = Context.SpriteBox->getSelected();
if ( selectedCursor >= 0 && selectedSprite >= 0 )
{
Context.Device->getCursorControl()->changeIcon((ECURSOR_ICON)selectedCursor, Context.Sprites[selectedSprite] );
Context.Device->getCursorControl()->setActiveIcon( ECURSOR_ICON(selectedCursor) );
}
}
}
break;
case EGET_LISTBOX_CHANGED:
case EGET_LISTBOX_SELECTED_AGAIN:
{
if ( event.GUIEvent.Caller == Context.CursorBox )
{
irr::s32 selected = Context.CursorBox->getSelected();
if ( selected >= 0 )
Context.Device->getCursorControl()->setActiveIcon( ECURSOR_ICON(selected) );
}
}
break;
default:
break;
}
}
if (event.EventType == EET_MOUSE_INPUT_EVENT)
{
irr::core::stringw infoText;
PrintMouseState(event, infoText);
Context.InfoStatic->setText(infoText.c_str());
if ( event.MouseInput.Event != EMIE_MOUSE_MOVED && event.MouseInput.Event != EMIE_MOUSE_WHEEL ) // no spam
{
infoText = L"";
PrintMouseEventName(event, infoText);
Context.EventBox->insertItem(0, infoText.c_str(), -1);
}
}
return false;
}
private:
SAppContext & Context;
};
// Use several imagefiles as animation frames for a sprite which can be used as cursor icon.
// The images in those files all need to have the same size.
// Return sprite index on success or -1 on failure
irr::s32 AddAnimatedIcon( irr::gui::IGUISpriteBank * spriteBank, video::IVideoDriver* driver, const irr::core::array< irr::io::path >& files, u32 frameTime )
{
if ( !spriteBank || !driver || !files.size() )
return -1;
irr::video::ITexture * tex = driver->getTexture( files[0] );
if ( tex )
{
core::array< core::rect<s32> >& spritePositions = spriteBank->getPositions();
u32 idxRect = spritePositions.size();
spritePositions.push_back( core::rect<s32>(0,0, tex->getSize().Width, tex->getSize().Height) );
SGUISprite sprite;
sprite.frameTime = frameTime;
core::array< SGUISprite >& sprites = spriteBank->getSprites();
u32 startIdx = spriteBank->getTextureCount();
for ( u32 f=0; f < files.size(); ++f )
{
tex = driver->getTexture( files[f] );
if ( tex )
{
spriteBank->addTexture( driver->getTexture(files[f]) );
irr::gui::SGUISpriteFrame frame;
frame.rectNumber = idxRect;
frame.textureNumber = startIdx+f;
sprite.Frames.push_back( frame );
}
}
sprites.push_back( sprite );
return sprites.size()-1;
}
return -1;
}
// Use several images within one imagefile as animation frames for a sprite which can be used as cursor icon
// The sizes of the icons within that file all need to have the same size
// Return sprite index on success or -1 on failure
irr::s32 AddAnimatedIcon( irr::gui::IGUISpriteBank * spriteBank, video::IVideoDriver* driver, const irr::io::path& file, const irr::core::array< irr::core::rect<s32> >& rects, u32 frameTime )
{
if ( !spriteBank || !driver || !rects.size() )
return -1;
irr::video::ITexture * tex = driver->getTexture( file );
if ( tex )
{
core::array< core::rect<s32> >& spritePositions = spriteBank->getPositions();
u32 idxRect = spritePositions.size();
u32 idxTex = spriteBank->getTextureCount();
spriteBank->addTexture( tex );
SGUISprite sprite;
sprite.frameTime = frameTime;
core::array< SGUISprite >& sprites = spriteBank->getSprites();
for ( u32 i=0; i < rects.size(); ++i )
{
spritePositions.push_back( rects[i] );
irr::gui::SGUISpriteFrame frame;
frame.rectNumber = idxRect+i;
frame.textureNumber = idxTex;
sprite.Frames.push_back( frame );
}
sprites.push_back( sprite );
return sprites.size()-1;
}
return -1;
}
int main()
{
video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
IrrlichtDevice * device = createDevice(driverType, core::dimension2d<u32>(640, 480));
if (device == 0)
return 1; // could not create selected driver.
device->setWindowCaption(L"Cursor control - Irrlicht engine tutorial");
video::IVideoDriver* driver = device->getVideoDriver();
IGUIEnvironment* env = device->getGUIEnvironment();
irr::gui::IGUISpriteBank * SpriteBankIcons;
SAppContext context;
context.Device = device;
core::rect< s32 > rectInfoStatic(10,10, 200, 200);
env->addStaticText (L"Cursor state information", rectInfoStatic, true, true);
rectInfoStatic.UpperLeftCorner += core::dimension2di(0, 15);
context.InfoStatic = env->addStaticText (L"", rectInfoStatic, true, true);
core::rect< s32 > rectEventBox(10,210, 200, 400);
env->addStaticText (L"click events (new on top)", rectEventBox, true, true);
rectEventBox.UpperLeftCorner += core::dimension2di(0, 15);
context.EventBox = env->addListBox(rectEventBox);
core::rect< s32 > rectCursorBox(210,10, 400, 250);
env->addStaticText (L"cursors, click to set the active one", rectCursorBox, true, true);
rectCursorBox.UpperLeftCorner += core::dimension2di(0, 15);
context.CursorBox = env->addListBox(rectCursorBox);
core::rect< s32 > rectSpriteBox(210,260, 400, 400);
env->addStaticText (L"sprites", rectSpriteBox, true, true);
rectSpriteBox.UpperLeftCorner += core::dimension2di(0, 15);
context.SpriteBox = env->addListBox(rectSpriteBox);
context.ButtonSetVisible = env->addButton( rect<s32>( 410, 20, 560, 40 ), 0, -1, L"set visible (delayed)" );
context.ButtonSetInvisible = env->addButton( rect<s32>( 410, 50, 560, 70 ), 0, -1, L"set invisible (delayed)" );
context.ButtonSimulateBadFps = env->addButton( rect<s32>( 410, 80, 560, 100 ), 0, -1, L"simulate bad FPS" );
context.ButtonSimulateBadFps->setIsPushButton(true);
context.ButtonChangeIcon = env->addButton( rect<s32>( 410, 140, 560, 160 ), 0, -1, L"change cursor icon\n(cursor+sprite must be selected)" );
// create sprites for cursor icons
SpriteBankIcons = env->addEmptySpriteBank(io::path("cursor_icons"));
context.SpriteBox->setSpriteBank(SpriteBankIcons);
// create an animated icon from several files
irr::core::array< irr::io::path > files;
files.push_back( irr::io::path("../../media/icon_crosshairs16x16bw1.png") );
files.push_back( irr::io::path("../../media/icon_crosshairs16x16bw2.png") );
files.push_back( irr::io::path("../../media/icon_crosshairs16x16bw3.png") );
files.push_back( irr::io::path("../../media/icon_crosshairs16x16bw3.png") );
files.push_back( irr::io::path("../../media/icon_crosshairs16x16bw2.png") );
irr::s32 SpriteIdxBw = AddAnimatedIcon( SpriteBankIcons, driver, files, 200 );
SCursorSprite spriteBw( SpriteBankIcons, SpriteIdxBw, core::position2d<s32>(7,7) );
context.SpriteBox->addItem(L"crosshair_bw", SpriteIdxBw);
context.Sprites.push_back(spriteBw);
// create an animated icon from one file
irr::core::array< irr::core::rect<s32> > iconRects;
iconRects.push_back( irr::core::rect<s32>(0,0, 16, 16) );
iconRects.push_back( irr::core::rect<s32>(16,0, 32, 16) );
iconRects.push_back( irr::core::rect<s32>(0,16, 16, 32) );
iconRects.push_back( irr::core::rect<s32>(0,16, 16, 32) );
iconRects.push_back( irr::core::rect<s32>(16,0, 32, 16) );
irr::s32 SpriteIdxCol = AddAnimatedIcon( SpriteBankIcons, driver, irr::io::path("../../media/icon_crosshairs16x16col.png"), iconRects, 200 );
SCursorSprite spriteCol( SpriteBankIcons, SpriteIdxCol, core::position2d<s32>(7,7) );
context.SpriteBox->addItem(L"up_icon_colored", SpriteIdxCol);
context.Sprites.push_back(spriteCol);
for ( int i=0; i < (int)gui::ECI_COUNT; ++i )
{
context.CursorBox->addItem(core::stringw( GUICursorIconNames[i] ).c_str());
}
context.Device->getCursorControl()->addIcon(spriteBw);
context.CursorBox->addItem(L"black-white");
context.Device->getCursorControl()->addIcon(spriteCol);
context.CursorBox->addItem(L"color");
MyEventReceiver receiver(context);
device->setEventReceiver(&receiver);
while(device->run() && driver)
{
// if (device->isWindowActive())
{
u32 realTimeNow = device->getTimer()->getRealTime();
context.update();
driver->beginScene(true, true, SColor(0,200,200,200));
env->drawAll();
// draw custom sprite with normal functions for comparison and to show the difference also for the hardware cursor.
if ( SpriteIdxCol >= 0 )
SpriteBankIcons->draw2DSprite(u32(SpriteIdxCol), core::position2di(30, 140), 0, video::SColor(255, 255, 255, 255), 0, realTimeNow);
if ( SpriteIdxBw >= 0 )
SpriteBankIcons->draw2DSprite(u32(SpriteIdxBw), core::position2di(80, 140), 0, video::SColor(255, 255, 255, 255), 0, realTimeNow);
driver->endScene();
}
// By simulating bad fps we can find out if hardware-support for cusors works or not. If it works the cursor will move as usual,while it otherwise will just update with 2 fps now.
if ( context.SimulateBadFps )
{
device->sleep(500); // 2 fps
}
else
{
device->sleep(10);
}
}
device->drop();
return 0;
}
/*
**/
...@@ -13,7 +13,7 @@ all: all_linux ...@@ -13,7 +13,7 @@ all: all_linux
# target specific settings # target specific settings
all_linux: SYSTEM=Linux all_linux: SYSTEM=Linux
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/$(SYSTEM) -lIrrlicht -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/$(SYSTEM) -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SYSTEM=Win32-gcc
all_win32: LDFLAGS = -L../../lib/$(SYSTEM) -lIrrlicht -lopengl32 -lm all_win32: LDFLAGS = -L../../lib/$(SYSTEM) -lIrrlicht -lopengl32 -lm
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="Irrlicht" /> <Add library="Irrlicht" />
<Add library="GL" /> <Add library="GL" />
<Add directory="../../lib/Linux" /> <Add directory="../../lib/Linux" />
......
...@@ -14,6 +14,70 @@ namespace irr ...@@ -14,6 +14,70 @@ namespace irr
namespace gui namespace gui
{ {
class IGUISpriteBank;
//! Default icons for cursors
enum ECURSOR_ICON
{
// Following cursors might be system specific, or might use an Irrlicht icon-set. No guarantees so far.
ECI_NORMAL, // arrow
ECI_CROSS, // Crosshair
ECI_HAND, // Hand
ECI_HELP, // Arrow and question mark
ECI_IBEAM, // typical text-selection cursor
ECI_NO, // should not click icon
ECI_WAIT, // hourclass
ECI_SIZEALL, // arrow in all directions
ECI_SIZENESW, // resizes in direction north-east or south-west
ECI_SIZENWSE, // resizes in direction north-west or south-east
ECI_SIZENS, // resizes in direction north or south
ECI_SIZEWE, // resizes in direction west or east
ECI_UP, // up-arrow
// Implementer note: Should we add system specific cursors, which use guaranteed the system icons,
// then I would recommend using a naming scheme like ECI_W32_CROSS, ECI_X11_CROSSHAIR and adding those
// additionally.
ECI_COUNT // maximal of defined cursors. Note that higher values can be created at runtime
};
//! Names for ECURSOR_ICON
const c8* const GUICursorIconNames[ECI_COUNT+1] =
{
"normal",
"cross",
"hand",
"help",
"ibeam",
"no",
"wait",
"sizeall",
"sizenesw",
"sizenwse",
"sizens",
"sizewe",
"sizeup",
0
};
//! structure used to set sprites as cursors.
struct SCursorSprite
{
SCursorSprite()
: SpriteBank(0), SpriteId(-1)
{
}
SCursorSprite( gui::IGUISpriteBank * spriteBank, s32 spriteId, const core::position2d<s32> &hotspot=core::position2d<s32>(0,0) )
: SpriteBank(spriteBank), SpriteId(spriteId), HotSpot(hotspot)
{
}
gui::IGUISpriteBank * SpriteBank;
s32 SpriteId;
core::position2d<s32> HotSpot;
};
//! Interface to manipulate the mouse cursor. //! Interface to manipulate the mouse cursor.
class ICursorControl : public virtual IReferenceCounted class ICursorControl : public virtual IReferenceCounted
{ {
...@@ -73,6 +137,28 @@ namespace gui ...@@ -73,6 +137,28 @@ namespace gui
for example in an editor. for example in an editor.
\param rect: A pointer to an reference rectangle or 0 to disable the reference rectangle.*/ \param rect: A pointer to an reference rectangle or 0 to disable the reference rectangle.*/
virtual void setReferenceRect(core::rect<s32>* rect=0) = 0; virtual void setReferenceRect(core::rect<s32>* rect=0) = 0;
//! Sets the active cursor icon
/** Setting cursor icons is so far only supported on Win32 and Linux */
virtual void setActiveIcon(ECURSOR_ICON iconId) {}
//! Gets the currently active icon
virtual ECURSOR_ICON getActiveIcon() const { return gui::ECI_NORMAL; }
//! Add a custom sprite as cursor icon.
/** \return Identification for the icon */
virtual ECURSOR_ICON addIcon(const gui::SCursorSprite& icon) { return gui::ECI_NORMAL; }
//! replace a cursor icon.
/** Changing cursor icons is so far only supported on Win32 and Linux
Note that this only changes the icons within your application, system cursors outside your
application will not be affected.
*/
virtual void changeIcon(ECURSOR_ICON iconId, const gui::SCursorSprite& sprite) {}
//! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work.
virtual core::dimension2di getSupportedIconSize() const { return core::dimension2di(0,0); }
}; };
......
...@@ -15,50 +15,6 @@ namespace irr ...@@ -15,50 +15,6 @@ namespace irr
namespace video namespace video
{ {
//! An enum for the color format of textures used by the Irrlicht Engine.
/** A color format specifies how color information is stored. */
enum ECOLOR_FORMAT
{
//! 16 bit color format used by the software driver.
/** It is thus preferred by all other irrlicht engine video drivers.
There are 5 bits for every color component, and a single bit is left
for alpha information. */
ECF_A1R5G5B5 = 0,
//! Standard 16 bit color format.
ECF_R5G6B5,
//! 24 bit color, no alpha channel, but 8 bit for red, green and blue.
ECF_R8G8B8,
//! Default 32 bit color format. 8 bits are used for every component: red, green, blue and alpha.
ECF_A8R8G8B8,
/** Floating Point formats. The following formats may only be used for render target textures. */
//! 16 bit floating point format using 16 bits for the red channel.
ECF_R16F,
//! 32 bit floating point format using 16 bits for the red channel and 16 bits for the green channel.
ECF_G16R16F,
//! 64 bit floating point format 16 bits are used for the red, green, blue and alpha channels.
ECF_A16B16G16R16F,
//! 32 bit floating point format using 32 bits for the red channel.
ECF_R32F,
//! 64 bit floating point format using 32 bits for the red channel and 32 bits for the green channel.
ECF_G32R32F,
//! 128 bit floating point format. 32 bits are used for the red, green, blue and alpha channels.
ECF_A32B32G32R32F,
//! Unknown color format:
ECF_UNKNOWN
};
//! Interface for software image data. //! Interface for software image data.
/** Image loaders create these images from files. IVideoDrivers convert /** Image loaders create these images from files. IVideoDrivers convert
these images into their (hardware) textures. these images into their (hardware) textures.
......
...@@ -151,9 +151,11 @@ define out. */ ...@@ -151,9 +151,11 @@ define out. */
//! On some Linux systems the XF86 vidmode extension or X11 RandR are missing. Use these flags //! On some Linux systems the XF86 vidmode extension or X11 RandR are missing. Use these flags
//! to remove the dependencies such that Irrlicht will compile on those systems, too. //! to remove the dependencies such that Irrlicht will compile on those systems, too.
//! If you don't need colored cursors you can also disable the Xcursor extension
#if defined(_IRR_LINUX_PLATFORM_) && defined(_IRR_COMPILE_WITH_X11_) #if defined(_IRR_LINUX_PLATFORM_) && defined(_IRR_COMPILE_WITH_X11_)
#define _IRR_LINUX_X11_VIDMODE_ #define _IRR_LINUX_X11_VIDMODE_
//#define _IRR_LINUX_X11_RANDR_ //#define _IRR_LINUX_X11_RANDR_
#define _IRR_LINUX_XCURSOR_
#endif #endif
//! Define _IRR_COMPILE_WITH_GUI_ to compile the engine with the built-in GUI //! Define _IRR_COMPILE_WITH_GUI_ to compile the engine with the built-in GUI
......
...@@ -12,6 +12,50 @@ namespace irr ...@@ -12,6 +12,50 @@ namespace irr
{ {
namespace video namespace video
{ {
//! An enum for the color format of textures used by the Irrlicht Engine.
/** A color format specifies how color information is stored. */
enum ECOLOR_FORMAT
{
//! 16 bit color format used by the software driver.
/** It is thus preferred by all other irrlicht engine video drivers.
There are 5 bits for every color component, and a single bit is left
for alpha information. */
ECF_A1R5G5B5 = 0,
//! Standard 16 bit color format.
ECF_R5G6B5,
//! 24 bit color, no alpha channel, but 8 bit for red, green and blue.
ECF_R8G8B8,
//! Default 32 bit color format. 8 bits are used for every component: red, green, blue and alpha.
ECF_A8R8G8B8,
/** Floating Point formats. The following formats may only be used for render target textures. */
//! 16 bit floating point format using 16 bits for the red channel.
ECF_R16F,
//! 32 bit floating point format using 16 bits for the red channel and 16 bits for the green channel.
ECF_G16R16F,
//! 64 bit floating point format 16 bits are used for the red, green, blue and alpha channels.
ECF_A16B16G16R16F,
//! 32 bit floating point format using 32 bits for the red channel.
ECF_R32F,
//! 64 bit floating point format using 32 bits for the red channel and 32 bits for the green channel.
ECF_G32R32F,
//! 128 bit floating point format. 32 bits are used for the red, green, blue and alpha channels.
ECF_A32B32G32R32F,
//! Unknown color format:
ECF_UNKNOWN
};
//! Creates a 16 bit A1R5G5B5 color //! Creates a 16 bit A1R5G5B5 color
inline u16 RGBA16(u32 r, u32 g, u32 b, u32 a=0xFF) inline u16 RGBA16(u32 r, u32 g, u32 b, u32 a=0xFF)
{ {
...@@ -327,6 +371,77 @@ namespace video ...@@ -327,6 +371,77 @@ namespace video
getBlue() * mul0 + c1.getBlue() * mul1 + c2.getBlue() * mul2 ), 0, 255 )); getBlue() * mul0 + c1.getBlue() * mul1 + c2.getBlue() * mul2 ), 0, 255 ));
} }
//! set the color by expecting data in the given format
/** \param data: must point to valid memory containing color information in the given format
\param format: tells the format in which data is available
*/
void setData(const void *data, ECOLOR_FORMAT format)
{
switch (format)
{
case ECF_A1R5G5B5:
color = A1R5G5B5toA8R8G8B8(*(u16*)data);
break;
case ECF_R5G6B5:
color = R5G6B5toA8R8G8B8(*(u16*)data);
break;
case ECF_A8R8G8B8:
color = *(u32*)data;
break;
case ECF_R8G8B8:
{
u8* p = (u8*)data;
set(255, p[0],p[1],p[2]);
}
break;
default:
break;
}
}
//! Write the color to data in the defined format
/** \param data: target to write the color. Must contain sufficiently large memory to receive the number of bytes neede for format
\param format: tells the format used to write the color into data
*/
void getData(void *data, ECOLOR_FORMAT format)
{
switch(format)
{
case ECF_A1R5G5B5:
{
u16 * dest = (u16*)data;
*dest = video::A8R8G8B8toA1R5G5B5( color );
}
break;
case ECF_R5G6B5:
{
u16 * dest = (u16*)data;
*dest = video::A8R8G8B8toR5G6B5( color );
}
break;
case ECF_R8G8B8:
{
u8* dest = (u8*)data;
dest[0] = (u8)getRed();
dest[1] = (u8)getGreen();
dest[2] = (u8)getBlue();
}
break;
case ECF_A8R8G8B8:
{
u32 * dest = (u32*)data;
*dest = color;
}
break;
default:
break;
}
}
//! color in A8R8G8B8 Format //! color in A8R8G8B8 Format
u32 color; u32 color;
}; };
......
...@@ -18,9 +18,14 @@ ...@@ -18,9 +18,14 @@
#include "COSOperator.h" #include "COSOperator.h"
#include "CColorConverter.h" #include "CColorConverter.h"
#include "SIrrCreationParameters.h" #include "SIrrCreationParameters.h"
#include "IGUISpriteBank.h"
#include <X11/XKBlib.h> #include <X11/XKBlib.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#ifdef _IRR_LINUX_XCURSOR_
#include <X11/Xcursor/Xcursor.h>
#endif
#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ #if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
...@@ -131,6 +136,7 @@ CIrrDeviceLinux::~CIrrDeviceLinux() ...@@ -131,6 +136,7 @@ CIrrDeviceLinux::~CIrrDeviceLinux()
XFree(StdHints); XFree(StdHints);
// Disable cursor and free it later on // Disable cursor and free it later on
CursorControl->setVisible(false); CursorControl->setVisible(false);
CursorControl->drop();
if (display) if (display)
{ {
#ifdef _IRR_COMPILE_WITH_OPENGL_ #ifdef _IRR_COMPILE_WITH_OPENGL_
...@@ -823,6 +829,9 @@ bool CIrrDeviceLinux::run() ...@@ -823,6 +829,9 @@ bool CIrrDeviceLinux::run()
os::Timer::tick(); os::Timer::tick();
#ifdef _IRR_COMPILE_WITH_X11_ #ifdef _IRR_COMPILE_WITH_X11_
static_cast<CCursorControl*>(CursorControl)->update();
if ((CreationParams.DriverType != video::EDT_NULL) && display) if ((CreationParams.DriverType != video::EDT_NULL) && display)
{ {
SEvent irrevent; SEvent irrevent;
...@@ -1907,6 +1916,301 @@ void CIrrDeviceLinux::initXAtoms() ...@@ -1907,6 +1916,301 @@ void CIrrDeviceLinux::initXAtoms()
#endif #endif
} }
#ifdef _IRR_COMPILE_WITH_X11_
Cursor CIrrDeviceLinux::TextureToMonochromeCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot)
{
XImage * sourceImage = XCreateImage(display, visual->visual,
1, // depth,
ZPixmap, // XYBitmap (depth=1), ZPixmap(depth=x)
0, 0, sourceRect.getWidth(), sourceRect.getHeight(),
32, // bitmap_pad,
0// bytes_per_line (0 means continuos in memory)
);
sourceImage->data = new char[sourceImage->height * sourceImage->bytes_per_line];
XImage * maskImage = XCreateImage(display, visual->visual,
1, // depth,
ZPixmap,
0, 0, sourceRect.getWidth(), sourceRect.getHeight(),
32, // bitmap_pad,
0 // bytes_per_line
);
maskImage->data = new char[maskImage->height * maskImage->bytes_per_line];
// write texture into XImage
video::ECOLOR_FORMAT format = tex->getColorFormat();
u32 bytesPerPixel = video::IImage::getBitsPerPixelFromFormat(format) / 8;
u32 bytesLeftGap = sourceRect.UpperLeftCorner.X * bytesPerPixel;
u32 bytesRightGap = tex->getPitch() - sourceRect.LowerRightCorner.X * bytesPerPixel;
const u8* data = (const u8*)tex->lock(true, 0);
data += sourceRect.UpperLeftCorner.Y*tex->getPitch();
for ( s32 y = 0; y < sourceRect.getHeight(); ++y )
{
data += bytesLeftGap;
for ( s32 x = 0; x < sourceRect.getWidth(); ++x )
{
video::SColor pixelCol;
pixelCol.setData((const void*)data, format);
data += bytesPerPixel;
if ( pixelCol.getAlpha() == 0 ) // transparent
{
XPutPixel(maskImage, x, y, 0);
XPutPixel(sourceImage, x, y, 0);
}
else // color
{
if ( pixelCol.getAverage() >= 127 )
XPutPixel(sourceImage, x, y, 1);
else
XPutPixel(sourceImage, x, y, 0);
XPutPixel(maskImage, x, y, 1);
}
}
data += bytesRightGap;
}
tex->unlock();
Pixmap sourcePixmap = XCreatePixmap(display, window, sourceImage->width, sourceImage->height, sourceImage->depth);
Pixmap maskPixmap = XCreatePixmap(display, window, maskImage->width, maskImage->height, maskImage->depth);
XGCValues values;
values.foreground = 1;
values.background = 1;
GC gc = XCreateGC( display, sourcePixmap, GCForeground | GCBackground, &values );
XPutImage(display, sourcePixmap, gc, sourceImage, 0, 0, 0, 0, sourceImage->width, sourceImage->height);
XPutImage(display, maskPixmap, gc, maskImage, 0, 0, 0, 0, maskImage->width, maskImage->height);
XFreeGC(display, gc);
XDestroyImage(sourceImage);
XDestroyImage(maskImage);
Cursor cursorResult = 0;
XColor foreground, background;
foreground.red = 65535;
foreground.green = 65535;
foreground.blue = 65535;
foreground.flags = DoRed | DoGreen | DoBlue;
background.red = 0;
background.green = 0;
background.blue = 0;
background.flags = DoRed | DoGreen | DoBlue;
cursorResult = XCreatePixmapCursor(display, sourcePixmap, maskPixmap, &foreground, &background, hotspot.X, hotspot.Y);
XFreePixmap(display, sourcePixmap);
XFreePixmap(display, maskPixmap);
return cursorResult;
}
#ifdef _IRR_LINUX_XCURSOR_
Cursor CIrrDeviceLinux::TextureToARGBCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot)
{
XcursorImage * image = XcursorImageCreate (sourceRect.getWidth(), sourceRect.getHeight());
image->xhot = hotspot.X;
image->yhot = hotspot.Y;
// write texture into XcursorImage
video::ECOLOR_FORMAT format = tex->getColorFormat();
u32 bytesPerPixel = video::IImage::getBitsPerPixelFromFormat(format) / 8;
u32 bytesLeftGap = sourceRect.UpperLeftCorner.X * bytesPerPixel;
u32 bytesRightGap = tex->getPitch() - sourceRect.LowerRightCorner.X * bytesPerPixel;
XcursorPixel* target = image->pixels;
const u8* data = (const u8*)tex->lock(true, 0);
data += sourceRect.UpperLeftCorner.Y*tex->getPitch();
for ( s32 y = 0; y < sourceRect.getHeight(); ++y )
{
data += bytesLeftGap;
for ( s32 x = 0; x < sourceRect.getWidth(); ++x )
{
video::SColor pixelCol;
pixelCol.setData((const void*)data, format);
data += bytesPerPixel;
*target = (XcursorPixel)pixelCol.color;
++target;
}
data += bytesRightGap;
}
tex->unlock();
Cursor cursorResult=XcursorImageLoadCursor(display, image);
XcursorImageDestroy(image);
return cursorResult;
}
#endif // #ifdef _IRR_LINUX_XCURSOR_
Cursor CIrrDeviceLinux::TextureToCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot)
{
#ifdef _IRR_LINUX_XCURSOR_
return TextureToARGBCursor( tex, sourceRect, hotspot );
#else
return TextureToMonochromeCursor( tex, sourceRect, hotspot );
#endif
}
#endif // _IRR_COMPILE_WITH_X11_
CIrrDeviceLinux::CCursorControl::CCursorControl(CIrrDeviceLinux* dev, bool null)
: Device(dev), IsVisible(true), Null(null), UseReferenceRect(false)
, ActiveIcon(gui::ECI_NORMAL), ActiveIconStartTime(0)
{
#ifdef _IRR_COMPILE_WITH_X11_
if (!Null)
{
XGCValues values;
unsigned long valuemask = 0;
XColor fg, bg;
// this code, for making the cursor invisible was sent in by
// Sirshane, thank your very much!
Pixmap invisBitmap = XCreatePixmap(Device->display, Device->window, 32, 32, 1);
Pixmap maskBitmap = XCreatePixmap(Device->display, Device->window, 32, 32, 1);
Colormap screen_colormap = DefaultColormap( Device->display, DefaultScreen( Device->display ) );
XAllocNamedColor( Device->display, screen_colormap, "black", &fg, &fg );
XAllocNamedColor( Device->display, screen_colormap, "white", &bg, &bg );
GC gc = XCreateGC( Device->display, invisBitmap, valuemask, &values );
XSetForeground( Device->display, gc, BlackPixel( Device->display, DefaultScreen( Device->display ) ) );
XFillRectangle( Device->display, invisBitmap, gc, 0, 0, 32, 32 );
XFillRectangle( Device->display, maskBitmap, gc, 0, 0, 32, 32 );
invisCursor = XCreatePixmapCursor( Device->display, invisBitmap, maskBitmap, &fg, &bg, 1, 1 );
XFreeGC(Device->display, gc);
XFreePixmap(Device->display, invisBitmap);
XFreePixmap(Device->display, maskBitmap);
initCursors();
}
#endif
}
CIrrDeviceLinux::CCursorControl::~CCursorControl()
{
for ( u32 i=0; i < Cursors.size(); ++i )
{
for ( u32 f=0; f < Cursors[i].Frames.size(); ++f )
{
XFreeCursor(Device->display, Cursors[i].Frames[f].IconHW);
}
}
}
#ifdef _IRR_COMPILE_WITH_X11_
void CIrrDeviceLinux::CCursorControl::initCursors()
{
Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_top_left_arrow)) ); // (or XC_arrow?)
Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_crosshair)) );
Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_hand2)) ); // (or XC_hand1? )
Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_question_arrow)) );
Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_xterm)) );
Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_X_cursor)) ); // (or XC_pirate?)
Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_watch)) ); // (or XC_clock?)
Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_fleur)) );
Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_top_right_corner)) ); // NESW not available in X11
Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_top_left_corner)) ); // NWSE not available in X11
Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_sb_v_double_arrow)) );
Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_sb_h_double_arrow)) );
Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_sb_up_arrow)) ); // (or XC_center_ptr?)
}
void CIrrDeviceLinux::CCursorControl::update()
{
if ( !Cursors[ActiveIcon].Frames.empty() && Cursors[ActiveIcon].FrameTime )
{
// update animated cursors. This could also be done by X11 in case someone wants to figure that out (this way was just easier to implement)
u32 now = Device->getTimer()->getRealTime();
u32 frame = ((now - ActiveIconStartTime) / Cursors[ActiveIcon].FrameTime) % Cursors[ActiveIcon].Frames.size();
XDefineCursor(Device->display, Device->window, Cursors[ActiveIcon].Frames[frame].IconHW);
}
}
#endif
//! Sets the active cursor icon
void CIrrDeviceLinux::CCursorControl::setActiveIcon(gui::ECURSOR_ICON iconId)
{
if ( iconId >= (s32)Cursors.size() )
return;
#ifdef _IRR_COMPILE_WITH_X11_
if ( Cursors[iconId].Frames.size() )
XDefineCursor(Device->display, Device->window, Cursors[iconId].Frames[0].IconHW);
#endif
ActiveIconStartTime = Device->getTimer()->getRealTime();
ActiveIcon = iconId;
}
//! Add a custom sprite as cursor icon.
gui::ECURSOR_ICON CIrrDeviceLinux::CCursorControl::addIcon(const gui::SCursorSprite& icon)
{
if ( icon.SpriteId >= 0 )
{
CursorX11 cX11;
cX11.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime;
for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i )
{
irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber;
irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber;
irr::core::rect<s32> rectIcon = icon.SpriteBank->getPositions()[rectId];
Cursor cursor = Device->TextureToCursor(icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot);
cX11.Frames.push_back( CursorFrameX11(cursor) );
}
Cursors.push_back( cX11 );
return (gui::ECURSOR_ICON)(Cursors.size() - 1);
}
return gui::ECI_NORMAL;
}
//! replace the given cursor icon.
void CIrrDeviceLinux::CCursorControl::changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon)
{
if ( iconId >= (s32)Cursors.size() )
return;
for ( u32 i=0; i < Cursors[iconId].Frames.size(); ++i )
XFreeCursor(Device->display, Cursors[iconId].Frames[i].IconHW);
if ( icon.SpriteId >= 0 )
{
CursorX11 cX11;
cX11.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime;
for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i )
{
irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber;
irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber;
irr::core::rect<s32> rectIcon = icon.SpriteBank->getPositions()[rectId];
Cursor cursor = Device->TextureToCursor(icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot);
cX11.Frames.push_back( CursorFrameX11(cursor) );
}
Cursors[iconId] = cX11;
}
}
irr::core::dimension2di CIrrDeviceLinux::CCursorControl::getSupportedIconSize() const
{
// this returns the closest match that is smaller or same size, so we just pass a value which should be large enough for cursors
unsigned int width, height;
XQueryBestCursor(Device->display, Device->window, 64, 64, &width, &height);
return core::dimension2di(width, height);
}
} // end namespace } // end namespace
#endif // _IRR_COMPILE_WITH_X11_DEVICE_ #endif // _IRR_COMPILE_WITH_X11_DEVICE_
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/cursorfont.h>
#ifdef _IRR_LINUX_X11_VIDMODE_ #ifdef _IRR_LINUX_X11_VIDMODE_
#include <X11/extensions/xf86vmode.h> #include <X11/extensions/xf86vmode.h>
#endif #endif
...@@ -125,6 +126,15 @@ namespace irr ...@@ -125,6 +126,15 @@ namespace irr
return EIDT_X11; return EIDT_X11;
} }
#ifdef _IRR_COMPILE_WITH_X11_
// convert an Irrlicht texture to a X11 cursor
Cursor TextureToCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
Cursor TextureToMonochromeCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
#ifdef _IRR_LINUX_XCURSOR_
Cursor TextureToARGBCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
#endif
#endif
private: private:
//! create the driver //! create the driver
...@@ -145,40 +155,9 @@ namespace irr ...@@ -145,40 +155,9 @@ namespace irr
{ {
public: public:
CCursorControl(CIrrDeviceLinux* dev, bool null) CCursorControl(CIrrDeviceLinux* dev, bool null);
: Device(dev), IsVisible(true), Null(null), UseReferenceRect(false)
{
#ifdef _IRR_COMPILE_WITH_X11_
if (!Null)
{
XGCValues values;
unsigned long valuemask = 0;
XColor fg, bg;
// this code, for making the cursor invisible was sent in by ~CCursorControl();
// Sirshane, thank your very much!
Pixmap invisBitmap = XCreatePixmap(Device->display, Device->window, 32, 32, 1);
Pixmap maskBitmap = XCreatePixmap(Device->display, Device->window, 32, 32, 1);
Colormap screen_colormap = DefaultColormap( Device->display, DefaultScreen( Device->display ) );
XAllocNamedColor( Device->display, screen_colormap, "black", &fg, &fg );
XAllocNamedColor( Device->display, screen_colormap, "white", &bg, &bg );
GC gc = XCreateGC( Device->display, invisBitmap, valuemask, &values );
XSetForeground( Device->display, gc, BlackPixel( Device->display, DefaultScreen( Device->display ) ) );
XFillRectangle( Device->display, invisBitmap, gc, 0, 0, 32, 32 );
XFillRectangle( Device->display, maskBitmap, gc, 0, 0, 32, 32 );
invisCursor = XCreatePixmapCursor( Device->display, invisBitmap, maskBitmap, &fg, &bg, 1, 1 );
XFreeGC(Device->display, gc);
XFreePixmap(Device->display, invisBitmap);
XFreePixmap(Device->display, maskBitmap);
}
#endif
}
//! Changes the visible state of the mouse cursor. //! Changes the visible state of the mouse cursor.
virtual void setVisible(bool visible) virtual void setVisible(bool visible)
...@@ -295,6 +274,27 @@ namespace irr ...@@ -295,6 +274,27 @@ namespace irr
UseReferenceRect = false; UseReferenceRect = false;
} }
//! Sets the active cursor icon
virtual void setActiveIcon(gui::ECURSOR_ICON iconId);
//! Gets the currently active icon
virtual gui::ECURSOR_ICON getActiveIcon() const
{
return ActiveIcon;
}
//! Add a custom sprite as cursor icon.
virtual gui::ECURSOR_ICON addIcon(const gui::SCursorSprite& icon);
//! replace the given cursor icon.
virtual void changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon);
//! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work.
virtual core::dimension2di getSupportedIconSize() const;
#ifdef _IRR_COMPILE_WITH_X11_
void update();
#endif
private: private:
void updateCursorPos() void updateCursorPos()
...@@ -327,10 +327,35 @@ namespace irr ...@@ -327,10 +327,35 @@ namespace irr
core::rect<s32> ReferenceRect; core::rect<s32> ReferenceRect;
#ifdef _IRR_COMPILE_WITH_X11_ #ifdef _IRR_COMPILE_WITH_X11_
Cursor invisCursor; Cursor invisCursor;
struct CursorFrameX11
{
CursorFrameX11() : IconHW(0) {}
CursorFrameX11(Cursor icon) : IconHW(icon) {}
Cursor IconHW; // hardware cursor
};
struct CursorX11
{
CursorX11() {}
explicit CursorX11(Cursor iconHw, u32 frameTime=0) : FrameTime(frameTime)
{
Frames.push_back( CursorFrameX11(iconHw) );
}
core::array<CursorFrameX11> Frames;
u32 FrameTime;
};
core::array<CursorX11> Cursors;
void initCursors();
#endif #endif
bool IsVisible; bool IsVisible;
bool Null; bool Null;
bool UseReferenceRect; bool UseReferenceRect;
gui::ECURSOR_ICON ActiveIcon;
u32 ActiveIconStartTime;
}; };
friend class CCursorControl; friend class CCursorControl;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "irrString.h" #include "irrString.h"
#include "COSOperator.h" #include "COSOperator.h"
#include "dimension2d.h" #include "dimension2d.h"
#include "IGUISpriteBank.h"
#include <winuser.h> #include <winuser.h>
namespace irr namespace irr
...@@ -481,7 +482,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) ...@@ -481,7 +482,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
// because Windows forgot about that in the meantime // because Windows forgot about that in the meantime
dev = getDeviceFromHWnd(hWnd); dev = getDeviceFromHWnd(hWnd);
if (dev) if (dev)
{
dev->getCursorControl()->setActiveIcon( dev->getCursorControl()->getActiveIcon() );
dev->getCursorControl()->setVisible( dev->getCursorControl()->isVisible() ); dev->getCursorControl()->setVisible( dev->getCursorControl()->isVisible() );
}
break; break;
case WM_INPUTLANGCHANGE: case WM_INPUTLANGCHANGE:
...@@ -530,7 +534,7 @@ CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params) ...@@ -530,7 +534,7 @@ CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params)
wcex.cbWndExtra = 0; wcex.cbWndExtra = 0;
wcex.hInstance = hInstance; wcex.hInstance = hInstance;
wcex.hIcon = NULL; wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hCursor = 0; // LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = 0; wcex.lpszMenuName = 0;
wcex.lpszClassName = ClassName; wcex.lpszClassName = ClassName;
...@@ -602,7 +606,7 @@ CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params) ...@@ -602,7 +606,7 @@ CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params)
// create cursor control // create cursor control
Win32CursorControl = new CCursorControl(CreationParams.WindowSize, HWnd, CreationParams.Fullscreen); Win32CursorControl = new CCursorControl(this, CreationParams.WindowSize, HWnd, CreationParams.Fullscreen);
CursorControl = Win32CursorControl; CursorControl = Win32CursorControl;
// initialize doubleclicks with system values // initialize doubleclicks with system values
...@@ -628,7 +632,7 @@ CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params) ...@@ -628,7 +632,7 @@ CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params)
// get the codepage used for keyboard input // get the codepage used for keyboard input
KEYBOARD_INPUT_HKL = GetKeyboardLayout(0); KEYBOARD_INPUT_HKL = GetKeyboardLayout(0);
KEYBOARD_INPUT_CODEPAGE = LocaleIdToCodepage( LOWORD(KEYBOARD_INPUT_HKL) ); KEYBOARD_INPUT_CODEPAGE = LocaleIdToCodepage( LOWORD(KEYBOARD_INPUT_HKL) );
} }
...@@ -746,6 +750,8 @@ bool CIrrDeviceWin32::run() ...@@ -746,6 +750,8 @@ bool CIrrDeviceWin32::run()
{ {
os::Timer::tick(); os::Timer::tick();
static_cast<CCursorControl*>(CursorControl)->update();
MSG msg; MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
...@@ -1542,6 +1548,217 @@ void CIrrDeviceWin32::ReportLastWinApiError() ...@@ -1542,6 +1548,217 @@ void CIrrDeviceWin32::ReportLastWinApiError()
} }
} }
// Convert an Irrlicht texture to a Windows cursor
// Based on http://www.codeguru.com/cpp/w-p/win32/cursors/article.php/c4529/
HCURSOR CIrrDeviceWin32::TextureToCursor(HWND hwnd, irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot)
{
//
// create the bitmaps needed for cursors from the texture
HDC dc = GetDC(hwnd);
HDC andDc = CreateCompatibleDC(dc);
HDC xorDc = CreateCompatibleDC(dc);
HBITMAP andBitmap = CreateCompatibleBitmap(dc, sourceRect.getWidth(), sourceRect.getHeight());
HBITMAP xorBitmap = CreateCompatibleBitmap(dc, sourceRect.getWidth(), sourceRect.getHeight());
HBITMAP oldAndBitmap = (HBITMAP)SelectObject(andDc, andBitmap);
HBITMAP oldXorBitmap = (HBITMAP)SelectObject(xorDc, xorBitmap);
video::ECOLOR_FORMAT format = tex->getColorFormat();
u32 bytesPerPixel = video::IImage::getBitsPerPixelFromFormat(format) / 8;
u32 bytesLeftGap = sourceRect.UpperLeftCorner.X * bytesPerPixel;
u32 bytesRightGap = tex->getPitch() - sourceRect.LowerRightCorner.X * bytesPerPixel;
const u8* data = (const u8*)tex->lock(true, 0);
data += sourceRect.UpperLeftCorner.Y*tex->getPitch();
for ( s32 y = 0; y < sourceRect.getHeight(); ++y )
{
data += bytesLeftGap;
for ( s32 x = 0; x < sourceRect.getWidth(); ++x )
{
video::SColor pixelCol;
pixelCol.setData((const void*)data, format);
data += bytesPerPixel;
if ( pixelCol.getAlpha() == 0 ) // transparent
{
SetPixel(andDc, x, y, RGB(255,255,255));
SetPixel(xorDc, x, y, RGB(0,0,0));
}
else // color
{
SetPixel(andDc, x, y, RGB(0,0,0));
SetPixel(xorDc, x, y, RGB(pixelCol.getRed(), pixelCol.getGreen(), pixelCol.getBlue()));
}
}
data += bytesRightGap;
}
tex->unlock();
SelectObject(andDc, oldAndBitmap);
SelectObject(xorDc, oldXorBitmap);
DeleteDC(xorDc);
DeleteDC(andDc);
ReleaseDC(hwnd, dc);
//
// create the cursor
ICONINFO iconinfo;
iconinfo.fIcon = false; // type is cursor not icon
iconinfo.xHotspot = hotspot.X;
iconinfo.yHotspot = hotspot.Y;
iconinfo.hbmMask = andBitmap;
iconinfo.hbmColor = xorBitmap;
HCURSOR cursor = CreateIconIndirect(&iconinfo);
DeleteObject(andBitmap);
DeleteObject(xorBitmap);
return cursor;
}
CIrrDeviceWin32::CCursorControl::CCursorControl(CIrrDeviceWin32* device, const core::dimension2d<u32>& wsize, HWND hwnd, bool fullscreen)
: Device(device), WindowSize(wsize), InvWindowSize(0.0f, 0.0f),
HWnd(hwnd), BorderX(0), BorderY(0),
UseReferenceRect(false), IsVisible(true)
, ActiveIcon(gui::ECI_NORMAL), ActiveIconStartTime(0)
{
if (WindowSize.Width!=0)
InvWindowSize.Width = 1.0f / WindowSize.Width;
if (WindowSize.Height!=0)
InvWindowSize.Height = 1.0f / WindowSize.Height;
updateBorderSize(fullscreen, false);
initCursors();
}
CIrrDeviceWin32::CCursorControl::~CCursorControl()
{
for ( u32 i=0; i < Cursors.size(); ++i )
{
for ( u32 f=0; f < Cursors[i].Frames.size(); ++f )
{
DestroyCursor(Cursors[i].Frames[f].IconHW);
}
}
}
void CIrrDeviceWin32::CCursorControl::initCursors()
{
Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_ARROW)) );
Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_CROSS)) );
Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_HAND)) );
Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_HELP)) );
Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_IBEAM)) );
Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_NO)) );
Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_WAIT)) );
Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZEALL)) );
Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZENESW)) );
Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZENWSE)) );
Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZENS)) );
Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZEWE)) );
Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_UPARROW)) );
}
void CIrrDeviceWin32::CCursorControl::update()
{
if ( !Cursors[ActiveIcon].Frames.empty() && Cursors[ActiveIcon].FrameTime )
{
// update animated cursors. This could also be done by X11 in case someone wants to figure that out (this way was just easier to implement)
u32 now = Device->getTimer()->getRealTime();
u32 frame = ((now - ActiveIconStartTime) / Cursors[ActiveIcon].FrameTime) % Cursors[ActiveIcon].Frames.size();
SetCursor( Cursors[ActiveIcon].Frames[frame].IconHW );
}
}
//! Sets the active cursor icon
void CIrrDeviceWin32::CCursorControl::setActiveIcon(gui::ECURSOR_ICON iconId)
{
if ( iconId >= (s32)Cursors.size() )
return;
ActiveIcon = iconId;
ActiveIconStartTime = Device->getTimer()->getRealTime();
if ( Cursors[ActiveIcon].Frames.size() )
SetCursor( Cursors[ActiveIcon].Frames[0].IconHW );
}
//! Add a custom sprite as cursor icon.
gui::ECURSOR_ICON CIrrDeviceWin32::CCursorControl::addIcon(const gui::SCursorSprite& icon)
{
if ( icon.SpriteId >= 0 )
{
CursorW32 cW32;
cW32.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime;
for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i )
{
irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber;
irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber;
irr::core::rect<s32> rectIcon = icon.SpriteBank->getPositions()[rectId];
HCURSOR hc = Device->TextureToCursor(HWnd, icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot);
cW32.Frames.push_back( CursorFrameW32(hc) );
}
Cursors.push_back( cW32 );
return (gui::ECURSOR_ICON)(Cursors.size() - 1);
}
return gui::ECI_NORMAL;
}
//! replace the given cursor icon.
void CIrrDeviceWin32::CCursorControl::changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon)
{
if ( iconId >= (s32)Cursors.size() )
return;
for ( u32 i=0; i < Cursors[iconId].Frames.size(); ++i )
DestroyCursor(Cursors[iconId].Frames[i].IconHW);
if ( icon.SpriteId >= 0 )
{
CursorW32 cW32;
cW32.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime;
for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i )
{
irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber;
irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber;
irr::core::rect<s32> rectIcon = icon.SpriteBank->getPositions()[rectId];
HCURSOR hc = Device->TextureToCursor(HWnd, icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot);
cW32.Frames.push_back( CursorFrameW32(hc) );
}
Cursors[iconId] = cW32;
}
}
//! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work.
core::dimension2di CIrrDeviceWin32::CCursorControl::getSupportedIconSize() const
{
core::dimension2di result;
result.Width = GetSystemMetrics(SM_CXCURSOR);
result.Height = GetSystemMetrics(SM_CYCURSOR);
return result;
}
} // end namespace } // end namespace
#endif // _IRR_COMPILE_WITH_WINDOWS_DEVICE_ #endif // _IRR_COMPILE_WITH_WINDOWS_DEVICE_
...@@ -111,24 +111,16 @@ namespace irr ...@@ -111,24 +111,16 @@ namespace irr
//! Does call GetLastError and on errors formats the errortext and displays it in a messagebox. //! Does call GetLastError and on errors formats the errortext and displays it in a messagebox.
static void ReportLastWinApiError(); static void ReportLastWinApiError();
// convert an Irrlicht texture to a windows cursor
HCURSOR TextureToCursor(HWND hwnd, irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
//! Implementation of the win32 cursor control //! Implementation of the win32 cursor control
class CCursorControl : public gui::ICursorControl class CCursorControl : public gui::ICursorControl
{ {
public: public:
CCursorControl(const core::dimension2d<u32>& wsize, HWND hwnd, bool fullscreen) CCursorControl(CIrrDeviceWin32* device, const core::dimension2d<u32>& wsize, HWND hwnd, bool fullscreen);
: WindowSize(wsize), InvWindowSize(0.0f, 0.0f), ~CCursorControl();
HWnd(hwnd), BorderX(0), BorderY(0),
UseReferenceRect(false), IsVisible(true)
{
if (WindowSize.Width!=0)
InvWindowSize.Width = 1.0f / WindowSize.Width;
if (WindowSize.Height!=0)
InvWindowSize.Height = 1.0f / WindowSize.Height;
updateBorderSize(fullscreen, false);
}
//! Changes the visible state of the mouse cursor. //! Changes the visible state of the mouse cursor.
virtual void setVisible(bool visible) virtual void setVisible(bool visible)
...@@ -280,6 +272,27 @@ namespace irr ...@@ -280,6 +272,27 @@ namespace irr
} }
} }
//! Sets the active cursor icon
virtual void setActiveIcon(gui::ECURSOR_ICON iconId);
//! Gets the currently active icon
virtual gui::ECURSOR_ICON getActiveIcon() const
{
return ActiveIcon;
}
//! Add a custom sprite as cursor icon.
virtual gui::ECURSOR_ICON addIcon(const gui::SCursorSprite& icon);
//! replace the given cursor icon.
virtual void changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon);
//! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work.
virtual core::dimension2di getSupportedIconSize() const;
void update();
private: private:
//! Updates the internal cursor position //! Updates the internal cursor position
...@@ -316,6 +329,7 @@ namespace irr ...@@ -316,6 +329,7 @@ namespace irr
} }
} }
CIrrDeviceWin32* Device;
core::position2d<s32> CursorPos; core::position2d<s32> CursorPos;
core::dimension2d<u32> WindowSize; core::dimension2d<u32> WindowSize;
core::dimension2d<f32> InvWindowSize; core::dimension2d<f32> InvWindowSize;
...@@ -325,6 +339,32 @@ namespace irr ...@@ -325,6 +339,32 @@ namespace irr
core::rect<s32> ReferenceRect; core::rect<s32> ReferenceRect;
bool UseReferenceRect; bool UseReferenceRect;
bool IsVisible; bool IsVisible;
struct CursorFrameW32
{
CursorFrameW32() : IconHW(0) {}
CursorFrameW32(HCURSOR icon) : IconHW(icon) {}
HCURSOR IconHW; // hardware cursor
};
struct CursorW32
{
CursorW32() {}
explicit CursorW32(HCURSOR iconHw, u32 frameTime=0) : FrameTime(frameTime)
{
Frames.push_back( CursorFrameW32(iconHw) );
}
core::array<CursorFrameW32> Frames;
u32 FrameTime;
};
core::array<CursorW32> Cursors;
gui::ECURSOR_ICON ActiveIcon;
u32 ActiveIconStartTime;
void initCursors();
}; };
//! returns the win32 cursor control //! returns the win32 cursor control
......
<?xml version="1.0" encoding="Windows-1252"?> <?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="9.00" Version="9,00"
Name="Irrlicht" Name="Irrlicht"
ProjectGUID="{E08E042A-6C45-411B-92BE-3CC31331019F}" ProjectGUID="{E08E042A-6C45-411B-92BE-3CC31331019F}"
RootNamespace="Irrlicht" RootNamespace="Irrlicht"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment