11 years agoversion 0.2.0 v0.2.0
Mats Johannesson [Thu, 26 Jun 2008 18:13:37 +0000 (14:13 -0400)]
version 0.2.0
(NOTE: A version of this archive was pulled from the website after a
few hours of exposure on April 28, based on the suspicion that it
contained a corrupt file due to some file system issues on my machine.
Both fears were unfounded. I've spent this interim on further
restructuring of the text files outside of the code directories)

* New configuration file format. Incompatible with the old one, hence
the version bump from 0.1 to 0.2

Move/rename the old file and run the program to get a new. Then edit...

The old format was basically just a transcript of how a C structure
is initialized. It had nothing in common with how a configuration
file in *nix should be construed.

Rules for the new configuration file is: Blank lines and everything
after a "#" is discarded. Full program records begin and end with
a double percentage sign "%%". A program field begins after a colon ":".
The program names must be within two double quotes "". Like so:

"A ProgramName" <-- OK
" A ProgramName" or "A ProgramName " <-- NOT-OK

This is in accordance with the old rule about how to deal with spaces
in that field.

I can only vouch for parsing sanity if each line in the file is kept
below 160 bytes in length (see the BUGS file). That's the equiv of
two old style terminal lines. If you want more, change the MAXBUFFER
value in globals.h

* Another command line option: "-v". Will turn on the be_verbose flag
which prints info to the screen from plenty of program execution points.
An aid for debugging, or just checking out the runtime state.

* Got rid of the ugly switch routines in event_loop.c and config_read.c.
I've done extensive benchmarking and see no difference in code speed.
Advantage, apart from code simplicity, is that the compiled program
size was reduced by ca 4000 bytes - before the 0.2.0 additions.

11 years agoversion 0.1.4 v0.1.4
Mats Johannesson [Thu, 26 Jun 2008 18:06:46 +0000 (14:06 -0400)]
version 0.1.4
* Memory bugfix. Running the program under Valgrind to catch memory
leaks and other errors I finally saw the reason for me needing
heap_protect kludges. Doing XFreeDeviceList on a structure and then
reading data from the freed memory only works through luck...

* Took the opportunity to free lingering memory allocations at program
exit. It's not strictly necessary since the OS should reclaim it all,
but looks nice in the Valgrind summary. There's still one left that
I can't find the souce of. It belongs to XextCreateExtension apparently.

* Bugfix: Had forgotten to close the error.log after writing to it in
the exit_on_error function. Also, that function shouldn't do a final
exit(EXIT_KO) but instead jump to clean_up_exit(SIGTERM). However,
doing that it won't return the EXIT_KO to any parent. I'd have to
change the signal handling to achieve this.

* Bugfix: The config file version tag was meant to look like:

Version: 1

and nothing else, for now... The confusion and uncertainty stems from
doing this before a final format has been chosen. There are many factors
to consider, so bear with me.

* Reverted to the "expresskeys" base name on compile output and shell
files. When writing code it's more convenient with a short name, but
any final product should have a consistent naming.

11 years agoversion 0.1.3 v0.1.3
Mats Johannesson [Thu, 26 Jun 2008 17:50:51 +0000 (13:50 -0400)]
version 0.1.3
* Just internal code cleanup/restructuring after having begun reading
"The Art of Unix Programming" by Eric Steven Raymond:

* Now tags a new configuration file with a version number according to
his advice: "Always, _always_ either include a version number, or ...".
Expect more internal changes when I'm done reading. In an already
existing configuration file you'll have to add it manually. Put a:

Config File Version 1:

on a line by itself at the very top.

11 years agoversion 0.1.2 v0.1.2
Mats Johannesson [Thu, 26 Jun 2008 17:49:18 +0000 (13:49 -0400)]
version 0.1.2
* Signal handling in place. Not much in itself, but:

* Re-reads the configuration file upon receipt of the signal SIGUSR1.
Do a "kill -USR1 <pid-of-ekeys>" after a config file edit. That's USR
and the digit 1. I've also modified USR2 to do the same thing, for
now at least.

Included is a shell script called which does it for you
if ekeys is running in daemon mode. Also included is
which replaces the former (a bit smarter).

* The program will now refuse to start if it detects another instance
running. Only works if there is a pid-file to examine of course.
A pid-file left by a crash (will never happen...) and not connected
with any process by that number is ignored, and the program continues.

* A properly terminated program deletes the pid-file upon exit. Proper
means a normal "kill <pid>", "killall ekeys", "kill -TERM <pid>" etc.
Doing a brutal "kill -9 <pid>" or if the program crashes (cough, cough)
will leave the pid-file undeleted.

* Any error, encountered by the code, which terminates the program is
written to the file "error.log" as well as to the screen. A restart
truncates the file (it becomes size 0). This means that there always
will be an error.log present, but empty in normal cases.

11 years agoversion 0.1.1 v0.1.1
Mats Johannesson [Thu, 26 Jun 2008 15:29:14 +0000 (11:29 -0400)]
version 0.1.1
* Now reads an external configuration file at program launch. It
searches in the user home directory under the hidden "/.expresskeys"
directory. File is called "expresskeys.conf". If none is found, or
the directory doesn't exist yet, it makes the dir, then creates and
populates a minimal file from an internal list. The original "default",
"Gimp", "Blender" and "XTerm" entries. It then goes on and reads in
that file immediately. A limit of 64 different program definitions
has been set (easily altered in the code). It's way more than most
would need, since the "default" is fine for a huge group of programs.

Rules for the configuration file is: Don't use { or } in comments,
and preferably keep comments outside of program definitions. The
comma (,) inside a definition is still used to separate all the
fields. Program names don't need the embracing quotes "" but I
kept the default list using them. Since spaces are accepted as part
of a class name, make sure there are no space _before or after_ the
name, prior to the terminating field comma:

{"A ProgramName", or {A ProgramName,    <-- OK
{"A ProgramName" , or { A ProgramName,  <-- NOT-OK

The extra space/s would become part of the class name. Not what you want.
If you absolutely must put some space before the comma, use TAB instead.
Those are discarded while parsing the string.

* Pen handling is now specified on the command line, eg:

ekeys pad stylus

The value for pen mode switch in the configuration file is still 999.

Yes, "ekeys" :-) I changed the compile output to that name. The code
tarball will still be named expresskeys though. Doing a web search
revealed it to be rather unique to the Intuos3, while ekeys turned
up music hardware and relatives. But, naturally, feel free to name it
badzilla or VincentVanGogh instead. Program behaviour is not dependent
on the file name.

* Another command line change, to make it run in the background:

ekeys pad stylus -d

It then runs in "daemon" mode. The difference between pushing it
with a terminating & or letting internal code "fork" it is beyond
most peoples interest. I can already hear the snores building up...
But in terms of how I've coded stuff it still matters.

If the program is launched into daemon mode, it writes out another
file in the configuration directory: "". A
process identification (PID) is a unique number, separating the
program from all the other stuff you have running. The number can
be used, for example, to do an easy kill.

I've included a simple shell script (called which reads the and tries to kill whatever process that has the pid,
so do a "ps aux | grep ekeys" beforehand to be sure it's running
(and don't confuse your "grep ekeys" with an actual "ekeys" instance).
Add a line to start ekeys directly after a kill and you have an easy
path when doing config file changes. The pid file is not automatically
deleted by internal code on exit (yet).

* For any programmer out there, or curious user, I've now filled the
code with comments. It had to be done at some point...

11 years agoversion 0.1.0 v0.1.0
Mats Johannesson [Thu, 26 Jun 2008 14:31:46 +0000 (10:31 -0400)]
version 0.1.0
Just internal changes. A massive rewrite to get rid of cruft, and
put my own stink on the whole code structure. Ah yes, I then GPL-d
the result...

11 years agoversion 0.09 v0.09
Mats Johannesson [Wed, 25 Jun 2008 19:29:09 +0000 (15:29 -0400)]
version 0.09
Bugfix to handle some weird windows who don't set the "class",
and even their parents lack it (like the "xev" program...). I
won't go further back in a hierarchy, so these weirdos get the
"default" keyset.

Note: Without this fix expresskeys will crash in such cases.

11 years agoversion 0.08 v0.08
Mats Johannesson [Wed, 25 Jun 2008 19:29:09 +0000 (15:29 -0400)]
version 0.08
When I was customizing the keyboard shortcuts within Gimp itself
(I wanted Alt + and Alt - to do Next Brush and Previous Brush) it
became obvious that I couldn't assign these brush steppings to any
touch strip, due to my shortsightedness.

Now touch strips can send two keys at a time, just like the pad
buttons: l_touch_up, l_touch_up_plus etc. All of the "_plus" touch
strip definitions are set to 0 (nothing) per default.

Being able to use the touch strips for things like this is really
neat. Look in Gimp's File -> Preferences -> Interface -> Configure
Keyboard Shortcuts -> Context for some good touch strip candidates.

Bugfix: Would crash if _no_ window had focus (except the root win).

11 years agoversion 0.07 v0.07
Mats Johannesson [Wed, 25 Jun 2008 19:29:09 +0000 (15:29 -0400)]
version 0.07
Multiple configurations to rule them all... Yes, we now send
keypresses intelligently based on several configurations. I've
included a "default" catch all type, one for Gimp, for Blender
and for XTerm. Observe the spelling! It is case sensitive.

To create a new definition, just copy a full block and alter the
Name and the keycodes. To find the proper name of a program/window
fire up "xprop". It should be included with your X. xprop without
any arguments expects you to then click on the target window.
What comes out is a flood of information in the terminal window
you used to run xprop from. What we're after is something called
WM_CLASS. And within that, only one string. Let me show you:

$ xprop | grep WM_CLASS
WM_CLASS(STRING) = "<unknown>", "Eclipse"

It's the last string we would use, the "Eclipse" part. That is,
if we were doing a definition for this program, an IDE ;-)

You can see above why I use the last part. Program windows do not
always set their "name" (the first string). But they should
absolutely set the "class" they belong to, which often coincides
with the name.

So non-technically, this is how expresskeys works now:

1) Pad button pressed or Touch strips touched.
2) Examine which window is the current active one (has focus).
3) Get the "class" name of the window.
4) Compare that name with an internal list of program names.
5) If a match is found, use those keydefinitions.
6) If no match is found, use a "default" set of definitions.
7) Send the keypress to the specified window.

In order to achieve this functionality I had to change the
"user config area" somewhat. I've done my very best to retain
a simple design, and at the same time keep it compact. But
success is in the eye of the beholder... Cut out example:

/*  key_9 */ <-- A visual reminder of which pad button it is.
50, <-- The actual keycode and a COMMA (don't erase it).

Otherwise all the keys and options from past versions are, almost,
the same. End Version Note Rant.

11 years agoversion 0.06 v0.06
Mats Johannesson [Wed, 25 Jun 2008 19:29:09 +0000 (15:29 -0400)]
version 0.06
Comment 2 April 2005: This is default only in Gimp. Basic defaults
are now Arrow-keys Up/Down/Right/Left. End comment.

Touch Strip simple implementation. Default, if turned on, sends plus
(+) and minus (-) key presses based on finger/stylus up/down motion.
This was chosen for Gimp Zoom In/Out functionality. It must be turned
on by setting a value in the "user config area", just as for pen mode
handling. Default is off, don't handle the touch strips.

It turns out that with linuxwacom-0.6.7 (beta is out) this program
works better than ever! The blender "confusion" I talked about in
the previous version note has vanished completely. Also blender
zoom, translation and rotation work flawlessly with the pad buttons
and pen middle button (was half-working in linuxwacom-0.6.6). So the
XTestFakeKeyEvent was no bad choice at all. I'm very pleased :-)

11 years agoversion 0.05 v0.05
Mats Johannesson [Wed, 25 Jun 2008 19:29:09 +0000 (15:29 -0400)]
version 0.05
Bugfix. My key scan "case:, if, else, break" flow was somewhat borked.
Ugly function but does the right thing now. There are still issues
with (I believe) the timing of the XTestFakeKeyEvent of the XTest
extension. Using the "u" and "Shift-u" for undo and redo in blender
works, but sometimes blender gets confused. Waiting some seconds and
doing a "slow-push-release" of the key can fix the issue. Ah well,
this simulates keypresses, it's not the real thing... I'll look into
using another extension for the simulation.

11 years agoversion 0.04 v0.04
Mats Johannesson [Wed, 25 Jun 2008 19:29:09 +0000 (15:29 -0400)]
version 0.04
Bugfix to handle certain key combinations better. Not perfect though.
Will debug further.

11 years agoversion 0.03 v0.03
Mats Johannesson [Wed, 25 Jun 2008 19:29:09 +0000 (15:29 -0400)]
version 0.03
Handle a pen from the pad keys (toggle between absolute and relative mode).
See the new "user config area" for details. Observe: Whatever pen mode
you are in when exiting or killing this program, that's the pen mode
you have... So if wrong, fire up the program again and toggle until it's
the right mode. Default is off, don't handle a pen.

Clearly marked and cleaned up a "user config area" at the very beginning
of the code.

11 years agoversion 0.02 v0.02
Mats Johannesson [Wed, 25 Jun 2008 19:29:09 +0000 (15:29 -0400)]
version 0.02
Comment 2 April 2005: These instructions are dated. #define
for the keycodes are not used anymore. End comment.

Added the option to specify an extra key for each pad key.
"#define KEY_xx_PLUS yy". By setting yy of KEY_11_PLUS to 57 you'd get
the famous Ctrl-n ;-). I needed this for undo and redo in blender.

11 years agoversion 0.01 v0.01
Mats Johannesson [Wed, 25 Jun 2008 19:29:09 +0000 (15:29 -0400)]
version 0.01
Original release

Have fun,