ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

X Window SystemコミュのX Window Programming

  • mixiチェック
  • このエントリーをはてなブックマークに追加

興味本位で、X-Windowプログラミングを
行っています。

・X-Windowプログラミングでは
キーボード・マウス以外の
イベントを読み取ることは
できるのでしょうか??
(たとえば、ジョイスティックなど)

XSelectInputで選択可能なものには存在しないようで...


だれか詳しいかたがいらっしゃいましたら、
ご教授いただけたら幸いです。

コメント(37)

私は全然詳しくないのですが,面白そうなので検索してみたら(古い情報ではありますが)こんなの見つけました.

http://ayapin.film.s.dendai.ac.jp/~matuda/TeX/PDF/22nd.pdf

よくよく考えれば当たり前の結論ですが,要は「OS側で適切にドライバを設定して,X側で適切にドライバからXへ入力が渡されるように設定をしてやれば使えます」ということみたいですね.

#最近のXだと多少は便利になってるかもしれませんが,基本は似たようなものじゃないかと思います.
>Wazbonesさん

さっそくの返信ありがとうございます。
なるほど、たしかにpdfファイルをよむと、
そのようなことが書いてありますねf^^;

「ドライバからXへ入力が渡されるように設定をする」

というものが、当り前のようですが四苦八苦していて...
実は、powermate(http//www.focal.co.jp/product/griffin/powermate/index.html)
というデバイスを用いて、遊んでたのです...
ドライバはきちんとあって、printf関数などで
確認すると、ターミナル上では値を読み取ることはできてるのですが、
Xに反映されず...f^^;

もうすこし、試行錯誤してみます。
ありがとうございました。
とりあえずX標準の入力デバイスでないものを扱うには、
X Input Extension を使います。

X Input Extension は X11R6 以降の標準的な拡張なので、
現在普通に動いている大抵のXサーバで使えると思います。

使いたいデバイスについて Input Extension に対応する
ためのコードが既に書かれていれば、アプリケーション
からは X Input Extension Library を使ってデバイスの
初期化やイベントの取得などができるようになってます。

たとえば XFree86 だとジョイスティック用のドライバは
あったと思うので、そこも含めてビルドできて動いている
のであれば、対応しているジョイスティックなら使えると
思います。
XtならXtAppAddInput()でファイルに返歌があったことを検出できるので、デバイスファイルをオープンして監視するという芸当ができるかもしれません。
Gtk2にもgtk_add_input()だったか似たような関数があったはず。
「ドライバからXへ」というところはXのドライバモジュールを作らないといけないような気がするので、結構面倒な気がします。
PowerMateの場合,Xから見ると(マウスやジョイスティックと違って)1次元のアナログデータを入力するという特殊なデバイスなので,X経由で使うよりも,直接ドライバを読んで使うのが楽なんじゃないかと思いますが…

もし,PowerMateで何か既存のXのアプリを操作したいのであれば,PowerMateのドライバから読み込んで,必要に応じてイベントを発行するようなプログラムを自前で書くのが良いんじゃないでしょうか?
>えたんだーるさん

返信ありがとうございます
(^^)
X Input Extension Libraryですか...
調べてみます。

>びいさん
やりたいことはまさに

「デバイスファイルをオープンして監視する」

ということ...のハズなので、
Xtなどを調べてみたいと思います。

>Wazbonesさん

とくにアプリなどを操作する...というわけではないんですよね...
(powermateの回転量に応じて、線の描画など
できないものか...とf^^;
イメージとしては Etch-A-Sketch
(http://www.geocities.co.jp/MusicStar-Live/1292/etch_a_sketch.htm))
のようなものを作成しようとしてまして...

「直接ドライバを読んで使う」と、
「ファイルをオープンして監視する」がゴチャゴチャになってるようで
す。



僕自身のCPUがおっついてないので、
スゴくおかしな回答をしてるかもしれません。
御了承ください(皆様)。
(いろいろ試行錯誤しながら、理解しようと思います。)

返信ありがとうございます。
連続レス失礼します。

Input Extensionに対応するためのコード...
というのがよく理解できてないようで...

#include<X11/Xutil.h>
#include <X11/extensions/XInput.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/soundcard.h>
#include <linux/input.h>

//powermateがマウントされてるとこ
#define RIGHT_POWER_MATE "/dev/input/event0"
#define LEFT_POWER_MATE "/dev/input/event1"
#define BUFFER_SIZE 32


int redraw(Display *d,Window w, GC gc);

int main()
{
int rpower_mate,lpower_mate;
unsigned int output_data;
int parm,status,bits,sampling,r,l;
int right_abs_pos,left_abs_pos;
long s;
struct input_event ibuffer[BUFFER_SIZE];
XDeviceInfoPtr list, slist;

FILE *fp;
Display *d;
Window w;
int black, white;
GC gc;
XEvent e;
d = XOpenDisplay(NULL);
black = BlackPixel(d,0);
white = WhitePixel(d,0);
w = XCreateSimpleWindow(d,RootWindow(d,0), 100,100,320,320,2,black,white);

//線を描くためにGCを設ける。
gc = XCreateGC(d,w,0,0);
//取り込むイベントの指定
XSelectInput(d,w,ExposureMask | ButtonPressMask);
//マップするとExposeイベントが発生する。
XMapWindow(d,w);

rpower_mate = open( RIGHT_POWER_MATE, O_RDWR|O_NONBLOCK);
lpower_mate = open( LEFT_POWER_MATE, O_RDWR|O_NONBLOCK);
//この部分をどー読ませるかが問題...

while(1)
{
//イベントの取り込み
XNextEvent(d,&e);
if(e.type == Expose)
redraw(d,w,gc);
if(e.type == ButtonPress)
break;
}

XCloseDisplay(d);
}

int redraw(Display *d,Window w,GC gc)
{
XDrawArc(d,w,gc,0,0,319,319,0,300*64);
}


...ここから
while(1)ループの中で
上手く「rpower_mate」の値を
よんでXに反映できたらよいハズなのですが...

ファイルをオープンして監視するのが間違っているのでしょうか...

誰か、気づいた点がありましたら、
ご教授いただけたらと思います。

(ソースまで貼り付けて申し訳ありません)
まず、そのdeviceが X Input Extentionに対応しているかを確かめる必要があるのでは (Xiについて詳しいわけではないですが)。えたんだーるさんのいう「Input Extension に対応する
ためのコードが既に書かれて」いるかが問題です。

Xiをつかうと以下のような流れになります:

mouse   \
keyboard  -- X server --(X proto + Xi) -- X client
new device /

この new deviceと X serverを繋ぐ線がすでにあるのか、というのが問題になります。(もちろん X clientが Xiを handleする必要もあります)

Xiをつかわないと:

mouse  \
keyboard ―X server―(X protocol)―X client
newdevice ―――――――――――/

という流れになって、X clientが対応するだけでok。
こちらがdeviceを直接開いてやる、ということでしょう。

どちらがいいかはよくわかりませんが、Xiをちゃんと知らない私から見ると、後者のほうが楽そうな気がします。
あ、よくみるとすでに後者の deviceを直接開く方法をやってるようですね。
その場合、deviceから得られたデータは Xのまったくあずかり知らぬものとなります。applicationが煮ようが焼こうが好きにして構いません(「Xに反映させる」必要はない)。

で、Xlibを直接使う場合、(提示のコードのように) XNextEventをつかうと blockしてしまい deviceのデータを読む暇がなくなります。XPeekEvent を使い pollingしながら rpower_mateの値を読むなどするのが簡単でしょう。

pollingは CPUを占有するのがいやだ、ってときは..えーと、どうやるんだっけ... Xtや GTKを使う場合はびいさんのいう方法があるんですけど..
こんにちは。

pollingが嫌な場合は、select(2)/poll(2)でデータ到着をチェックすることになるかと思います。

ちょっと外れるかもしれませんが、XPeekEvent()で届いているイベントがある間はXNextEvent()で処理を済ませた上で、あるウィンドウの状態を調べるといったことをしたのですが、どうも見た目と調べた状態がずれてしまいました。(単にXNextEvent()で待たないのは、まさに他にデータ到着を別途select(2)で調べるといった事情があります。)

全部処理したつもりだったのですが、まだXPeekEvent()で確認できない、未着のイベントがあったようです。僅かな時間(1ms程度)をusleep(3)で待って再度届いていないか調べる、といったことを数回行うといった場当たりな対処で何とかしました。

これまた、未着のイベントが届ききるまでの時間が動作する環境(CPU速度やOSの違い?)で違ったりもしました。;-(

Xのプログラミングのプロフェッショナルではないので、ほんとは何かよい方法があったのかもしれません。
O_ASYNCと組み合わせる荒業もありそうですが、
Xに対しても同時にselectしてしまうのが無難な気がします。
その select(2) に渡す descriptorはどうやってとるんだっけ? ってとこで悩んでたんでした >>tacaさん
ぐぐってみると以下のものが近いようです:
http://homepage3.nifty.com/rio_i/lab/xlib/101tips.htm
これは networkから読む例だけど。
はい、もちろんその手のちゃんとselect(2)とかもしてます。

だけどタイミング的な問題で、しばらく待たないとイベントが届いていないこともあるようです。
自分でselectしているときはXNextEventなどでブロックしてはダメです
UNIX系(特にBSD由来)のプログラムインタフェースでは、
select でブロックして入力待ちができます。
(Linux でもそうですよね?)

> その select(2) に渡す descriptorはどうやってとるんだっけ? ってとこで悩んでたんでした

それは、batayan さんのプログラムの例だと open() で
取って FD_SET します。

問題はこれをアプリケーション側でやるか X Input Extension
に対応させるかで、これは8番のコメントで ゛゛゛゛゛゛さん
が説明されたとおりです。

アプリケーションでやると、入力待ちが通常のイベントループ
の作法から外れるのでコードを書くのが面倒になります。

一方、XI用の入力ドライバを書くのは面倒ですが、入力は
通常のイベントループで待てますし、アプリケーションを
書く場合のプログラミング言語の選択肢が広がります。


で、XI(X Input Extension) を使う場合には、以下のような
アクションを持つ DeviceControlProc を書くことが必須です。

DEVICE_INIT
DEVICE_ON
DEVICE_OFF
DEVICE_CLOSE

このあたりのアクションでデバイスファイルの open/close
や、ioctl などによるパラメータ設定などを行います。

あとは入力をXのイベントとして扱うために、以下を
書く必要があります。

DeviceGetEvents
DeviceEnqueueProc

標準的な入力イベント(KEY, BUTTON, VALUATOR)は、ここ
で扱います。

ここで select で入力を待ったり、read で入力を読んだり
して、イベントキューに突っ込みます。

power mate はボタン入力と座標入力だけができれば
良さそうなので、標準的な入力イベントで対応できる
と思いますが、さらにデバイス独自のコードが必要な
場合には、デバイス依存の拡張イベントなどを定義し、
それのハンドリング用のコードを書く必要があります。

ここまで準備ができると、その入力ドライバをXサーバに
組み込んで、通常のXのイベントループの中でイベントと
して入力待ちができます。

さらに、XFree86 系の場合は、XFree86 的な作法に則って
コードを書くと、設定ファイルの Device セクションで、
そのドライバの組み込みを指示してパラメータなどを渡す
ことが可能になります。

ジョイスティックなどのコードは XFree86 や Xorg の
ソースツリーだと以下のあたりにありますので参考に
してみてください。
xc/programs/Xserver/hw/xfree86/input
えー、はしょってたので誤解を招いたと思います。

1. XPeekEvent()でイベントがある間はXNextEvent()で取り出して処理する。
2. で、とあるWindowの状態を調べようとする。

この1.と2.の間で、さらにイベントが届いてしまっていて、実際に調べた結果は見た目と合わないわけです。

これと別に入力をチェックしたい方面もありますが、これはXサーバへの接続のファイル記述子と併せて2.が終わった後でselect(2)して調べています。
> この1.と2.の間で、さらにイベントが届いてしまっていて、
> 実際に調べた結果は見た目と合わないわけです。

そのあと、またチェックすればすぐに合うのでは?
Xtのソースを確認したところ、XtAppAddInput()もFD_SETで初期化しているのでselect/pollを使っているようです。
selectに渡すX自体のファイルディスクリプタはどうしたら得られるのかと思ったら、ConnectionNumber()で得られることが判りました。
なので、Xと/dev/input/event?のファイルディスクリプタをselect()に突っ込んで、
Xに何かあったらXPeekEvent/XNextEventでイベントを取り出して、
/dev/〜に何かあったら読んで情報を更新する
でうまくいきそうな気がします。
気になるのは/dev/〜のディスクリプタをselectに突っ込んでブロックしてくれるのかどうか(常に読みだし可能と判断されないか)というところですが、試してみないことにはなんとも。
select()がすぐに戻ってくるようならドライバのselectを書き換えて操作する(状態が変わる)までブロックするようにする必要があります。
> そのあと、またチェックすればすぐに合うのでは?
いったい何時まで「またチェック」する必要があるのかって問題となるわけです。
> いったい何時まで「またチェック」する必要があるのかって問題となるわけです。

プログラムが終了するまで、
ループの頭には単一のselectが機能するはずだが、
作ろうとしているのはselectのループが存在せずに
値が読めたら即終了するプログラム?
こういうことをしてます。

1. XPeekEvent()でイベントがくる間はXNextEvent()で取り込んで記録する。
2. 来なくなったら、記録した情報を元に今のウィンドウの状況を調べて、他のプロセスに状況を送信する。
3. select()で、他のプロセスから要求が来ていたら、その処理を行う。このときはXサーバへのファイル記述子も見ていますが、どっちにしろこの時点で1.に戻る。

最初はselect()でループを回したのですが、イベントの処理を主に変えました。で、2.で「来なくなったら」と思っていたら、実はまだ来ていたという場面がありました。

書いてる途中で、もう少しトライすべき方法も見えてきました。ありがとうございます。
> で、2.で「来なくなったら」と思っていたら、実はまだ来ていたという場面がありました。

それは次のループ内で処理されるのだから、一瞬の遅延になるだけのような。
「実際に調べた結果は見た目と合わない」というのは、
一瞬の遅延が人間の目で認識できてしまう問題なのだろうか。
> 最初はselect()でループを回したのですが、イベントの処理を主に変えました。
> で、2.で「来なくなったら」と思っていたら、実はまだ来ていたという場面がありました。

これって、13番の
「ちゃんとselectしているのにしばらく待たないとイベントが届いていない」
の話と違う内容に。
「ちゃんとselectしているのに」が前提なんですけどね。
XPeekEvent()とselect()の併用ではなくて、1つのselect()で回すべきです。
なぜなら、Xのイベントもselect()のイベントも発生していないときには無駄な空ループになってしまいます。
select()にタイムアウトを指定敷いた場合、select()からタイムアウトして戻ってくるでXに対して無反応になってしまいます。
えーっと...(トピ主の頭の整頓も兼ねて...)

僕の書いたソースコードだと

[XIを使わず、直接deviceを開いている。]

そのためXPeekEvent を使い polling しながら
rpower_mateの値を読むことが可能。
もしくはselect(2)/poll(2)で値を読むことが可能。
(pollingって?? select(2)/poll(2)??って...
というのは自分で調べるとしてf^^;)

僕自身の解釈では、比較的この方法は楽。
ただし、未着のイベントが届ききるまでの
遅延が発生する?? ということでしょうか??



XIを使うと、えたんだーるさんのコメントにあるように

DEVICE_INIT
DEVICE_ON
DEVICE_OFF
DEVICE_CLOSE

などを設定する必要がある。
結構大変だけど、できると
常のXのイベントループの中でイベントとして入力待ちができる。

(こちらは遅延などが発生しないのでしょうか??)


...ということでしょうか??

(とんでもない勘違いをしていたら、御指摘ください。)

皆様の快いアドバイス、本当に感謝しています。
[ポーリング/polling]
特定の入力ソースやステータスフラグなどを監視して、監視対象が
準備完了かどうかを調べるような、プログラム上の処理一般を指す
言葉です。

今回の例ではXのイベントキュー、power mate の入力などが
ポーリングの対象となり得る処理です。

[select(2)]
(N)はマニュアルページのセクション番号で、N = 2 はシステム
コールを指します。つまりここでは select システムコールを
指しています。

select(2) は特定のファイルディスクリプタやソケットを監視
するためのシステムコールで、入力が可能になるまでブロック
します。

power mate のデバイス入力に対して select でブロックして
しまうと、その間はXのイベントが取れないのが問題です。

ここまでのコメントで「ConnectionNumber() を使う」と
いうものがありましたが、これは ConnectionNumber() で
得られたディスクリプタを select(2) の監視対象にする
ことで、Xのイベント発生が監視できるということです。

select(2)は複数のディスクリプタを一回のシステムコール
で監視できるので、Xのイベントと power mate の入力を
select システムコールで同時に監視すれば、どちらかの
要因で select システムコールでのブロックから抜けて、
どちらの要因だったかを調べて処理を分岐させれば良い、
というわけですね。

分岐後の処理が完了したらまたselect(2)する、という
ループ処理を書けば良いわけです。

select(2) を使用するためにはデバイスドライバが
select(2) に対応している必要があります。

[poll(2)]
poll システムコールは、指定したファイルディスクリプタが
入力可能かどうかを調べるためのシステムコールです。

poll(2)を使用する場合もselect(2)同様、デバイスドライバ
がpoll(2)に対応している必要があります。

usleep(3)などを使って適当な間隔でpoll(2)して、あとやる
べきことはselect(2)の場合と同じです。

この場合も処理が完了したら、poll(2)での入力待ちに戻る
必要があります。

また自力でselect(2)/poll(2)を呼ぶ以外にアプリケーション
側で入力処理を追加する方法もあります。

プログラミングに Xt を使う場合には、XtAppAddInput() を
使用して特定のファイルディスクリプタを指定してやると、
イベント待ちの処理にファイルディスクリプタの監視を追加
できます。

あとはそれぞれのイベントに対するコールバックを登録して、
XtAppMainLoop() というわりとシンプルなプログラムになり
ます。

以上ここまで、「アプリケーションはC言語で書いてください」
という話になりますね。


で、最後にXIを使う場合ですが、これは power mate の入力
がマウスやキーボードの入力と基本的に同列に扱われるという
ことになります。

XI での入力処理が書けてしまえば、Xでのプログラミングを
サポートしている大抵のプログラム言語でアプリケーション
を書くことができる、というメリットがあります。

XI での入力処理は結局C言語で書くことにはなるんでしょうが…。
> [ポーリング/polling]
> 特定の入力ソースやステータスフラグなどを監視して、監視対象が
> 準備完了かどうかを調べるような、プログラム上の処理一般を指す
> 言葉です。

あ、これはCPUをぶん回して監視するという意味です。

例えば割り込みで監視するような場合はポーリングとは
言いません。
> XPeekEvent()とselect()の併用ではなくて、1つのselect()で回すべきです。

しかしXPeekEventは必須でしょう。
XPeekEvent()ではなくてXPendingでも良いので「必須」ではありません。
というのはともかくとして、意図としてはループの度にXPeekEvent()を呼ぶのではなくてselect()の結果に応じて呼ぶかどうかを決めるべきだ、というものです。
> select()の結果に応じて呼ぶかどうかを決めるべきだ、というものです。

そうあるべきですね。
ただしselectの直後は連続selectになるので問題あり。
>返信ありがとうございます。

fd_set org_set,read_set;

FD_ZERO( &org_set );
FD_SET( rpower_mate, &org_set );
FD_SET( lpower_mate, &org_set );

while(1)
{
char buf[100];
XPeekEvent(d,&e);
select( rpower_mate + 1, &read_set, NULL, NULL, NULL );
select( lpower_mate + 1, &read_set, NULL, NULL, NULL );
XConnectionNumber(d);

//XtAppAddInput(rpower_mate, fileno(fid), XtInputReadMask,
// get_file_input, NULL);
//XtAppMainLoop(rpower_mate);
// XSendEvent(d,w,True, 0xfff, &e) ;
//ここら辺が未だによく分かってなく... f^^;

switch (e.type) {
case Expose:
redraw(d,w,gc);
// x = x + 1 ;
// replot(d,w,gc,x,y);
case KeyPress:
break;
}

イメージとしてはこんな風になるのでしょうか??
イベントタイプで分岐させる...のとは違うのでしょうか??
(selectで値をとってくるというのは、なんとなく理解できたのですが、
その後の とってきたイベントを如何にしてXに送るべきなのかに
相変わらず、悪戦苦闘... orz
powermateを回転させると、反応はするようなので、
あとは回転量に応じて、点をプロットできるもの...などが理想なのですけど...)

とここで、新たに疑問が生まれまして...

select( rpower_mate + 1, &read_set, NULL, NULL, NULL );
select( lpower_mate + 1, &read_set, NULL, NULL, NULL );

この部分が、どうやら片方しか読みこんでくれないようで...

別サンプルなどで

while ( 1 ) {
read_set = org_set;
printf( "Calling select() ...\n" );
// select( rpower_mate + 1, &read_set, NULL, NULL, NULL );
select( lpower_mate + 1, &read_set, NULL, NULL, NULL );
printf( "Now possible to read()\n %d", cnt );
read( lpower_mate, buf, sizeof( buf ) );
read( rpower_mate, buf, sizeof( buf ) );
cnt ++;
}

片方をコメントアウトすると、
なぜかrpower_mateとlpower_mate両方の
値を読んでくれているようなのですが...
これはなぜでしょうか??
いろいろと誤解してますね。

1. 「その後の とってきたイベントを如何にしてXに送るべき」
イベントをXに送る必要はないし、できません。
powermateから来たイベントは、自分の望むように (変数を変更するなり、音を鳴らすなり) 処理してください。
その結果、表示を変えたいこともあるだろうけど、そのときに Exposeとかを自分自身に投げてください。

2. 多分あなたの codeでは XtAppAddInputとかは使えません。
なぜなら、Xt Intrinsicsをそもそも使ってないからです。
その代わりになるのが selectです。

3. selectの使い方が間違っています。
selectは複数の descriptorを同時に監視できるので 1回でokです。監視する descriptorは 2つの power_mateのほか、Xの descriptor (XEventも file descriptor経由できます。XNextEventとかは file descriptorから読み取るための関数に過ぎません)です。Xの descriptorを得るのが XConnectionNumber() です。

selectの使い方は network programmingの入門サイトに書かれていると思います。X11も (XNextEventなどを使っているうちは隠されていますが) network programmingの一種なので。
>゛゛゛゛゛゛さん

御指摘ありがとうございます。

...なるほど、たしかにselectはFD_SETで指定したものを
読み込んでくれるようですね...f^^;
勘違いしてました。

while(1)
{
read_set = org_set;
char buf[100];
XPeekEvent(d,&e);
select( lpower_mate + 1 , &read_set, NULL, NULL, NULL );
r = read( rpower_mate , ibuffer, sizeof(struct input_event) * BUFFER_SIZE);
l = read( lpower_mate , ibuffer, sizeof(struct input_event) * BUFFER_SIZE);
if( r > 0)
{
x = x + 1;
XDrawPoint(d,w,gc,x,y);
XFlush(d);
}

if( l > 0)
{
y = y + 1;
XDrawPoint(d,w,gc,x,y);
XFlush(d);
}
}
XCloseDisplay(d);
}

こんな形で、イメージに相当近く なったのですが...
XConnectionNumber() を用いてません...
(これは、どこかでトラブルの元になるのでしょうか??)

とりあえず、あとは

・回転方向(時計回り/反時計回り)に応じて、動く方向が変える
(たぶんこれは、 r とか l の値を調整すればよいはず...)

・一定の条件を満たすと、画像が出力される
(もしくは、プログラム起動時に、背景画像のようなものが
出力される)

という過程を考えているのですが ...
XConnectionNumberは Xの Eventをまじめに処理しようと思ったら必要になります。上のイメージのコードでは、Xの Eventは無視されている (i.e. XPeekEventで覗いてはいるが、eを handlingするコードがない) のでなくてもそれなりに動くかもしれません。でも Xの Event処理はやっぱり必須でしょう。たとえば Expose eventをハンドルしないため「背景画像のようなものが出る」という症状になっているのでは。

XConnectionNumberでえられた descriptorは、ほかのdescriptor(rpower_mateや lpower_mate)と同じように変化を待つ対象として使えます。要するに FD_SETの引き数になると。

で、selectから帰ってきたらとにかく readしていますが、一般には FD_ISSETで調べてから readすべきでしょう (powermateというdeviceの特性上、これでも blockingすることなく動くのかもしれませんが)。これは Xの descriptorも混じってきたらもっと問題になります。

あと、selectの第1引き数の "lpower_mate + 1" も結構心配...

全体的に「selectの意味、使い方」と「Xの network programとしてのアーキテクチャ」をもう少し理解すべきの気がします。
> ちょっと外れるかもしれませんが、XPeekEvent()で届いている
> イベントがある間はXNextEvent()で処理を済ませた上で、ある
> ウィンドウの状態を調べるといったことをしたのですが、どう
> も見た目と調べた状態がずれてしまいました。
何てことを以前に書きましたが、やはり間違っていたのは自分でした。:-(
お騒がせしました。
ConnectionNumber()を用いていないということは、select()はXのイベントを監視対象にしていないということです。
仮りにXPeekEvent()で取得したイベントを処理するコードを追加したとしても
- 他のウィンドウを重ねてどけてもウィンドウが再描画されない。
PowerMateを操作するとウィンドウが描画される
- キー入力に反応しない。
PowerMateを操作するとキー入力に反応する
といった動作になります。たぶん。
>゛゛゛゛゛゛ さん びいさん

アドバイスありがとうございます。
ご指摘のとおり、
相当不思議な動作をしてる部分が多々あります。
(キー入力に反応しなくて、終了に苦労したり)

まだまだ試行錯誤してみます。
(別件で、あと2,3日は手を加える時間がなさそうですが...)

しかも、ゲーム感覚にしようとして
SDLを導入してみたりするとひっちゃかめっちゃかになって
いて...(フルスクリーンモードにしたかったので...)

またソースをのっけたりするかもしれませんが、
そのときはアドバイスをいただけたらと思います。

ありがとうございます。
取り急ぎお礼を。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

X Window System 更新情報

X Window Systemのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。