Not logged inOpenClonk Forum
Up Topic Development / Developer's Corner / Multi pointer X (MPX) for multiplaying on same computer
- - By aapo [fi] Date 2010-12-11 23:35
I tried to search but didn't found any real discussion about MPX.

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)
Parent - By Günther [de] Date 2010-12-12 01:18
Yes, there's interest. The various HandleMessage functions correspond to the various windows Clonk uses. All but C4FullScreen and StdWindow are used by the editor, so if you want to start with the normal game first, those two are relevant.
Reply
Parent - By Sven2 [de] Date 2010-12-12 10:36
Multi-mice support was kinda "planned" already. The input functions in C4PlayerControl take a mouse number parameter, which corresponds to mouse indices in control assignment sets (e.g. Mouse[Number]LeftDown).

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.
Parent - - By Asmageddon [pl] Date 2010-12-12 13:05
Yay! Somebody is working on multi-mice support!
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)
Reply
Parent - - By Mortimer [de] Date 2010-12-12 13:11
Writing that directly below Sven2's answer where he pointed out that in fact some parts of the engine were already written with multi-mice support in mind is kind of funny :D
Reply
Parent - By Asmageddon [pl] Date 2010-12-13 17:48
Well, I very often do many things at once, and I could have had this tab opened for few hours, and clicked reply then, without even noticing that so much time passed.
However! "Good luck" and "Yaaay!" are still relevant :p
Reply
Parent - By Mortimer [de] Date 2010-12-13 19:01
There is also http://icculus.org/manymouse/ but I don't know how well that works.
Reply
- - By aapo [fi] Date 2010-12-13 17:31
Thanks you for your answers.

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).
Parent - By Günther [de] Date 2010-12-13 19:30

> 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.
Reply
- - By aapo [fi] Date 2010-12-14 16:51
Ok. I attached patch to bug tracker for previews, comments and corrections. Currently it will not add any value for end-users (instead it introduces couple of misfeatures).
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?
Parent - - By Günther [de] Date 2010-12-14 21:32

> *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.
Reply
Parent - - By aapo [fi] Date 2010-12-15 16:43

>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?
Parent - By Newton [de] Date 2010-12-15 16:47

> 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.
Parent - By Günther [de] Date 2010-12-15 19:57

> 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.)
Reply
Parent - By aapo [fi] Date 2010-12-23 14:11

>> *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?
Up Topic Development / Developer's Corner / Multi pointer X (MPX) for multiplaying on same computer

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill