expresskeys.git
10 years agoversion 0.2.6 v0.2.6
Mats Johannesson [Thu, 26 Jun 2008 18:47:28 +0000 (14:47 -0400)]
version 0.2.6
* Continuation of the maintenance by future proofing the ./configure phase
of the program compilation. We now examine what is returned from the commands
"pkg-config --variable=libdir x11" and "pkg-config --variable=includedir x11"
which is used to identify a modular X11R7 release. If that fails, we fall
back on a hardcoded /usr/X11R6/lib[64] and /usr/X11R6/include path for the
monolithic X11R6 releases. Failing that... the users can specify their own
paths through the "--with-xlib=" and/or "--with-xinc=" options. ".

10 years agoversion 0.2.5 v0.2.5
Mats Johannesson [Thu, 26 Jun 2008 18:45:35 +0000 (14:45 -0400)]
version 0.2.5
[Absolutely no new functionality! A pure maintenance release to prevent
trouble. Ticked off a todo-list based on user experiences and their snafus]

* Erased the useless code in the src-expresskeysconf directory. When or
if a graphical utility is written it should have a fresh start.

* Populated the auto-generated Gimp section of the configuration file
with a more complete set of keycodes (a collection which I use myself).
This was done in order to help people's understanding of the fields.

Updated the USAGE file with this Gimp information, close to the bottom,
since there was no easy way to auto-write a description in the configuration
file itself.

* Changed the expresskeys-reread.sh and expresskeys-terminate.sh scripts
in the old-extra directory so they won't use any hardcoded program paths,
except for the #!/bin/sh trigger. I thought that I had used the canonical
paths, but distributions apparently shuffle stuff around willy-nilly.

* Threw in a basic trap/filtering routine in config_read.c which silently
swallows illegal keycodes from the low region - below 9 [Escape] - unless
the program is run in verbose (-v) mode. Then it spits out a "keycode IGNORED"
message when the configuration file is read. Xlib crashes the program when
fed unsavory keycodes, so more work can be done in this area.

* Implemented a ./configure discovery section where a dummy file is
compiled and linked for each of libX11.so libXext.so libXi.so libXtst.so
X11/Xlib.h X11/Xutil.h X11/extensions/XInput.h and X11/extensions/XTest.h
Missing dependencies are thus quickly spotted and a comprehensible error
message delivered. A section dealing with dependencies has also been added
at the end of the INSTALL file.

The discovery section can be ogled in the configure.in file of the
root directory. I almost went mad before nailing a working piece like:

echo $'#include <X11/Xlib.h>\nmain(){}'|$CC -L$XLIBDIR -xc - -o dum 2>/dev/null
if test $? != 0 ; then
   echo "Can not include <X11/Xlib.h> header file!"
   SOMEERROR=1
else
   echo "Xlib.h OK"
fi

So simple looking and yet so hard to produce...

* Included the following text block in the runtime help, the README and
the USAGE file (and now here ;-)

"Please direct any bug reports or questions to the top address in
the AUTHORS file. This program is _not_ a linuxwacom project."

10 years agoversion 0.2.4
Mats Johannesson [Thu, 26 Jun 2008 18:41:33 +0000 (14:41 -0400)]
version 0.2.4
* Began code transfer/reuse from src-expresskeys to src-expresskeysconf
as a scaffold for some kind of graphical utility. Long way to go...

* Explained the X "xev" program and keycodes a little better in
the USAGE file.

* Put a warning regarding the X program "xmodmap" in the BUGS and
in the USAGE file.

* Cleaned up gcc warnings on a x86_64 system.

_Data Type Sizes (for my own reference)_

Type x86 x86_64

char 8 8
short 16 16
int 32 32
long 32 64
long long 64 64
float 32 32
double 64 64
long double 96 128
void* 32 64

In short, a programmer should NOT assume that:
sizeof(int) == sizeof(long) == sizeof(void*)

10 years agoversion 0.2.3 v0.2.3
Mats Johannesson [Thu, 26 Jun 2008 18:39:27 +0000 (14:39 -0400)]
version 0.2.3
* The project now uses the GNU Autotools to:
"./configure", "make" and "make install".

* Print out a version number with the "Usage" info if the program is
run with an empty command line.

* Corrected the Blender entry (undo/redo in both edit and object mode).
Yes, that's a cryptic line ;-) Try Blender for yourself. Next version,
(2.37) due this month or so, will be something extra.

10 years agoversion 0.2.2 v0.2.2
Mats Johannesson [Thu, 26 Jun 2008 18:16:28 +0000 (14:16 -0400)]
version 0.2.2
* Included an example of how to use an external program through
the simple "system" command (see exec_shell.c). The sample
"xsetwacom" utilization (pen pressure sensitivity) is not particularly
exciting as a new feature, but nevertheless an opening for future
implementations.

It's hard to imagine someone wasting three full expresskeys to get
a comfortable workflow, but here you are:

Keycode field value (regular button only, not touch strips or Plus)
1001 <-- Pen sensitivity gets lower with each press, until roll over.
1002 <-- Pen sensitivity is set to wacom default, a middle curve.
1003 <-- Pen sensitivity gets higher with each press, until roll over.

A pen name must be specified on the command line, of course.

Since both the 1001 and 1003 flip over in a carousel fashion at the
top and bottom values, you could manage the operation with only one
button. But if you go too far, there are 6 presses to be made until
next rendezvous in the 7 state circle. Not good.

The curve values are picked from how the "wacomcpl" program sets them
(the tcl utility) in Feel -> Sensitivity [1 to 7].

I've refrained from documenting the 1001 - 1003 in the USAGE file, and
a new configuration file won't have them listed in the header. The real
world usability is too limited, I feel. Better things will hopefully
come in the future.

The old pen mode toggle code could be rewritten so it was handled by
this external xsetwacom functionality, in good *nix tradition of reuse.
But what if the user environment doesn't have the xsetwacom program
installed? Better leave the code as is, I think.

-------------------------------------------------------------------------
Speaking of the future, this 0.2.2 version will be the last one (from me
at least) for quite some time. When I began the project, more than 1 1/2
months ago, it was out of pure necessity. I had a brand new (expensive)
Wacom tablet with semi functional hardware. Extensive web searches didn't
reveal any program to unlock the enticing ExpressKeys and Touch Strips,
so I reluctantly opened a C language book and set to work.

I never planned to enter the "programmer" domain in earnest. Neither
did I anticipate a perpetual development. When the job was done, it
would be done...

And now it's done, from my point of view. Core functions are rather
complete, and the program runs without hiccups. Ideas have dried up
and I am frankly getting bored with code hacking. Now I want to USE
the tablet, finally.

The code is free as in beer and freedom. If anyone feels like expanding
or even forking it, just do so (according to the GPL). There's the whole
bag of internationalization, installation and graphical configuration
left to a fresh mind. I'm too tired right now.

Though, I'll dive in again if a pressing issue turns up ;-)

Bye for now,
Mats
-------------------------------------------------------------------------

10 years agoversion 0.2.1 v0.2.1
Mats Johannesson [Thu, 26 Jun 2008 18:15:20 +0000 (14:15 -0400)]
version 0.2.1
* Added support for faking mouse button events. Denis DerSarkisian
sent a function called "fake_event" (top of event_loop.c) which
in essence acts like a traffic cop, steering true keycodes to
XTestFakeKeyEvent and a set of false ones to XTestFakeButtonEvent.
The fake codes can be entered as 991 to 997 in the configuration
file, simulating mouse buttons 1 to 7.

Only existing mouse buttons, defined through the driver of the
active core pointer, can be simulated. I added discovery code to
prevent a crash if someone tries to use a nonexistent mouse button
in the range 1 to 7.

The code author wanted his touch strips to act like a mouse's scroll
wheel through the use of mouse buttons 4 - 5 (Up/Down) and 6 - 7
(Left/Right). I only have a three button mouse, the Wacom puck is
not a core pointer, but can make good use of the new functionality
in eg the web browser Opera:

[...]
20 Right Pad - Button 14: 993 # Button 14
21 Right Pad - Button 14 Plus: 991 # Extra key
[...]
24 Right Pad - Button 16: 991 # Button 16
25 Right Pad - Button 16 Plus: 993 # Extra key
[...]

With those definitions I step backwards (14) and forwards (16) in
the visited page history. Opera's "forward" can also take me to
the "Next" linked page, so it's very convenient when having a long
reading session.

* Expanded the "-v" (verbose mode) printing to cover more execution
points and be a lot more detailed.

* Racked my brain and added some more knowledge to the BUGS file.

10 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.

10 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.

10 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:
http://www.catb.org/~esr/writings/taoup/html/

* 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.

10 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 ekeys-reread.sh which does it for you
if ekeys is running in daemon mode. Also included is ekeys-terminate.sh
which replaces the former ekeys-kill.sh (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.

10 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: "expresskeys.pid". 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 ekeys-kill.sh) which reads the
expresskeys.pid 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...

10 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...

10 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.

10 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).

10 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.

10 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 :-)

10 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.

10 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.

10 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.

10 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.

10 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,
Mats