コンソールアプリケーションでマウスイベントを読み取るためにlibgpmを使用します。シェルから直接開始した場合は正常に機能します。 mc(真夜中の司令官)から開始した場合、マウスイベントを受信しません。
問題は、mcが私のプロセス用に作成する疑似端末に関連しています。 Gpm_Openに(0-auto?の代わりに)2番目の引数として渡された指定されたコンソール画面をgpmに使用させることで、この問題を半解決できます。
int Gpm_Open(Gpm_Connect*,int);
疑似tty(mcによって作成された)で実行するときに使用する仮想コンソール画面を知る方法はありますか?アクティブコンソールの使用を検討しましたが、アプリケーションが実行されているコンソールではない可能性があります。おそらくプロセスツリーをトラバースして、そのTTYが実際のコンソールであるかどうかを確認することはできますが、特定のpidのtty(name)を取得する方法がわからないため、昇格された特権が必要になると思います。
または、うまくいけば、もっと簡単な回避策はありますか?
編集:mcからプロセスを開始するが、gpmに特定のvc画面を使用させることなく(コマンドラインを使用して)Sudoを介してプロセスを開始することに気づきました-単純に機能します!
プロセスツリーを取得するためにps f
を実行する簡単な起動スクリプトを作成することができました。それは私に必要なすべてを教えてくれる素敵な出力を与えてくれます:
PID TTY STAT TIME COMMAND
281 tty1 Ss 0:00 -bash
383 tty1 S+ 0:00 \_ mc
385 pts/0 Ss 0:00 \_ bash -rcfile .bashrc
408 pts/0 R+ 0:00 \_ ps f
最後の行からそれを解析すると、実際のTTY = tty1で処理することになります(もちろん、それは有罪ですmc
)。したがって、最終的に、解析されたmcのtty番号を引数としてプログラムを実行できます。
別のオプションは、tty devidと親プロセスIDの両方を含むps
プログラムのように '/ proc/PID/stat'ファイルを解析して、プログラム内のtty番号を取得することです。しかし、スクリプトを使用すると、OSへの依存度が低くなると感じます。以下のサンプル '/ proc/PID/stat':
383 (mc) R 281 383 281 1025 383 ...
| |_ TTY: test major bits for type and minor for id
|______________ PPID: use to traverse tree
だから最後に私はこのコードを思いついた:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <gpm.h>
static int find_tty()
{
char buf[256];
char* ptr;
FILE* f;
int r;
char stat;
int ppid,pgrp,sess,tty;
int pid = getpid();
while (pid>0)
{
sprintf(buf,"/proc/%d/stat",pid);
f = fopen(buf,"r");
if (!f)
return 0;
r = fread(buf,1,255,f);
fclose(f);
if (r<=0)
return 0;
buf[r] = 0;
ptr = strchr(buf,')');
if (!ptr || !ptr[1])
return 0;
r = sscanf(ptr+2,"%c %d %d %d %d", &stat,&ppid,&pgrp,&sess,&tty);
if (r!=5)
return 0;
if ( (tty&~63) == 1024 && (tty&63) )
return tty&63;
pid = ppid;
}
return 0;
}
int main(int argc, char* argv[])
{
Gpm_Connect gpm_connect;
// ...
int gpm = Gpm_Open(&gpm_connect,find_tty()/*0*/);
// ...
}