web-dev-qa-db-ja.com

getch()ncursesでCtrl、Shift、またはAltを取得する方法は?

取得する方法 Ctrl、 Shift または Altgetch() ncurses?
取得するために動作させることができません Ctrl、 Shift または Altgetch()でncursesを使用しますか?私は男の中で何かが恋しいですか?

14
klefevre

正しい答えが降格されることがあり、「権威ある」諦めた答えが昇格することは驚くべきことです...少しの創造性で、key_nameは実際にこれを理解するための正しい鍵を握っていますが、1つの注意点があります-SHIFT/ALT/CTRLは同時に他のキーで押された:

  • まず、印刷可能なキーなどの「通常のキー」の場合、大文字であるため、シフトを簡単に検出できます。

  • 特別なキーの場合、例: KEY_LEFT、SHIFTが選択されたときに生成されるコードが実際にはKEY_SLEFTであることがわかります。 KEY_RIGHTの同上。残念ながら、SHIFTに惑わされていないように見えるKEY_UP/KEY_DOWNにはそのような運はありません。したがって、返された文字とgetch()を区別できます。KEY_S..は、シフトが押されたことを意味します。

  • ALT(少なくともXまたはAqua Windowmanagerによってトラップされないもの)の場合、keynameはキーをM ...何かに変換します。

  • Ctrlキーを押すと、実際のキー名の前に「^」が表示されます。例:キー18の^ R

したがって、簡単なスニペットで、switch(getch)ステートメントなどのキーコードを理解できるようになりました。

ch = getch(); endwin(); printf("KEY NAME : %s - %d\n", keyname(ch),ch);

それだけです。明確に「できない」と言う前に考えてください。たぶん、あまり明白ではない方法があります。

16
Technologeeks

(私の答えを大まかにコピーするには CursesでShift + X/Alt + Xキーを取得する方法は?

短編小説-できません。修飾キーはまさにそれです-修飾キー。それらはそれ自体では存在せず、押す可能性のある他の(印刷)キーを変更します。

そうは言っても、特に勇気がある場合は、my libtermkey を試すことができます。これにより、少なくとも次のようなものが正しく解析されます。 Ctrl-arrow

最後に、勇気さえ感じている場合は、私が書いたターミナルを実行できます pangoterm これには、任意に変更されたUnicodeキーをエンコードする一般的な方法があるため、区別できます Ctrl-m から Enter、 Ctrl-Shift-a から Ctrl-a、など.。

しかし、これら以外では、答えは「できません」のままです。

6
LeoNerd

少なくともコントロール修飾子については、簡単な解決策があります。 Cursesはviソースコードから派生したもので、次のようなものがあります( https://github.com/nt-roff/ex-1.1/blob/master/ex.h 77行目と https://github.com/nt-roff/ex-1.1/blob/master/ex_vops.c 445行目):

#ifndef CTRL
#define CTRL(c) ((c) & 037)
#endif

switch(getch()) {
case CTRL('r'):
    /* key ctrl-r (i.e. ^R) pressed */

使用されるインクルードに依存するCTRLは、コードで定義されている場合とされていない場合があります。

4
user3224237

@leonerdに(部分的に)同意すると、ncursesはonlyとして使用されるキーを提供します他のキーへの修飾子(ASCIIescape文字を無視します。 Alt キー)。一部の特定のデバイスは、この情報を提供するように指示できます(たとえば、 console_ioctl(4) に記載されているLinuxコンソール)が、ncursesが解決する問題ではありません。

長い答えについては、ncurses FAQ shift-またはcontrol-modifiersを使用するにはどうすればよいですか? を参照してください。

しかし短い:ncursesは、特定の修飾子が使用されたかどうかを通知しません(よく知られている使用法があった特別な場合を除く) shift)ではなく、その端末の説明は、次のいずれかの情報を提供します。

  • 実際のファンクションキーに、シフト修飾子とコントロール修飾子の組み合わせ、または
  • xtermのPCスタイルのファンクションキー(shiftは2、altは3、controlは5など)に基づく名前を使用して、情報を提供します。

2つのアプローチがあります。最初のアプローチは60以下のファンクションキーの配列(シフトとコントロールの組み合わせに十分)を使用し、もう1つはユーザー定義名のみを使用するためです)。

これらの変更されたキーはすべて、複数のバイトを提供します。 ncursesで(もちろん)keypad()を使用するアプリケーションは、単一の数値を取得します。後者の場合、キーコードは実行時に決定されます。

これは主に特殊キー(機能キー、編集キー、カーソルキー)に適用されます。通常のキーの場合、 keyname は特別な動作を与えると思われるかもしれませんが、説明を読むと次のようにはなりません。

  • ASCII制御文字(iscntrlマクロを使用して実行できます)を報告し、
  • メタ(使用する可能性のある端末のxtermにのみ役立つ)についての仮定を行い、
  • の助けを提供しません shift 修飾子。

端末の...すべて内部で利用可能な修飾子情報がありますが、端末には通常、この情報をアプリケーションに渡す方法がありません。 xtermmodifyOtherKeys リソースを使用してこれを行うことができます。

   modifyOtherKeys (class ModifyOtherKeys)
           Like modifyCursorKeys, tells xterm to construct an escape
           sequence for other keys (such as "2") when modified by
           Control-, Alt- or Meta-modifiers.  This feature does not apply
           to function keys and well-defined keys such as ESC or the
           control keys.  The default is "0":

           0    disables this feature.

           1    enables this feature for keys except for those with well-
                known behavior, e.g., Tab, Backarrow and some special
                control character cases, e.g., Control-Space to make a
                NUL.

           2    enables this feature for keys including the exceptions
                listed.

これは、 XTerm制御シーケンス に見られる制御シーケンスに対応します。

CSI > Ps; Ps m
          Set or reset resource-values used by xterm to decide whether
          to construct escape sequences holding information about the
          modifiers pressed with a given key.  The first parameter iden-
          tifies the resource to set/reset.  The second parameter is the
          value to assign to the resource.  If the second parameter is
          omitted, the resource is reset to its initial value.
            Ps = 0  -> modifyKeyboard.
            Ps = 1  -> modifyCursorKeys.
            Ps = 2  -> modifyFunctionKeys.
            Ps = 4  -> modifyOtherKeys.

ただし(xterm固有の機能であるため)、ncursesで使用する理由はありません。getchが不必要に複雑になります。

3
Thomas Dickey

できません。主要なターミナルエミュレータには、それを実現するための拡張機能はありません。

X11環境を想定している場合は、X11関数を使用してそれを取得できますが、それはまったく別の質問です。

0
Per Johansson

key_name( c )を呼び出して、getch()から生成されたキーをctrl修飾子の状態を示すものに変えることができます。

たとえば、ctrl-rを押すと、このコードは「^ R」を表示します。

while( true )
{
   char c = getch();
   if ( ERR == c )
      break;

   const char *name = key_name( c );

   move( 2, 2 );
   clear();
   printw( "You entered: %s             ", name );
   refresh();

}
0
user14038