Usando o gpm como entrada do mouse no meu aplicativo iniciado a partir do mc (midnight commander)

2

Eu uso libgpm para ler eventos de mouse no meu aplicativo de console. Ele funciona bem se iniciado a partir do shell. Ele não recebe nenhum evento de mouse se iniciado a partir de mc (comandante da meia-noite).

O problema está relacionado ao pseudo-terminal mc criado para o meu processo. Eu posso semi-resolver esse problema, forçando o gpm a usar a tela do console especificada, passada como segundo argumento para Gpm_Open (ao invés de 0 - auto?).

int Gpm_Open(Gpm_Connect*,int);

Existe alguma maneira de saber qual tela de console virtual devo usar ao executar no pseudo-tty (criado por mc)? Eu considerei usar o console ativo, mas pode não ser aquele em que meu aplicativo está sendo executado. Provavelmente, percorrendo a árvore de processos e verificando se o seu TTY é um console real funcionaria, mas eu não sei como obter o tty (name) para o dado pid e tenho medo de precisar de privilégios elevados para isso.

Ou esperamos que haja alguma solução mais simples?

Edit: Acabei de notar que iniciar meu processo a partir do mc mas via sudo (usando a linha de comando) sem forçar o gpm a usar a tela vc - simplesmente funciona!

    
por Anonymous 13.02.2018 / 18:31

1 resposta

0

Eu consegui criar um script de inicialização simples que executa ps f para obter a árvore de processos. Isso me dá uma boa saída dizendo tudo que eu preciso:

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

Analisá-lo da última linha leva-me a processar com um TTY real = tty1 (claro que é culpado mc ). Então, finalmente, posso executar meu programa com o número de parsed mc tty como um argumento.

Outra opção seria recuperar o número tty dentro do programa analisando os arquivos '/ proc / PID / stat' como ps program que contém tanto o tty dev id quanto o pai process id. Mas usar script me faz sentir que é menos dependente do sistema operacional. Amostra '/ proc / PID / stat' abaixo:

383 (mc) R 281 383 281 1025 383 ...
            |            |_ TTY:  test major bits for type and minor for id
            |______________ PPID: use to traverse tree 

Então, no final, eu criei este código:

#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*/);
    // ...
}
    
por 14.02.2018 / 11:59

Tags