Comment déterminer la couleur actuelle de la sortie de la console?

14

Je sais que, si un terminal coloré est disponible, on peut colorer sa sortie en utilisant des caractères d'échappement .

Mais y a-t-il une possibilité de savoir de quelle couleur la sortie est actuellement affichée? Ou mieux, de quelle couleur serait le texte, si je le sortais maintenant?

Je demande de ne pas casser les paramètres de couleur précédents lors de l'utilisation de ces caractères d'échappement. Le caractère d'échappement 'couleur de premier plan par défaut' obtient ses informations du jeu de couleurs, plutôt que la couleur du texte avant de le changer.

Minix
la source
En regardant les variables termcap et terminfo, il semble que ce ne soit pas possible. Vous pouvez par exemple obtenir le nombre de couleurs que votre terminal prend en charge avec echotc Coou echoti colors, mais il n'y a tout simplement pas de variable qui stocke la définition actuelle du code couleur.
jimmij
@jimmij Je le pensais et j'espérais avoir raté quelque chose. Si vous êtes certain que cela n'est pas possible, répondez-y et je l'accepterai finalement, si rien d'autre ne suit. Merci pour votre temps.
Minix

Réponses:

10

En général, l'obtention des couleurs actuelles est impossible. Le traitement de la séquence de contrôle d'un terminal se produit "à l'intérieur" du terminal, où que ce soit. Avec un émulateur de terminal tel que xtermou celui intégré dans un noyau de système d'exploitation qui fournit les terminaux virtuels du noyau, l'état interne de l'émulateur, y compris sa notion du "rendu graphique" actuel (c'est-à-dire la couleur et les attributs), est sur la machine lui-même et est théoriquement accessible. Mais pour un vrai terminal, ces informations se trouvent dans un emplacement RAM sur une machine physiquement séparée connectée via une liaison série.

Cela dit, certains terminaux incluent un mécanisme de lecture de ces informations dans le cadre de leur protocole de terminal, qui est envoyé sur cette liaison série. Ils fournissent des séquences de contrôle qu'un programme peut envoyer au terminal, qui lui font renvoyer des informations sur son état interne, en tant qu'entrée du terminal. mikeservvous a montré les séquences de contrôle auxquelles l' xtermémulateur de terminal répond. Mais ceux-ci sont spécifiques à xterm. Les émulateurs de terminaux intégrés dans le noyau Linux et les différents noyaux BSD sont par exemple différents types de terminaux et n'implémentent pas du tout de telles séquences de contrôle. Il en va de même pour des familles entières de terminaux réels.

Les terminaux DEC VT525 implémentent un mécanisme de lecture, mais ont un ensemble de séquences de contrôle qui n'a aucune relation avec celles utilisées par xterm. On envoie la séquence DECRQSS (Request Selection or Setting) pour demander le rendu graphique actuel, et le terminal répond en envoyant le DECRPSS (Report Selection or Setting). Plus précisément:

  1. L'hôte envoie: DCS $ q mST (DECRQSS avec la partie fonction de contrôle de SGR comme paramètre)
  2. Le terminal répond: DCS 0 $ r 0 ; 3 3 ; 4 4 mST (DECRPSS avec les paramètres et la fonction de contrôle faisant partie d'une séquence de contrôle SGR qui définit les couleurs actuelles de premier plan et d'arrière-plan)

Bien sûr, une lecture attentive de votre question révèle que vous agitez à nouveau une banane enrobée de chocolat dans ces systèmes monétaires européens. Ce que vous essayez réellement de faire, pour lequel vous avez sélectionné une solution puis demandé comment faire une partie de cette solution, est de conserver l'état précédent pendant que vous écrivez une sortie colorisée. Non seulement il y a une séquence de contrôle DEC VT pour ce faire, mais il y a une séquence de terminaux de console SCO qui est reconnue par xtermet divers émulateurs de terminaux intégrés au noyau, et une entrée termcap / terminfo qui vous indique ce qu'ils sont pour votre terminal.

Les entrées termcap sont scet rc. Les entrées terminfo sont save_cursoret restore_cursor. Les noms sont quelque peu trompeurs quant à leur effet (bien qu'ils agissent comme un avertissement que vous comptez sur quelque chose qui est de facto plutôt que de jure ). Les séquences de contrôle DECSC, DECRC, SCOSC et SCORC réelles enregistrent et restaurent également le rendu graphique actuel.

Étant donné que l'article que vous avez souligné concerne la génération de séquences de contrôle à partir de scripts shell, la commande que vous recherchez maintenant l' est tput.

Lectures complémentaires

JdeBP
la source
Très bonne réponse. Heureux que j'y sois retourné. Merci beaucoup.
Minix
@Minix - outre scet rc, vous voudrez peut-être également examiner le tampon alternatif si votre terminal le prend en charge. Et oui, c'est une excellente réponse. Minix, regardez peut-être aussi ceci: comment utiliser / dev / fb0 comme console depuis l'espace utilisateur . La noshsuite qu'il recommande est la sienne.
mikeserv
@mikeserv Je vais jeter un oeil, merci pour les liens :)
Minix
2
Remarqué que "n'a aucun rapport avec ceux utilisés par xterm" - cependant, DECRQSS a pris en charge DECRQSS pendant un certain temps. La partie avec réponse SGR incluant les dates de couleur jusqu'en 1996.
Thomas Dickey
2
Voir Lectures complémentaires , dans la documentation des séquences de contrôle de xterm, qui souligne que la documentation VT520 / etc n'était pas disponible lorsque xterm a commencé à fournir des couleurs DECRQSS(environ 7 ans de retard ...).
Thomas Dickey
10

Dans un, xtermvous pouvez obtenir les codes de couleur RVB de couleur actuels signalés en modifiant un changement de couleur d'échappement à une requête. Utilisez le ESC ] Ps m- mais ajoutez un ?point d'interrogation. De la documentation :

  • Si un "?"est donné plutôt qu'un nom ou une spécification RVB, xtermrépond avec une séquence de contrôle de la même forme qui peut être utilisée pour définir la couleur dynamique correspondante. Étant donné que plusieurs paires de numéros de couleur et de spécifications peuvent être fournies dans une même séquence de contrôle, xtermplusieurs réponses peuvent être apportées .
    • P s = 1 0 → Remplacer la couleur de premier plan du texte VT100 par P t.
    • P s = 1 1 → Changer la couleur d'arrière-plan du texte du VT100 en P t.
    • P s = 1 2 → Changer la couleur du curseur de texte en P t.
    • P s = 1 3 → Changer la couleur de premier plan de la souris en P t.
    • P s = 1 4 → Changer la couleur d'arrière-plan de la souris en P t.
    • P s = 1 5 → Changer la couleur de premier plan de Tektronix en P t.
    • P s = 1 6 → Changer la couleur de fond de Tektronix en P t.
    • P s = 1 7 → Changer la couleur de fond de surbrillance en P t.
    • P s = 1 8 → Changer la couleur du curseur Tektronix en P t.
    • P s = 1 9 → Remplacer la couleur de premier plan en surbrillance par P t.

J'ai de sérieux doutes si cela est susceptible de fonctionner dans un autre émulateur de terminal, mais dans un xtermsi vous exécutez ...

printf '\033]11;?\007'

... le xtermrepoussera dans le tampon d'entrée de votre terminal une séquence comme celle-ci ...

11;rgb:ffff/ffff/ffff

... pour le fond ou pour le premier plan:

printf '\033]10;?\007'

10;rgb:0000/0000/0000
mikeserv
la source
Ainsi, lorsque je cours printf '\033]10;rgb:8f8f/8f8f/8f8f8f\007, tout le texte du terminal qui était auparavant "normal" devient bleu clair. Par la suite, l'exécution printf '\033]10;rgb:bfbfbf/bfbfbf/bfbfbf\007'ramène tout le texte bleu clair à "normal". Comment utiliser cette valeur pour modifier uniquement la couleur du texte à l'avenir?
fourpastmidnight
@fourpastmidnight: peut-être d' clearabord?
mikeserv
Je pense que je ne comprends pas la documentation. Il dit clairement "P s = 1 0 -> changer la couleur de premier plan du VT100", et bien, c'est ce qu'il semble faire. ;) Mais ce n'est pas ce à quoi je m'attendais. Je pourrais avoir besoin d'utiliser la valeur RVB extraite de "P s = 1 0; Pt =?" avec une autre commande échappée pour réaliser ce que je veux.
fourpastmidnight
Ok, donc printf '\033]10;?\007'demande à xterm la couleur de premier plan actuelle du terminal. Si votre terminal a été démarré avec "normal" (par exemple 7 comme couleur de premier plan), mais que vous exécutez tput setaf 3avant d'exécuter la printfcommande, la printfcommande ci-dessus renvoie toujours "normal" - et c'est vrai, car c'est la couleur de premier plan actuelle de votre terminal. Ce que j'espérais, c'était un moyen de récupérer la couleur actuelle de la position actuelle du curseur afin de pouvoir l'enregistrer pour la "restaurer" plus tard - conformément à l'OP.
fourpastmidnight
1
@fourpastmidnight - avez-vous suivi le lien dans la réponse ici? aussi, Thomas Dickey - (il a commenté l'autre réponse à cette question) est xtermle mainteneur et est un membre actif ici. (le lien est vers son site Web - xtermles documents d'échappement de sont nombreux - et, fondamentalement, la référence standard pour tout autre programmeur souhaitant écrire un terminal)
mikeserv