lkubuntu

A listing of random software, tips, tweaks, hacks, and tutorials I made for Ubuntu

Injecting code into running process with linux-inject

I was about to title this “Injecting code, for fun and profit”, until I realized that this may give a different sense than I originally intended… :P

I won’t cover the reasons behind doing such, because I’m pretty sure that if you landed on this article, you would already have a pretty good sense of why you want to do this …. for fun, profit, or both ;)

Anyway, after trying various programs and reading on how to do it manually (not easy!), I came across linux-inject, a program that injects a .so into a running application, similar to how LD_PRELOAD works, except that it can be done while a program is running… and it also doesn’t actually replace any functions either (but see the P.S. at the bottom of this post for a way to do that). In other words, maybe ignore the LD_PRELOAD simile :P

The documentation of it (and a few other programs I tried) was pretty lacking though. And for good reason, the developers probably expect that most users who would be using these kinds of programs wouldn’t be newbies in this field, and would know exactly what to do. Sadly, however, I am not part of this target audience :P It took me a rather long time to figure out what to do, so in hopes that it may help someone else, I’m writing this post! :D

Let’s start by quickly cloning and building it:

git clone https://github.com/gaffe23/linux-inject.git
cd linux-inject
make

Once that’s done, let’s try the sample example bundled in with the program. Open another terminal (so that you have two free ones), cd to the directory you cloned linux-inject to (e.g. cd ~/workspace/linux-inject), and run ./sample-target.

Back in the first terminal, run sudo ./inject -n sample-target sample-library.so

What this does is that it injects the library sample-library.so to a process by the -name of sample-target. If instead, you want to choose your victim target by their PID, simply use the -p option instead of -n.

But … this might or might not work. Since Linux 3.4, there’s a security module named Yama that can disable ptrace-based code injections (or code injections period, I doubt there is any other way). To allow this to work, you’ll have to run either one of these commands (I prefer the second, for security reasons):

echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope # Allows any process to inject code into any other process started by the same user. Root can access all processes
echo 2 | sudo tee /proc/sys/kernel/yama/ptrace_scope # Only allows root to inject code

Try it again, and you will hopefully see “I just got loaded” in-between the “sleeping…” messages.

Before I get to the part about writing your own code to inject, I have to warn you: Some applications (such as VLC) will segfault if you inject code into them (via linux-inject, I don’t know about other programs, this is the first injection program that I managed to get working, period :P). Make sure that you are okay with the possibility of the program crashing when you inject the code.

With that (possibly ominous) warning out of the way, let’s get to writing some code!

#include <stdio.h>

__attribute__((constructor))
void hello() {
    puts("Hello world!");
}

If you know C, most of this should be pretty easy to understand. The part that confused me was __attribute__((constructor)). All this does is that it says to run this function as soon as the library is loaded. In other words, this is the function that will be run when the code is injected. As you may imagine, the name of the function (in this case, hello) can be whatever you wish.

Compiling is pretty straightforward, nothing out of the ordinary required:

gcc -shared -fPIC -o libhello.so hello.c

Assuming that sample-target is running, let’s try it!

sudo ./inject -n sample-target libhello.so

Amongst the wall of “sleeping…”, you should see “Hello world!” pop up!

There’s a problem with this though: the code interrupts the program flow. If you try looping puts("Hello world!");, it will continually print “Hello world!” (as expected), but the main program will not resume until the injected library has finished running. In other words, you will not see “sleeping…” pop up.

The answer is to run it in a separate thread! So if you change the code to this …

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

void* thread(void* a) {
    while (1) {
        puts("Hello world!");
        usleep(1000000);
    }
    return NULL;
}

__attribute__((constructor))
void hello() {
    pthread_t t;
    pthread_create(&t, NULL, thread, NULL);
}

… it should work, right? Not if you inject it to sample-target. sample-target is not linked to libpthread, and therefore, any function that uses pthread functions will simply not work. Of course, if you link it to libpthread (by adding -lpthread to the linking arguments), it will work fine.

However, let’s keep it as-is, and instead, use a function that linux-inject depends on: __libc_dlopen_mode(). Why not dlopen()? dlopen() requires the program to be linked to libdl, while __libc_dlopen_mode() is included in the standard C library! (glibc’s version of it, anyways)

Here’s the code:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <dlfcn.h>

/* Forward declare these functions */
void* __libc_dlopen_mode(const char*, int);
void* __libc_dlsym(void*, const char*);
int   __libc_dlclose(void*);

void* thread(void* a) {
    while (1) {
        puts("Hello world!");
        usleep(1000000);
    }
}

__attribute__((constructor))
void hello() {
    /* Note libpthread.so.0. For some reason,
       using the symbolic link (libpthread.so) will not work */
    void* pthread_lib = __libc_dlopen_mode("libpthread.so.0", RTLD_LAZY);
    int(*pthread_lib_create)(void*,void*,void*(*)(void*),void*);
    pthread_t t;

    *(void**)(&pthread_lib_create) = __libc_dlsym(pthread_lib, "pthread_create");
    pthread_lib_create(&t, NULL, thread, NULL);

    __libc_dlclose(pthread_lib);
}

If you haven’t used the dl* functions before, this code probably looks absolutely crazy. I would try to explain it, but the man pages are quite readable, and do a way better job of explaining than I could ever hope to try.

And on that note, you should (hopefully) be well off to injecting your own code into other processes!

If anything doesn’t make sense, or you need help, or just even to give a thank you (they are really appreciated!!), feel more than free to leave a comment or send me an email! :D And if you enjoy using linux-inject, make sure to thank the author of it as well!!

P.S. What if you want to change a function inside the host process? This tutorial was getting a little long, so instead, I’ll leave you with this: http://www.ars-informatica.com/Root/Code/2010_04_18/LinuxPTrace.aspx and specifically http://www.ars-informatica.com/Root/Code/2010_04_18/Examples/linkerex.c . I’ll try to make a tutorial on this later if someone wants :)

How to remove the annoying YouTube lightsaber sound

Google pulled off a clever marketing stunt for Star Wars, allowing you to “choose your side of the force” – which consequently changes various Google products to fit the theme accordingly.

One change they introduced added lightsaber sound effects when you hover over the volume icon on a Youtube video. While being a cute gimmick, I found this to be quite annoying, especially when listening to music, so I spent the morning trying to make a small script that would disable it.

I thought I would share it, since I’m guessing there are others who also find this annoying

It works most of the time, but if you hover over the volume icon before the script has a chance to run, the sound will still happen. Just wait a second or two, and it will work :) Also, if you just installed the extension, you will need to reload the page.

I uploaded a unified codebase to github, mainly since I didn’t like constantly having to copy files from/to various codebases :P Here it is, if anyone’s interested: https://github.com/MiJyn/youtube-no-lightsaber

My tmux configuration

Since I generally work on tty’s (X barely works on my machine), I need a sort of multiplexer in order to run more than one thing at once. I have nothing against GNU Screen, but I use tmux since I have a sort of vague understanding of how it works, and so far, it has been able to handle basically everything I want.

My configuration used to simply be to change the prefix to something other than ctrl+b (since I use emacs), but a few days ago, I decided to make it look slightly prettier to me (it was actually the reason I wrote tlock yesterday :) ).

Here is a screenshot: (sorry, the dots at the bottom weren’t aligned properly, I fixed it in the post)

tmux

It’s a bit difficult to see, but the second dot (window) is amber, which indicates a bell in that window. Not the nicest color, but I was using a modified version of it for my root accont, which uses red (instead of green), so I didn’t want any confusion. But, of course, this is really easy to change :)

I’ve also changed a few keyboard shortcuts to better accomodate my workflow (such as emacs keys — ctrl+[fbnp] — to access panes, and h/v to create split windows).

Anyways, without further ado, here it is:

### Options ###

set -g base-index 1
set -g renumber-windows on

unbind C-b
set -g prefix 'C-z'
bind 'C-z' send-prefix

bind C-b select-pane -L
bind C-f select-pane -R
bind C-p select-pane -U
bind C-n select-pane -D

bind v split-window -v
bind h split-window -h

bind r source-file ~/.tmux.conf

set -g lock-command ~/.tlock.sh # this script contains the wrapper script mentioned in https://lkubuntu.wordpress.com/2015/09/25/tlock-simple-but-slightly-prettier-alternative-to-vlock/
bind l lock

setw -g monitor-activity on


### Appearance ###

set -g status-fg white
set -g status-bg default

set -g window-status-format " •"
set -g window-status-current-format " •"

set -g window-status-fg white
set -g window-status-bg default
set -g window-status-activity-fg white
set -g window-status-activity-bg default
set -g window-status-current-fg green
set -g window-status-current-bg default
set -g window-status-bell-fg yellow
set -g window-status-bell-bg default

set -g window-status-attr default
set -g window-status-activity-attr none
set -g window-status-current-attr default
set -g window-status-bell-attr default

set -g pane-active-border-fg green
set -g pane-active-border-bg default

set -g status-left "     " # padding to make up for status-right
set -g status-right "%H:%M"
set -g status-justify centre

I have the clock beside, since I use the tty, and often lose track of time :P

I personally put this in /etc/tmux.conf, then in both my main account, and the root account, I write a sort of “wrapper” tmux.conf along the lines of this: (this is what I wrote for my root account)

source-file /etc/tmux.conf

set -g window-status-current-fg red
set -g pane-active-border-fg red

You can also just use it as-is, without any problems :)

It’s very simple, but I personally really like it. Let me know if you have any ideas for it, or if you enjoy it, or anything else! ^^

tlock – Simple, but slightly prettier alternative to vlock

Admittedly, the title might seem a bit weird. I mean, it might as well say “Simple, but slightly prettier alternative to cat”. I’m still not sure how that would work (ascii boxes??) XD

So what makes this both simpler, and prettier than vlock? Well, you could try it out for yourself!! But … then this post would be entirely useless :P However, if you wish to try it out for yourself, before reading the rest, don’t let me stop you!

Anyways, let’s go back to the second paragraph. It has less features than vlock (yes, it’s possible!), and security-wise, it’s definitely not up-to-par. I’m certainly not against a bit of extra security, but it works fine for me now, so until someone needs the extra features, I will probably leave it as-is (but if you see my laptop, remember, it’s most certainly running a security-enhanced version of it … don’t touch it, you don’t want to know what will happen :P ). Second, yes, it’s prettier. Not that it’s specifically difficult to beat vlock in this aspect, but, yes, it is pretty XD

Here is how it looks like normally (if you’re wondering, it’s “password” … and if you’re also wondering, no =p)

tlock_ugly

But you can configure how both look, via environmental variables (TL_USERNAME and TL_PASS_CHAR). Here’s a slightly customized version:

tlock_nice

Trust me, if you run this on a tty, with ter-112n (smallest font size of terminus — excellent coding font!), it will look amazingly slick :D (at least, in my biased opinion, it does!). There’s very little in this world that spells “awesome” better than root with red letters, with red dots below, surrounded by a vast array of blackness XD

So how do you install this thing? Clone the git repo, build, and install. It’s important that you install, since the application requires setuid privileges to check your password. Or you could just sudo chown root tlock;sudo chmod u+s tlock too. For copy&paste convenience:

git clone https://github.com/MiJyn/tlock.git
cd tlock
mkdir build
cd build
cmake ..
make
sudo make install # or sudo chown root src/tlock; sudo chmod u+s src/tlock

Now that it’s built/installed, all you need to do to run it is, quite simply, run it. It will automatically detect your username, and will hopefully work exactly as planned. However, if you want it to customize it a bit, here’s what I wrote for a wrapper script: (change to your liking :) )

export TL_USERNAME="`echo -e '\e[32m'`MiJyn`echo -e '\e[0m'`"
export TL_PASS_CHAR="`echo -e '\e[32m'` •`echo -e '\e[0m'`"
tlock

It just uses standard ANSI escape sequences for the colors, see here: http://ascii-table.com/ansi-escape-sequences.php

Let me know if you have any issues, or feature requests, or anything else! I’m not particularly invested in this project (since it is such a simple one), but I would be glad to help if anyone needs something for this :D

Collaborative Track Idea

I really, really want to make open-source music. Or rather, open-source musical projects. Software is never truly finished… and neither is music. It’s difficult to do it though, since the way music is written now, it’s very difficult to make a highly open collaborative environment. I want to change this (and I’ve been working on this in various areas for about 2 years), but, that’s for another post.

This post is actually for a step down from this idea. It’s not open-source, since I don’t think I can legally share the samples or plugins or anything else required. My DAW and plugins are sadly not open-source (let alone libre) either, so I don’t know what the project file has contained, and therefore, I don’t think I can share that either. The track will be released under a CC license though (I’m thinking BY-SA).

However, it’s still the same sort of idea in concept. It’s the idea of people working together and sharing ideas in order to make a track, and one person, the lead artist, implementing the ideas (and, of course, everyone gets credited fully for the work they did). Though I am suggesting this for one of my own tracks, I would personally love to work on an environment like this, for other musicians as the lead artist (in fact, I would probably prefer this, since I’m not very good myself).

My idea is to create this track in this manner, and hopefully inspire other musicians to do the same.

What I have so far of the track is here (the description contains basically the same information as provided in this post) … and no, don’t worry, it won’t be about ponies XD For now, it’s a remake of a MLP-themed track I did 2 years ago, but it will be its own track, entirely separate from ponies (though still musically inspired from the first track):

Why Openlux instead of Redshift?

First, I want to clarify that this is not a post trying to show that one is better than the other unequivocally. This is, instead, a post trying to show my reasons for writing openlux, and the differences between both softwares. I’m sure that many people will prefer the way that redshift works, over the way that openlux works, and that’s awesome!! The purpose of this post is, mainly, to show the differences, and hopefully help you decide which is better for your circumstance :)

My initial reason for writing openlux was because f.lux didn’t work for me, for various reasons (as I outlined in the first post about it) … I was actually unaware of redshift. There were a few people who linked me to it, and I immediately felt slightly disappointed that I hadn’t done my research before (would have saved me quite a bit of work!). Looking into it though, it’s not what I was looking for, and it has some of the issues that made me switch away from f.lux.

Redshift’s mode of operation is different than openlux’s. It primarily functions as a daemon, changing the color temperature automagically, depending on your timezone. This is a really handy feature, however, you don’t have much ability to configure the times. If you don’t have insomnia, and have a regular sleeping schedule, this is probably perfect. You tell it where you live, and it will change the screen color temperature throughout the day, in order to match the light you would receive if you were outside at that time (except at night, of course =P). But in my case, I can stay up until 4-5am, unable to sleep at all. Having the screen automatically change to a higher color temperature when I’m trying to go to sleep is most definitely not what I need. Now I could change the timezone every so often, but I’d rather have something in which I control when the screen color changes, instead of having to work against the program. I am aware that redshift has an option for manually changing the color temperature, but you don’t have much control over other options (such as animating to it, or individual control over RGB channels).

Redshift also uses color tables in order to compute the RGB values from kelvin temperatures. This allows for maximum accuracy within the range it provides (1000-25100K), however, it doesn’t allow anything outside of the range. On the other hand, openlux, works using Tanner Helland‘s algorithm, which allows for a theoretically infinite (practically 0-232, because it’s stored in a 32-bit integer), but less accurate result. Personally, I prefer using an algorithm, but there are definitely things to say about using a color table instead. The algorithm is pretty accurate (I think it’s a maximum of ~3-5% off of the original value), but if you’re within the range that redshift provides, it’s always nice to have 100% accuracy!

The main philosophical difference (that influences how the programs evolve) between redshift and openlux is the goal: redshift is more oriented towards being a standalone, fully-featured program, while openlux is oriented towards being a program that only does one task (change the screen color temperature), and focuses on that one task. It leaves tasks such as changing the color temperature in accordance with the timezone to other programs specialized for this (such as cron), or manually. Redshift tends to go more on the side of “run it, and forget about it”, while openlux leans more on giving the user maximum control and flexibility.

There’s definitely something to be said about both philosophies, and different users will appreciate different philosophies. I personally prefer the one of having full control at all times, but there are many users who would prefer to just have the program manage it for them automagically.

If you’re not sure which to use, try both! See which one works best for you. After all, GNU/Linux is all about choice :)

If I’ve made any mistake in this article, please let me know. This post is most definitely not about saying that one software is better than the other. While I, of course, prefer openlux, I want this to be a fair comparison of both softwares, so that users can better decide which software they want to use for themselves.

Openlux 0.2 beta – Animations, iOS port

I wrote openlux around 2 and a half weeks ago, as a simple, libre alternative to f.lux that addresses a few issues I’ve encountered with it. I’ve since used it everyday, and I’ve actually noticed an improvement in my sleep!

However, my iPad still uses f.lux (or, until today, at least). No, in this case, I’m not worried about the fact that f.lux is proprietary (it’s an iPad), but earlier, when my sleep was really messed up (and by messed up, I mean, I was going to sleep at 7-8am), f.lux would automatically switch to 3400K (instead of 2300K), which definitely didn’t have a positive impact on my sleep. Also, it only goes down to 2300K, doesn’t allow much customizability, and doesn’t always work how I want it to work, etc.

So after spending quite a long time (basically ever since I released the first version of openlux) working on the port, it finally works!!! It doesn’t work as well as I wanted it to (multiple colors output the same value, compressing the color range … I tried lerping values, but it ended up giving garbage), but at least it works!

Animations literally took about the last hour of developing this version (in other words, barely any time at all, compared to the time needed to develop the iOS port), since, luckily, I only encountered one bug while making it. The point of animations is not for visual bling, but rather to make it easier on the eyes if it’s run automatically (e.g. via cron).

Other than those, there are a few minor features, such as optional relative adjustment of colors (“-b 10” will set the blue channel to 10, “-b +10” will add 10 to the blue channel, and “-b -10” will remove 10), and saving/resetting gamma values (mainly just a by-product of working on the iOS port).

If anyone would be interested in testing this on their iDevices, I would really appreciate it ^^ Though it works fine on my 1st generation iPad, I don’t know if it will work on other devices too. I wrote instructions on how to compile and run it here: https://github.com/MiJyn/openlux/wiki/Compiling-for-iOS :) I’m not aware of this being able to cause any permanent damage to your device (my device works fine now, even after the display being severely messed up multiple times), but if you’re scared, stick with f.lux for now. Quick note: it doesn’t work on iOS <4, since it needs to retrieve the gamma table (which iOS versions <4 don’t support).

To wrap up, here’s a few examples of the new features that come with openlux 0.2:

openlux -k 1000 -a 10000         # Animates to 1000K in 10 seconds (10000 milliseconds)
openlux -k 1000 -a 100000 -d 100 # Animates to 1000K in 100 seconds, with a delay of 100 milliseconds per "frame" (less CPU usage)
openlux -k 1000 -g +10           # Sets the color temperature to 1000K, but adds 10 to the green channel
openlux -R                       # Resets to the last saved gamma table (openlux automatically saves the gamma table the first time it's run per boot)
openlux -s                       # Saves the gamma table

Follow up on the non-windowing display server idea

Note: I’m sorry, this post is a bit of a mess.

I wrote a post 2 days ago, outlining an idea for a non-windowing display server — a layer that wayland compositors (or other programs) could be built upon. It got quite a bit more attention than I expected, and there were many responses to the idea.

Before I go on, I wish to address a few things that weren’t clear in the original post:

The first being that I am not an ubuntu developer, and am in no way associated with canonical. I am only an ubuntu member :) Even though I don’t use ubuntu personally, I wish to improve the user experience of those who do.

Second is a point that I did not address clearly in the original post: One of the main reasons for this idea is to enable users to modify the video resolution, gamma ramp, orientation, brightness, etc. DRM provides an API for doing these operations, however, AFAIK, you cannot run modesetting operations on a virtual terminal that is already running an application that has called video modesetting operations. In other words, you cannot run a DRM-based application on an already-running wayland server in order to run a modesetting operation. So, AFAIK, the only way to enable an application to do this is to write a sort of “proxy” server that handles requests, and then runs the video modesetting operations.

Since I am currently confusing myself re-reading this, I’ll try to provide a diagram in order to explain what I mean.

If you want to change the gamma ramp, for example, this is impossible:

drm_client_wayland

So with the display server acting as a proxy of sorts, it becomes possible:

drm_client_display_server

This is also why I believe that having a server over a shared library is crucial. A shared library would allow for abstraction over multiple backends, however, it doesn’t allow communication with more than one application. A wayland compositor can access all of the functions, yes, but wayland clients cannot.

The third clarification is that this is not only meant for wayland. Though this is the main “client” I have in mind for this server, it isn’t restricted to only wayland. The idea is that it could be used by anything, for example, as one response pointed out, xen virtualization. Or, in my case, I actually want to write clients that use this server directly, without even using a windowing server like wayland (yes, I actually have a good reason for wanting this XD ). In other words, though I believe that the group that would use this the most would be wayland users (hence why I wrote the original post tailored towards this), it isn’t only meant for wayland.

There were a few responses saying that wayland intentionally doesn’t support this, not because of the reason I originally suspected (it being “only” a windowing protocol), but because one of wayland’s main goals is to let the compositor to have full control over the display, and make sure that there are no flickers or tearing etc., which changing the video resolution (or some other modesetting operations) would undoubtedly cause. I understand and respect this, however, I still want to be able to change the resolution or gamma ramp (etc.) myself, and suffer the consequences of the momentary flickering or whatever else. Again though, I respect wayland’s decision in this aspect, so my proposal, instead, is this: To make this an optional backend for wayland compositors. Instead of my original proposal, which was to build wayland compositors on top of this (in order to help simplify the stack), instead, have this as an option, so that if users wish to have the video modesetting (etc.) capabilities, they can use this backend instead.

A pretty large concern that many people (including myself) have is performance. Having an extra server on the stack would definitely have an impact on performance, but the question is how much.

So with this being said, going forwards, I am currently working on implementing a proof-of-concept prototype in order to have a better sense of what it entails, especially in regards to performance. The prototype will be anything but production-ready, but hopefully will at least work … maybe XD .

Idea: Non-windowing display server

For the TL;DR folk who are concerned with the title: It’s not an alternative to wayland or X11. It’s layer that wayland compositors (or other) can use.

As a quick foreward: I’m still a newbie at this field. While I try my best to avoid inaccuracies, there might be a few things I state here that are wrong, feel free to correct me!

Wayland is mainly a windowing protocol. It allows clients to draw windows (or, as the wayland documentation puts it, “surfaces”), and receive input from those surfaces. A wayland server (or “compositor”) has the task of drawing these surfaces, and providing the input to the clients. That is the specification.

However, where does a compositor draw these surfaces to? How does the compositor receive input? It has to provide many backends for various methods of drawing the composited surface. For example, the weston compositor has support for drawing the composited surface using 7 different backends (DRM, Linux Framebuffer, Headless [a fake rendering device], RDP, Raspberry Pi, Wayland, and X11). The amount of work put into making these backends work must be incredible, which is exactly where the problem relies in: it’s arguably too much work for a developer to put in if they want to make a new compositor.

That’s not the only issue though. Another big problem is that there is then no standard way to configure the display. Say you wanted a wayland compositor to change the video resolution to 800×600. The only way to do that is to use a compositor-specific extension to the protocol, since the protocol, AFAIK, has no method for changing the video resolution — and rightfully so. Wayland is a windowing protocol, not a display protocol.

My idea is to create a display server that doesn’t handle windowing. It handles display-related things, such as drawing pixels on the screen, changing video mode, etc… Wayland compositors and other programs that require direct access to the screen could then use this server and trust that the server will take care of everything display-related for them.

I believe that this would enable for much simpler code, and add a good deal more power and flexibility.

To give a more graphic description (forgive my horrible diagraming skills):

Current Stack:

wayland_current

Proposed Stack:

 

wayland_new

I didn’t talk about the input server, but it’s the same idea as the display server: Have a server dedicated to providing input. Of course, if the display server uses something like SDL as the backend, it may have to also provide the input server, due to the SDL library, AFAIK, doesn’t allow a program to access the input of another program.

This is an idea I have toyed around with for some time now (ever since I tried writing my own wayland compositor, in fact! XD), so I’m curious as to what people think of it. I would be more than happy to work with others to implement this.

Using Openlux to help your sleep and/or relax your eyes

If you are familiar with research suggesting that blue light affects your sleep, you might also be familiar with a (free!) software named f.lux. I use it on my iDevices (used to use it on my computers too), and it works great …. except for a few issues.

The first is CPU consumption. Seriously, this software takes up a lot of CPU. That was the main reason behind ditching xflux (the X11 edition of the software). It also doesn’t entirely block out blue light, even at the lowest color temperature it allows (this is true for the iOS version too). There were a number of other issues that became annoying over time (forced very long animations, a daemon that rarely ever works as intended, sometimes the software doesn’t even work at all, mouse cursor being left entirely out of the picture, etc.). These would (probably) all be simple to fix …. however, it’s free as in price, not as in freedom. The software is closed-source.

Openlux is a very simple open-source MIT-licensed clone I wrote that tries to address these issues (minus the mouse cursor issue, that one is a bit more complex). For now, it doesn’t contain as many features as xflux does, but it is only a first release. Animations and the lot will come later :)

I haven’t worked on packaging yet (if anyone wishes to spend some time doing this, that would be greatly appreciated!!), but for now, visit https://github.com/MiJyn/openlux for download and compilation information (sorry for the mess in main.c, I will get to that later!).

Here are a few usage examples

openlux                      # Sets the screen color temperature to 3400K (the default)
openlux -k 1000              # Sets the color temperature to 1000K
openlux -k 2000 -b 0         # Sets color temperature to 2000K, but removes all blue light
openlux -k 2000 -b 255       # Ditto, but blue is set to 255 (maximum value, gives the screen a magenta-ish tone)
openlux -r 130 -g 150 -b 100 # Gives the screen a dark swamp green tint (Kelvin value is ignored)
openlux -k 40000             # Sets the screen color temperature to 40000K
openlux -i                   # Resets the screen color temperature

I personally like using openlux -k 10000 during the day (very relaxing for the eyes!), and openlux -k 2300 -b 40 during the night.

I hope this can be useful for you!! If you have any issues, suggestions, feedback, etc. (even if you just want to say thank-you — those are always appreciated ^^), feel free to write a comment or send me an email!

Follow

Get every new post delivered to your Inbox.

Join 182 other followers