So I followed this (simple) instructions and got two pointers/cursors on my desktop
http://ao2.it/en/blog/2010/01/19/poor-mans-multi-touch-using-multiple-mice-xorg
I also checked demo-painting program and it worked.
Then I started modify
src/platform/StdXWindow.cpp
src/platform/StdXApp.cpp
(something like this: http://www.clearchain.com/blog/posts/xinput-1-xinput-2-conversion-guide )
What I got so far:
*Game is printing different deviceID when pressing mouse button on start menu.
What it is not working:
*Moving cursor on start menu.
HandleMessage (XEvent &e) is defined so many places, so I do not know where is the start menu.
My questions:
a) which file is moving cursor on startmenu?
(so I can test my proof-of-concept)
b) Is there any interested in about MPX?
(Because messagehandling is splitted several files, this is not trivial task, and I'm not doing it if nobody cares)
c) Are other (non-X11) systems handling multi mouse in any way?
(=Can core-engine support multi mouse even only one 'frontend' is using it)
Of course it was never tested whether stuff like dragging/etc. works without the mice conflicting each other, because the number is always passed as zero at the moment.
Also, all the stuff "above" player control (C4GUI, C4MouseControl, C4Viewport) is written for single mice only.
Good luck, though, I don't think that any of the devs ever thought about the fact that somebody could ever want to have multiple mice(especially since previous clonk games were mainly keyboard controlled)
However! "Good luck" and "Yaaay!" are still relevant :p
I have played with code and added hundred (not really) printf and Log to understand how flow of events works. I think this is doable.
a) How I should implement it?
X11 is handling events like this:
switch (event.type)
case KeyPress:
Game.DoKeyboardInput
And XInput2 (MPX) is handling it:
switch(event.xcookie.evtype)
case XI_KeyPress:
Game.DoKeyboardInput
So should it be
#ifdef MPX
switch(event.xcookie.evtype)
#else
switch (event.type)
#endif
#ifdef MPX
case KeyPress:
#else
case XI_KeyPress:
#endif
Game.DoKeyboardInput
Now they are guaranteed to be synced.
Another way is something like:
static void _internal_keypress(something) {
Game.DoKeyboardInput
}
#ifdef MPX
switch(event.xcookie.evtype)
case XI_KeyPress:
_internal_keypress(something);
#else
switch (event.type)
case KeyPress:
_internal_keypress(something);
#endif
b) Should it be compile or runtime decision?
It can be easily checked with
/* Check for XI2 support */
int major = 2, minor = 0;
if (XIQueryVersion(display, &major, &minor) == BadRequest) {
printf("XI2 not available. Server supports %d.%d\n", major, minor);
}
c) What is preferred way to send patches?
I have used to use git. I happily make smallest (=atomic) possible commits (I have never used hg).
> switch (event.type)
> switch(event.xcookie.evtype)
It's more complicated than that. xcookie is part of the "GenericEvent" stuff, which as far as I know is one kind of event.type.
I'm not sure whether we can require XI2 yet. If we can't, we need to keep the core event stuff enabled unconditionally, and XI2 optional at runtime. Otherwise we can just replace it. If we can not even rely on the library being available, we also need to make the XI2 code optional at compile time.
I'm using a hg-git import of the openclonk mercurial repos. If you want to keep using git, you can do that, too, our repositories will be compatible. Otherwise, plain text forum or bugtracker attachments or public mercurial repositories will all do.
http://bugs.openclonk.org/view.php?id=543
There are some fuzzy with naming:
event VS message
MPX VS Xi2
General design idea:
configure time: check Xi -library
compile time: #ifdef USE_MPX
run time: if X supports MPX
Missing/TODO (=current status)
*configure fails if Xi is missing (shoud be conditional/optional, but I do not know how to do it)
Status:
SdtXWindow.cpp:
*Check MPX support
*adds event listeners for MPX-events.
StdXApp.cpp:
*Handle MPXMessages and pass them to C4FullScreen.cpp (like regular events)
C4FullScreen.cpp
*Reacts to MPX-events (like regular events)
*Prints which pointer (ID) is used, BUT doesn't send it to forward!
Start game with one/two/three mice: There are only one cursor.
Clicking and moving will tell what mouse is used.
Moving cursor works. Single click (left/right) works. Double clicking works.
Moving Clonk with keyboard works.
Writing on chat-messages or changing team name (etc) works only with ASCII. Also shift+ctrl+alt are not working with dialogs.
(because there was too many Xutf8LookupString/XLookupString... I do not yet know how to use them with MPX-events)
*I have tested code without #define USE_MPX
(config.h:177)
*I have tested code with #define USE_MPX + faking that X-server doesn't have support for it.
(StdXWindow.cpp:194)
-> Then regular X-events are used.
Some questions:
1)
StdXApp.cpp has several
CStdWindow * pWindow = Priv->GetWindow(event.xany.window);
and pWindow
Are some of these 'global' (from StdWindow.h) and some local?
Now MPX-event handler uses only local-variable CStdWindow * pWindow = Priv->GetWindow(evData->event);
2)
Are copy-pasting-events used in game: SelectionClear, SelectionRequest, SelectionNotify?
> *configure fails if Xi is missing (shoud be conditional/optional, but I do not know how to do it)
instead of unconditionally calling AC_DEFINE, only do it if libXi is found. See the autoconf manual on AC_CHECK_LIB for where to place that.
You should be able to just include the MPX events as a case in the normal switch(e.type). XEvent is an union, e.xcookie.type is the same as e.type.
Do we really need to use XI for normal keyboard text input and focus stuff? Each player having their own keyboard and being able to chat sounds like a fringe case to me.
>StdXApp.cpp has several
> CStdWindow * pWindow = Priv->GetWindow(event.xany.window);
> and pWindow
> Are some of these 'global' (from StdWindow.h) and some local?
See src/platform/StdXPrivate.h and the functions it declares.
> Are copy-pasting-events used in game: SelectionClear, SelectionRequest, SelectionNotify?
Our text input boxes support copy&paste, yes.
>instead of unconditionally calling AC_DEFINE, only do it if libXi is found. See the autoconf manual on AC_CHECK_LIB for where to place that.
Thanks.
>You should be able to just include the MPX events as a case in the normal switch(e.type). XEvent is an union, e.xcookie.type is the same as e.type.
I do not (yet) know how to do that.
>Do we really need to use XI for normal keyboard text input and focus stuff? Each player having their own keyboard and being able to chat sounds like a fringe case to me.
How many players on the same computer are planned to work? If there are (let say) six people wit six mice, they need more than one keyboard. And maybe more than one people wants use 'wasd'. But maybe chatting and tuning team names can be handled with single keyboard.
>>StdXApp.cpp has several
>> CStdWindow * pWindow = Priv->GetWindow(event.xany.window);
>> and pWindow
I'm asking are there really same named local variable than class-variable ('global' as I earlier called them)?
Next question:
How to do something useful with this?
How to tell Core which pointer sent event?
> How many players on the same computer are planned to work?
More than two would not make much sense, considering space in the desk for mice. If you want to play with more than 2 players on one PC, I think getting gamepads for that might be more fun.
> I do not (yet) know how to do that.
Instead of e.xcookie.type==foo, do switch(e.type) { [...] case foo:, just like the other events do.
> How many players on the same computer are planned to work? If there are (let say) six people wit six mice, they need more than one keyboard. And maybe more than one people wants use 'wasd'. But maybe chatting and tuning team names can be handled with single keyboard.
Let's concentrate on mice, and think about this later.
> I'm asking are there really same named local variable than class-variable ('global' as I earlier called them)?
I think so. (I haven't got the source at the moment, I can make sure later.)
>> *configure fails if Xi is missing (shoud be conditional/optional, but I do not know how to do it)
>instead of unconditionally calling AC_DEFINE, only do it if libXi is found. See the autoconf manual on AC_CHECK_LIB for where to place that.
I checked it again. It is using AC_CHECK_LIB, so configure is not failing if Xi is not found.
AC_DEFINE(USE_MPX, 1, [Define to 1 if the Multi Pointer X is used])
AC_CHECK_LIB(Xi, XListInputDevices, [CLONK_LIBS="-lXi $CLONK_LIBS"],
[AC_MSG_ERROR([Xi-extension not found.])], [$X_LIBS])
Problem is, USE_MPX is defined even Xi is not found. Is there way to handle this?
Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill