2009年02月20日

仮想入力への道その2 SDLにxlibを加えて

SDL_WarpMouseを使えばSDL単独でも他のアプリで使用中のマウスを移動することができるが
クリックなどには使えずいまひとつだ。
そこで一部のユーティリティで使っていた/X11/extensions/XTest.hで宣言されている関数を使うことにした。
とりあえずwindowなしでジョイスティックからマウスやキーボードの信号を送ることができた。
パフォーマンスも悪くは無いのでSDLがやや無駄な感じだが仮想マウスや仮想キーボードの下地ができたわけだ。
関数は/X11/extensions/XTest.hに宣言されているが
今回はプログラム中に

#include <X11/Xlib.h>


だけを記述した。

ライブラリーも含めてコンパイルはjoytest014.cというファイルに対して

gcc -Wall -pipe joytest014.c -o joytest014 \
-I/usr/local/include -I/usr/local/include/SDL \
-L/usr/local/lib -Wl,-rpath,/usr/local/lib -lSDL -lXtst



で行った。-lX11なり-lxlibでなくて-lXtstなのがみそ。
XtstかSDLのどちらかがxlibの分も含んでいるということなのだろう。

使う関数は
キーコードをTrueとFalseで指定する関数

extern int XTestFakeKeyEvent(
Display* /* dpy */,
unsigned int /* keycode */,
Bool /* is_press */,
unsigned long /* delay */
);


マウスボタンのオンオフを指定する関数、これはボタンは見た目順で右クリックはButton3になる。

extern int XTestFakeButtonEvent(
Display* /* dpy */,
unsigned int /* button */,
Bool /* is_press */,
unsigned long /* delay */
);


マウスの位置指定関数

extern int XTestFakeMotionEvent(
Display* /* dpy */,
int /* screen */,
int /* x */,
int /* y */,
unsigned long /* delay */
);


マウスの相対移動指定関数
いずれもdelayにはCurrentTimeとどこぞで定義済みの変数を代入すると即実行する様だ。


extern int XTestFakeRelativeMotionEvent(
Display* /* dpy */,
int /* x */,
int /* y */,
unsigned long /* delay */
);

の4つだがこの他に
Xlib.hの


extern Display *XOpenDisplay(
_Xconst char* /* display_name */
);



extern void XFlush(
Display* /* display */,
);

も必要だった。

従って変数として

Display *dpy;
char *dname = NULL;

を追加した。

XOpenDisplayはイベントループの前にいっぺん使用すればよいようだ。
ここで取得した変数「dpy」を使いまわした。
XTestFakeMotionEventのscreenは-1で良い様だ。

「XTestFake」と若干うさんくさい名が付いているが
windowを取得せずに無差別送信できるので今回の目的では理想的な関数だ。
変更の反映には

XFlush(dpy);


が必要で仮想キーや仮想ボタンのオンは累積されるので必ずオフにしないといけないらしい。
この辺手抜くとアプリが終了した後どどどとキーコードが並んだりする。

XTestFakeRelativeMotionEventは相対移動できるので
アナログ軸のないゲームパッドでもマウスをコントロールできるのが良いと感じた。

またこの関数群は別にジョイステッィクでなくてもいいわけで
Windowの位置を記録しておいてショートカットで移動させるような用法にも使える。

今回はSDL側はイベントでパラメータを変数に収納させる形をとった。
つまり「SDL_JoystickGetAxis」等を使わなかった。
SDLのソースをみたら単にエラーチェックをして構造体を読んでいるだけだったからだ。


case SDL_JOYAXISMOTION:
if (event.jaxis.axis){y=event.jaxis.value;
} else {x=event.jaxis.value;}
break;
case SDL_JOYHATMOTION:
h=event.jhat.value;
break;


補正の類をここですると無駄に計算回数が増えるのでやめた方がいいだろう。
取り出し時に補正する方向で良い。
hatスイッチに関しては実際デジタルジョイステッィク的な意味合いが強いので
デジタルジョイスティックをhatの形にするか
hatをaxisにするか
あるいは違う形にするかおいおい考えてみたい。

SDLの入力に付いてはホイールについての言及が少なかったのでどうかと思ったのだが
SDL_BUTTON_WHEELUP/DOWNがあるのでDirectInputのように使えば良いのだろう。

ジョイスティックをバーチャルキー化する場合にせよdaemonでやる場合は
任意のサインで終了できるようにする必要がある。
今回は最終的にラストキーをシフトキー的にして各種実験を行いラスト-1と同時押しすると終了するようにした。

プログラム本文に書いてビルドするというのもFreeBSDの場合はありの様な気がするが
まぁコンフィグファイルで設定というのが良さそうだが
ここまでやると何もSDLを使うことも無い気がする。

それでも一連のコーディングと探索によるリサーチから
アプリのベースとしてxlibを使うんじゃなかったらSDLがベターだと感じた。
これはglib2,glut,plib,wxGTK等と比較してのはなしだ。
ラベル:Joystick SDL xlib
posted by Xo_ox at 23:05| Comment(0) | FreeBSDアプリ | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。