[c][unix] séquences touches directionnelles
Résolu
Dr.W
Messages postés
406
Statut
Membre
-
Dr.W Messages postés 406 Statut Membre -
Dr.W Messages postés 406 Statut Membre -
Bonjour a tous !
Je suis actuelement sur un projet qui consiste a reproduire un shell tel que le tcsh ou le bash.
J'ai un probleme avec les termcap (ca marche sous Freebsd , mais pas sous Ubuntu), j'ai longement cherche sur le net sans succes... Je vous expose le probleme:
Je n'arrive pas a intercepté les séquences de caractères des touches directionnelles via un read sur stdin (Sous ubuntu, sous FreeBSD ça marche nickel).
Je procède comme suis:
J'ai desactiver le mode echo et le mode canonique de mon term grace a ioctl:
Ensuite je recuperes les sequences grace a cette fonction:
1er probleme, je n'arrive pas a passe en mode non-applicatif sous Ubuntu (tgentent echoue), donc j'ai rajoute une ligne pour verifie si je suis sous Freebsd et le cas echeant passe en mode non applicatif.
Ensuite je commence a lire sur stdin pour recuperer les caracteres que l'utilisateur m'envoi, c'est ici que je bloque:
Quelqu'un saurait pourquoi je n'arrive pas a intercepte les sequences des fleches: gauche, droite, haut et bas?
Merci d'avance.
Je suis actuelement sur un projet qui consiste a reproduire un shell tel que le tcsh ou le bash.
J'ai un probleme avec les termcap (ca marche sous Freebsd , mais pas sous Ubuntu), j'ai longement cherche sur le net sans succes... Je vous expose le probleme:
Je n'arrive pas a intercepté les séquences de caractères des touches directionnelles via un read sur stdin (Sous ubuntu, sous FreeBSD ça marche nickel).
Je procède comme suis:
J'ai desactiver le mode echo et le mode canonique de mon term grace a ioctl:
void conf_term()
{
struct termios term;
if (ioctl(0, TCGETS, &term) < 0)
my_aff_error("TCGETS failed.");
term.c_lflag &= ~(ICANON|ECHO);
term.c_cc[VMIN] = 1;
term.c_cc[VTIME] = 0;
if (ioctl(0, TCSETS, &term) < 0)
my_aff_error("TCSETS failed");
}
Ensuite je recuperes les sequences grace a cette fonction:
char *xtgetstr(char *id, char **area)
{
char *tmp;
if ((tmp = tgetstr(id, area)) != NULL)
return (tmp);
my_puterror("Failed to get id: ", id);
return (NULL);
}
t_termcap *init_termcap(char **ae)
{
char *bp;
char *area;
t_termcap *tc;
area = xmalloc(4096);
bp = xmalloc(4096);
tc = xmalloc(sizeof(*tc));
if (tgetent(bp, get_name_term(ae)) <= 0)
my_aff_error("tgetent app failed");
tc->ue = xtgetstr("ue", &area);
tc->ul = xtgetstr("us", &area);
tc->so = xtgetstr("so", &area);
tc->se = xtgetstr("se", &area);
tc->cl = xtgetstr("cl", &area);
tc->vi = xtgetstr("vi", &area);
tc->ve = xtgetstr("ve", &area);
tc->kD = xtgetstr("kD", &area);
tc->nd = xtgetstr("nd", &area);
if (!strcmp(my_trunc_str(my_getenv(ae, "HOSTTYPE", 8), '='), "FreeBSD", 0))
if (tgetent(bp, my_strcat(get_name_term(ae), "-noapp")) <= 0)
my_aff_error("tgetent -noapp failed");
tc->kb = xtgetstr("kb", &area);
tc->ku.noapp = xtgetstr("ku", &area); // Voila les sequences qui pose probleme
tc->kd.noapp = xtgetstr("kd", &area);
tc->kr.noapp = xtgetstr("kr", &area);
tc->kl.noapp = xtgetstr("kl", &area);
tc->dc = xtgetstr("dc", &area);
return (tc);
}
1er probleme, je n'arrive pas a passe en mode non-applicatif sous Ubuntu (tgentent echoue), donc j'ai rajoute une ligne pour verifie si je suis sous Freebsd et le cas echeant passe en mode non applicatif.
Ensuite je commence a lire sur stdin pour recuperer les caracteres que l'utilisateur m'envoi, c'est ici que je bloque:
void get_command(t_store *stor)
{
char *buffer;
char *buffer_cpy;
int pos;
pos = 0;
buffer_cpy = xmalloc(BUFF_SIZE);
memset(buffer_cpy, 0, BUFF_SIZE);
buffer = xmalloc(5);
aff_prompt(stor->me, stor->nbr_cmd, stor->conf);
while (*buffer != '\n')
{
memset(buffer, 0, 5);
xread(0, buffer, 5);
if (!strcmp(buffer, stor->tc->ku.noapp)) // Je ne rentre jamais dans cette condition peu importe quel sequence je compare (ku, kd, kl, kr) ca echoue toujours sous ubuntu (sous freebsd ca marche nickel)
{
my_printf("OK");
if (pos > 0)
{
pos --;
my_printf("\b");
}
}
else if (!my_strcmp(buffer, stor->tc->kb)) // ici c'est pour intercepte backspace (ca marche nickel sous Ubuntu && freebsd)
{
if (pos > 0)
{
pos --;
my_printf("\b \b");
buffer_cpy[my_strlen(buffer_cpy) - 1] = '\0';
}
}
else if (*buffer >= ' ' && *buffer <= '~')
{
buffer_cpy = strcat(buffer_cpy, buffer);
my_putchar(*buffer);
pos ++;
}
}
stor->buffer = buffer_cpy;
free(buffer);
my_putchar('\n');
stor->nbr_cmd ++;
what_to_do(buffer_cpy, stor); // ici j'envoi la command pour la parses et l'executer
}
Quelqu'un saurait pourquoi je n'arrive pas a intercepte les sequences des fleches: gauche, droite, haut et bas?
Merci d'avance.
A voir également:
- [c][unix] séquences touches directionnelles
- Touches rémanentes - Guide
- Touches télécommande tv - Guide
- Couper des séquences dans une vidéo - Guide
- Excel touches directionnelles ne fonctionnent plus ✓ - Forum Excel
- Je dois appuyer longtemps sur les touches de mon clavier ✓ - Forum Clavier
3 réponses
Ton problème semble lié au mode non applicatif, non ? C'est les touches que tu utilises avec .noapp qui merdent.
Si tu essayais de traité les touches de direction comme des touches "normales" comme backspace par exemple ?
Sinon, regarde dans les sources de bash (par exemple) comment c'est fait.
Si tu essayais de traité les touches de direction comme des touches "normales" comme backspace par exemple ?
Sinon, regarde dans les sources de bash (par exemple) comment c'est fait.
Ouais, en faite sous Ubuntu je recupere les touches en mode applicatif a default de pouvoir les recuperer autrement, c'est juste la structure qui les contient qui s'appell noapp. Sinon ouais j'ai essayer de regarder les sources du bash, mais visblement il ont trouve un moyen pour ne pas utilise les termcap qui me depasse completement... Voir la ligne dans bashline.c: /* To avoid including curses.h/term.h/termcap.h and that whole mess. */
Je vais alle voir dans le sources du tcsh pour voir...
Je vais alle voir dans le sources du tcsh pour voir...