Linux gcc, läsaALLA tangenter i textmode?

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6886
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Linux gcc, läsaALLA tangenter i textmode?

Inlägg av Marta »

När något körs under X11 finns eventet KeyPress som innehåller keycode och state. Vilken tangent som tryckts ner och skifttangenternas lägen rakt av utan några "hjälpsammheter". Vad finns det för funktion(er) utan X11 som ger motsvarande information eller den kan utvinnas? Utan ncurses eller andra förbannelser.
Nerre
Inlägg: 26652
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Linux gcc, läsaALLA tangenter i textmode?

Inlägg av Nerre »

Du vill alltså läsa scankoderna (som de kallas).

Jag googlade på "reading scancodes c" och det verkar inte riktigt finnas nåt standardiserat sätt att göra detta från "userspace", men det fanns lite olika lösningar som t.ex. använde IOstreams.

Den här artikeln listar en massa olika sätt att detektera om en tangent trycks ner, inte riktigt samma sak som du vill, men vad jag förstått kan dessa funktioner även användas för det du vill.

https://faq.cprogramming.com/cgi-bin/sm ... 1043284385
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6886
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Linux gcc, läsaALLA tangenter i textmode?

Inlägg av Marta »

Tack för länken. tyvärr inget som ger alla tangenter.

Problemet är att det finns många kombinationer som inte ger någon reaktion om info från tangentbordet har "förädlats" av någon duttirutin innan den presenteras för programmet. Så snart getchar() är inblandad är det tvärnit.

Eftersom X11 kan skicka rådata måste denna finnas tillgänglig. Är det ingen funktion kanske det är någon ioctl eller strea som skall öppnas. Hittar bara ingen vettig info.

Det är vanlig gcc utan ++.
Nerre
Inlägg: 26652
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Linux gcc, läsaALLA tangenter i textmode?

Inlägg av Nerre »

Nej, problemet är ju att om du kör programmet i userspace så har du normalt inte direkt tillgång till hårdvaran. Det är kerneln som läser tangentbordet och presenterar tryckningarna för userspace.

Om du även måste kunna läsa av nedtryckningar och uppsläppningar av shift, ctrl etc så tror jag du är så illa tvungen att använda nåt i stil med ncurses (eller skriva motsvarande själv, ncurses finns ju open sources så det är bara att läsa källkoden hur den jobbar).
Användarvisningsbild
hawkan
Inlägg: 2585
Blev medlem: 14 augusti 2011, 10:27:40

Re: Linux gcc, läsaALLA tangenter i textmode?

Inlägg av hawkan »

Kanske detta är det hållet du söker http://www.thelinuxdaily.com/2010/05/gr ... nputevent/

Vet ej om X måste vara startad, men tycker det borde funka utan.
Nerre
Inlägg: 26652
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Linux gcc, läsaALLA tangenter i textmode?

Inlägg av Nerre »

Mig veterligen är input events just nåt som finns i X (när jag har pysslat med fjärrkontroll till HTPC så jag ibland kunna använda input events, men de har bara fungerat med X igång).
Användarvisningsbild
hawkan
Inlägg: 2585
Blev medlem: 14 augusti 2011, 10:27:40

Re: Linux gcc, läsaALLA tangenter i textmode?

Inlägg av hawkan »

Kan vara som du skriver. I den här texten jag hittade verkar det ändå som /dev/input/xxx är generella och hanteras av kärnan.

http://www.embeddedlinux.org.cn/essenti ... 1sec1.html
Bild

Det kanske är tvärt om t o m så att den som öppnar /dev/input/xx konsumerar de event som finns. Men jag vet inte.

Det kan vara något att titta vidare på möjligen.
Nerre
Inlägg: 26652
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Linux gcc, läsaALLA tangenter i textmode?

Inlägg av Nerre »

I det här fallet handlar det väl om ett program som ska köras utan X, d.v.s. du måste titta på Console.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6886
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Linux gcc, läsaALLA tangenter i textmode?

Inlägg av Marta »

Den koden kräver att köras som root och faller på det. Efter att ha lagt till de tappade backslash i printf() så visade det att /dev/input/event1 var pc-speaker enligt programmet. Provade några nummer till, men bara ljudenheter och power button...
Dessvärre inte användbart.
Skulle vilja att programmet kan köras utan dependencies. X-versionen länkas direkt mot xlib och har funkat utan gnäll överallt. Det skall en terminalversion för *** också kunna göra.
Användarvisningsbild
hawkan
Inlägg: 2585
Blev medlem: 14 augusti 2011, 10:27:40

Re: Linux gcc, läsaALLA tangenter i textmode?

Inlägg av hawkan »

Det är nog /dev/input/event0 som är tangentbordet iaf här

Kod: Markera allt

hawkan@debian:/dev/input/by-path$ ls -l
totalt 0
lrwxrwxrwx 1 root root 9 jan 15 23:45 pci-0000:02:00.0-usb-0:1:1.0-event-kbd -> ../event0
lrwxrwxrwx 1 root root 9 jan 15 23:45 pci-0000:02:00.0-usb-0:1:1.1-event-mouse -> ../event1
lrwxrwxrwx 1 root root 9 jan 15 23:45 pci-0000:02:00.0-usb-0:1:1.1-mouse -> ../mouse0
lrwxrwxrwx 1 root root 9 jan 15 23:45 platform-pcspkr-event-spkr -> ../event5
Testa även chmod o+rw /dev/input/event0
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6886
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Linux gcc, läsaALLA tangenter i textmode?

Inlägg av Marta »

Här var det event12 och det är X-fritt. Funkade direkt efter reboot men måste köras som root och eventen enumreras vid uppstart. Nu var #2 pc-speaker och #1 power button. Hur de identifieras framgår inte av artikeln, eller så har jag läst slarvigt.
Findecanor
Inlägg: 982
Blev medlem: 2 juli 2010, 23:04:07

Re: Linux gcc, läsaALLA tangenter i textmode?

Inlägg av Findecanor »

Man ska kunna sätta stdin (fd 0) i "raw mode" med ett ioctl()-anrop och sen få råa "scancodes". De är olika koder för när en tangent trycks ner och när den släpps upp. Sen får man göra timing själv.
http://www.gcat.org.uk/tech/?p=70

De scancodes som skickas ser ut att vara de som kallas "set 1" och är samma koder i DOS och protokollet för PC-XT - tangentbord. De borde vara lätt att hitta om man googlar på "DOS XT scancodes" eller liknande.
(Förresten. Du kanske hittar "set 2" och "set 3" också. När IBM designade PC-AT så ändrade de i protokollet till tangentbordet till "set 2". Men för att äldre DOS-program skulle funka så stoppade de in en mikrocontroller som översatte koderna tillbaks till de gamla koderna som XT använde. Därför använde program på PC:n (även nuvarande Windows) fortfarande gamla XT-scankoderna.
PS/2 är samma protokoll som PC-AT med annan kontakt f.öv. "Set 3" är något som IBM använde för sina terminaler och arbetsstationer men som aldrig slog igenom på PC-sidan.)

I vanligt läge är det annars ANSI escape-koder både för input och output.
Man får ANSI-koder för de flesta tangenter och kombinationer men det är bara färdiga tecken och kontroll-koder och det finns tyvärr inga koder för Ctrl+Shift+<tecken>. Koderna kan också skilja sig lite mellan olika terminaler och Linux-consollen (vilket är en anledning till att man använder terminfo/ncurses som abstraherar bort skillnaderna)
Jag bifogar källkoden till ett litet C-program som läser stdin, tecken för tecken, med en enkel tillståndsmaskin som tolkar indata och skriver ut fullständigt inlästa koder i klartext. Den konverterar också från utf-8 till 32-bittars unicode. Den är visserligen ful som förväntar sig "utf-8" och nog buggar ur med annat.
Redigerat: Man går ur programmet med Ctrl+C. Ursäkta att jag missade att skriva det ... Programmet stänger av att få signal på Ctrl+C och du kan ändra bindningen.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6886
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Linux gcc, läsaALLA tangenter i textmode?

Inlägg av Marta »

Oj vad knöligt...

Finns det verkligen inget sätt att läsa av tangenterna utan någon "hjälpsam" funktion som knökar ihop det och sedan måste knökas tillbaka till scancodes och shiftstate?

Här är koden som skall ta emot keycode och shiftstate samt en av tabellerna som hör till.

Kod: Markera allt

int KeyConv(int Key, int State, int* twokey){

  int result;
  bool capsLock;


	//printf("Keycode %02x\n", Key);

  //static int twokey = 0;
  

  //printf("deb KeyConv keycode: %02x\n", Key);

  result = -1;						//assume not valid keypress

  capsLock = ((State & 0x02) !=0);			//keep capslock status
  State &= ~0x12;					//clear capslock and numlock bits

  
  if (*twokey == 0){					//2:nd of twokey?

  	switch (State){					//no, convert to char, shift/crrl/alt/caps selects conv.table
 
	  case 0x00: if (Key<0x80){
	               if (!capsLock)
	                 result = KeyNone[Key]; 
	               else  
	                 result = KeyLock[Key];
		       break;
		     };
		       
	  case 0x01: if (Key<0x80) result = KeyShift[Key]; break;

	  case 0x04: if (Key<0x80) result = KeyCtrl[Key]; break; 

	  case 0x08: if (Key<0x80) result = KeyAlt[Key]; break;

	  case 0x40: if (Key<0x80) result = KeyWin[Key]; break;

	  case 0x80: if (Key<0x80) result = KeyAltGr[Key]; break;
  };


  }
  else{

  	switch (*twokey){
  	
  	  case -0x100: if (Key<0x80) result = Key2Q[Key]; break;
  	  case -0x200: if (Key<0x80) result = Key2K[Key]; break;
  	  case -0x300: if (Key<0x80) result = Key2O[Key]; break;
  	  case -0x400: if (Key<0x80) result = Key2AltK[Key]; break;
  	
  	};
  	*twokey = 0;
  	
  };
	
  if ((result<0) && (result!=-1) ){
    *twokey = result;	
    result = -1;
  };  
	

  return result;
    
}; //KeyConv


short KeyNone[0x80] = {

//										esc	1	2	3	4	5	6
//	00	01	02	03	04	05	06	07	08	09	0a	0b	0c	0d	0e	0f
	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	27,	'1',	'2',	'3',	'4',	'5',	'6',

//	7	8	9	0	+	' l bs	backsp	tab	q	w	e	r	t	y	u	i
//	10	11	12	13	14	15	16	17	18	19	1a	1b	1c	1d	1e	1f
	'7',	'8',	'9',	'0',	'+',	-1,	p+29,	p+42,	'q',	'w',	'e',	'r',	't',	'y',	'u',	'i',

//	o	p	å	^	return	?	a	s	d	f	g	h	j	k	l	ö
//	20	21	22	23	24	25	26	27	28	29	2a	2b	2c	2d	2e	2f
	'o',	'p',	229,	-1,	p+34,	-1,	'a',	's',	'd',	'f',	'g',	'h',	'j',	'k',	'l',	246,

//	ä	§	?	*	z	x	c	v	b	n	m	,	.	-	?	num *
//	30	31	32	33	34	35	36	37	38	39	3a	3b	3c	3d	3e	3f
	228,	-1,	-1,   '\'',	'z',	'x',	'c',	'v',	'b',	'n',	'm',	',',	'.',	'-',	-1,	'*',

//	?	space	?	F1	F2	F3	F4	F5	F6	F7	F8	F9	F10	?	?	num 7
//	40	41	42	43	44	45	46	47	48	49	4a	4b	4c	4d	4e	4f
	-1,	0x20,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	'7',	

//	num 8	num 9	num -	num 4	num 5	num 6	num +	num 1	nom 2	num 3	num 0	num .	?	?	<	F11
//	50	51	52	53	54	55	56	57	58	59	5a	5b	5c	5d	5e	5f
	'8',	'9',	'-',	'4',	'5',	'6',	'+',	'1',	'2',	'3',	'0',	'.',	-1,	-1,   0x3c,	-1,

//	F12	?	?	?	?	?	?	?	?	?	num /	?	?	?	home	uparrow
//	60	61	62	63	64	65	66	67	68	69	6a	6b	6c	6d	6e	6f
	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	p+12,	

//	pgup	leftarr	rghtarr	end	downarr	pgdown	insert	delete	?	?	?	?	?	?	?	?
//	70	71	72	73	74	75	76	77	78	79	7a	7b	7c	7d	7e	7f
	p+15,	p+2,	p+3,	-1,	p+13,	p+14,	-1,	p+31,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1	
	
};//KeyNone
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6886
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Linux gcc, läsaALLA tangenter i textmode?

Inlägg av Marta »

Skulle det gå att få ett unikt värde för varje tangentkombination så kaj ju detta sedan "enkelt" omvandlas till scancode och shiftstatus med en helvetestabell som tar en dag eller två att få ihopa.

Tyvärr faller väl allt på att det inte kommer något tecken vid enbart shift. I X11 finns ju invalidstöd, men i äkta terminalläge måste programmet hantera detta. Friskhanden klarar inte alla kombinationer för avståndet blir för stort mellan tangenterna och då måste shift/ctrl/alt stana kvar. helst också kunna släppas upp vid misstag, något som X11 invalidstöd saknar..
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Linux gcc, läsaALLA tangenter i textmode?

Inlägg av lillahuset »

Marta, jag har inget konkret att bidra med i det här ämnet men tycker att du verkar vara på hugget igen. Trevligt! :D
Skriv svar