Thread: Let's help MutantJohn modify a terminal emulator...

  1. #1
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013

    Let's help MutantJohn modify a terminal emulator...

    Hello All,

    Now, this is something waaaay less math-y than anything I've ever thought that I wanted to do.

    But here's what I want :

    Let's say we have a terminal emulator. Let's just say it's terminator (doesn't have to be), for the sake of argument.

    What I wanna do is, I wanna modify the code and change the color of the text. What do I mean specifically? Right now I have the green text on black background setting. It's a classic terminal scheme.

    But what I want to make happen is, I want the text to follow a color gradient so it'll be like a "rainbow" terminal emulator.

    So my question is, what do I need to know to make this happen? Does anyone have any good links to reading material about this? I tried googling around and it seems like articles are scarce though there are a few people out there like me, it would seem.

  2. #2
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    United States
    Or PDcurses if your platform doesn't support ncurses.

  4. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    But what I want to make happen is, I want the text to follow a color gradient so it'll be like a "rainbow" terminal emulator.

    I don't think you'll find many terminals that offer gradients within a single glyph.

    Anyway, "curses" "lives" in the application. If you want "rainbow text" for anything, such as your prompt, you'll have to work in the "vte" using "Cairo" or whatever other libraries are appropriate.

    Or implement a "vte" layer in "curses". I don't think I've seen that.

    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  5. #5
    Unregistered User Yarin's Avatar
    Join Date
    Jul 2007
    Your title and actual question are two very different things

  6. #6
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Are they? Oh man, see how out of my element I am? I willl look up ncurses and everything else mentioned though

  7. #7
    Ticked and off
    Join Date
    Oct 2011
    La-la land
    This thread belongs to the Linux board, not the Tech board, btw.

    Assuming you use Ubuntu: terminator uses python-vte and thus libvte9 to display the GTK+-2.0 terminal widget. I prefer to use xfce4-terminal, but it too uses libvte9.

    So, change to a directory you use for rebuilding package sources, and obtain the sources and development prerequisites for the libvte9 package:
    sudo apt-get source libvte9
    sudo apt-get source equivs
    sudo mk-build-deps -i -r libvte9
    The interesting part is in the src/vtedraw.c:_vte_draw_text_internal() function; it's used to draw each glyph in the virtual terminal emulator widget. Within the for loop, requests[i].x and requests[i].y refer to the upper left corner of the glyph. Although draw->widget does refer to the GtkWidget (and therefore you could use it to obtain the widget on-screen size), I'd personally just extend the struct _vte_draw structure to include the current width and height of the widget, and update those in the relevant functions -- for efficiency sake; I bet that would be the approach the upstream developers would take, if they had the need. (In fact, requesting the widget size at _vte_draw_start() for the draw_started == 0 case only should suffice just fine.)

    As a simplified example, you can add the following line at the beginning of the for loop in src/vtedraw.c:_vte_draw_text_internal() :
    		cairo_set_source_rgba (draw->cr,
    			               (double)(requests[i].y & 255) / 255.0,
    			               color->green / 65535.,
    			               color->blue / 65535.,
    			               alpha / 255.);
    This will cause the red component of each glyph do depend on the y coordinate of the top of the glyph, repeating every 256 pixel rows. Not a rainbow, but an example change, anyway.

    Next, edit debian/changelog, adding a new changelog entry at the top to describe the changes. Be sure to use the same tab/space indentation and formatting; it is consumed by scripts. Also, remember to update the version number, too, because it determines the package version.

    Next, run
    fakeroot debian/rules binary
    to build the binary packages, and after that completes,
    sudo dpkg -i ../libvte9_*.deb ../libvte9-common_*.deb
    to install the changed packages. Any new Terminator terminal you open, will show the modified behaviour. (Already running Terminators' behaviour won't change, so just opening a new window is not enough. Some terminals use a single "master process" per user to handle all windows, so you may need to close all terminals to see the change.)

    To revert to upstream version, you can use your package manager. I personally prefer to build the original unmodified binaries first, so I can just run the above sudo dpkg -i command to downgrade back to the official versions. (Or you can download the binary packages files from the architecture-specific links at the libvte9 package page; left side, near the bottom.)

    Finally, such a change overrides theming. To add proper, full support for glyph color manipulation -- say, specifying any number of color spots within positive unit quadrant in 2D ((0,0)-(1,1)), and interpolating the color for each glyph based on those, would need updates to libvte9, python-vte, and terminator, so that terminator could pass the entire "foreground color list" to python-vte, which would parse it into color-points, update the libvte structures correspondingly (probably via new accessor functions), and so on down to the location above where we modified the code (where a helper function would take draw and request[i] to determine the glyph location relative to the window, and calculate the suitable code, and set it to the Cairo context draw->cr.

    Alternatively, you could convert the colors from RGB to say HSL or HSV, and only manipulate the saturation and/or hue. This would let the themes still work, as long as the manipulations are not too strong. (Use floating-point math to do it. Although it is done once per glyph, it isn't slow enough to really affect the terminal performance, really.) You'd only need to add the options for enabling/disabling/controlling this effect.

    The major work to get this available for everybody, would be convincing the upstream developers that this is a desirable feature, no matter how clean and nice the modifications are. Compared to that, the code changes are, dare I say it, trivial.

  8. #8
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Hey, thanks, Nominal

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 08-28-2011, 09:01 PM
  2. Console, Terminal and Terminal Emulator
    By lehe in forum C Programming
    Replies: 4
    Last Post: 02-15-2009, 09:59 PM
  3. terminal emulator issue - FreeBSD
    By olbas in forum Linux Programming
    Replies: 1
    Last Post: 07-13-2004, 04:39 PM
  4. How do terminal emulator work?
    By Roaring_Tiger in forum C Programming
    Replies: 1
    Last Post: 04-15-2003, 08:20 PM
  5. TM emulator
    By iain in forum A Brief History of
    Replies: 5
    Last Post: 03-14-2002, 03:20 PM