Make Special HP Laptop Touchpad Toggle Key Work In Linux

I recently purchased a new (refurbished) HP “Elitebook” 8440p laptop (see previous blog post) and docking station, and installed my custom “remastered” copy of Antix Linux!  Before buying, I had tried out my remastered Antix live-DVD on my wife’s laptop (same model with lower resolution screen) and everything basic seemed to check out.  As I expected, this laptop has proved to be a great laptop for Linux but I’ve been somewhat surprised at the number of additional (and difficult) issues/hacks I’ve had to resolve/make to my (already very customized) remastered linux installation.  In my previous post I described the nightmare I went through getting Linux to boot with Windows 7, though this is not at all a fault of the computer or it’s hardware, but rather owing to the way Windows 7 was partitioned and installed.  Another hack / workaround I ended up having to make (after another extended, but fruitless search) was downgrading my “AccelMethod” from “SNA” back to “UXA” in my /etc/11/xorg.conf file to stop screen corruption and lockup when exiting X without having to add a “chvt 1; sleep 2” sequence to each logout/exit/reboot command script in the window-manager, and disabling the “Ctrl-Alt-Backspace” command.  Switching to “UXA” eliminated the need for these workarounds (after I tried everything else I could come up with).  This machine has a LATER version of Intel graphics (Mesa DRI Intel Ironlake Mobile x86/MMX/SSE2).  The tradeoff is a slight reduction in video performance from up to 2000 fps to around 1700 or so, only really noticeable by running glxgears (My Dell never broke above 900 fps, but WORKED flawlessly with SNA!).
The hardware was very similar (driver-wise) to that of my old Dell D620, but more modern (Intel CPU, Intel integrated graphics, sound, and network interfaces).  The first issue that needed tweaking was to activate all the custom special-function keys.  Nearly all laptops have them and they all seem to be different not only between brands, but also between models.  I had long ago gotten the Dell’s all working using a now rather old program called “hotkeys”, however, I had not used them in ages since my Dell has not had a working battery since forever, and I’ve been using it almost exclusively docked (and the lid closed).  I’ve found that hotkeys seems to not work well anymore due to trouble staying up between suspends, etc.  I began looking for a better solution and found “xbindkeys”. This program also includes a GUI which permits you to actually press each key and then add your desired action command and builds the config. file for you!  This strategy proved successful for all the special keys, including the little “led” light-up ones above the keyboard that look more like status indicators than press-able keys.  The only ones not configurable via xbindkeys were the “wifi switch” led/key and the “touchpad toggle” led/key.


     "/usr/bin/amixer -q set Master 4- unmute"
         m:0x0 + c:122

     "/usr/bin/amixer -q set Master 4+ unmute"
         m:0x0 + c:123

     "/usr/bin/amixer -q set Master toggle"
         m:0x0 + c:121

     "sudo /usr/local/bin/"
         m:0x0 + c:235

         m:0x0 + c:180

         m:0x0 + c:160

     "/usr/local/bin/ -60"
         m:0x0 + c:232

     "/usr/local/bin/ 60"
         m:0x0 + c:233

         m:0x0 + c:248

     "sudo /usr/local/bin/s2ram"
         m:0x0 + c:150

The wifi key “works” in that it uses rfkill to toggle the wifi.  For most people, this will probably work fine out of the box, but I configure my networks manually, and need for the wifi to go off (and ethernet to come on) when docking so that my home network comes up on the ethernet connection (I needed to be able to execute a custom script whenever this key was pressed).  I ended up getting this key working by adding an ACPI event and script (see below).

     event=PNP0C14:01 00000080 00000000

In Linux Live-CD:


     event=PNP0C14:01 00000080 00000000

     test -f /usr/share/acpi-support/key-constants || exit 0

     . /usr/share/acpi-support/key-constants

     wifiblocked=`rfkill list wifi|grep "yes"`
     if [ "X$wifiblocked" = "X" ]; then
         echo "..WIFI BUTTON PRESSED: wifi not blocked!" >>/tmp/acpi.dbg
         echo "..WIFI BUTTON PRESSED: wifi BLOCKED!" >>/tmp/acpi.dbg

HP Touchpad Toggle Led/KeyI got all the special HP light-up buttons above the keyboard working with xbindkeys EXCEPT the one that looks like a tiny touchpad, that’s supposed to toggle the touchpad.  That little bugger just did not want to work, not even in Windows-7?!  The “touchpad toggle” led/key lights up cyan on startup and the touchpad is enabled.  Pressing it turns it orange and (should) disable the touchpad. Touching again turns it back to cyan (should re-enable touchpad).  In reality, it does nothing but change color when pressed.  X does not see it except the very first time it’s pressed, in which case xev sees a continuous spewing of keypresses and releases of keycode 138 killable by pressing Ctrl-C.  dmesg reveals that the kernel sees the alternate press as unassigned scancode “e058”.  Subsequent presses produce nothing visible to X until you reboot.  I tried adding the setkeycodes command the kernel suggested, googled and googled and could not find anything that would make this key visible to X. The console program showkey would show it alternately returning keycode 138 and keycode 140 (the one I assigned with setkeycodes) as I wanted, but for some reason nothing in X could see anything when the key was pressed.  Obviously, the key was seen by the kernel.  Several google pages described how to “translate” these kernel keycodes to X, including xmodmap, but nothing worked.
It was not like this particular key was very important to me, but at this point it had just become a determined challenge to force it to work!  I finally stumbled upon a tiny C program that could monitor the keyboard input device and report each key pressed.  I ended up modifying this program to look for these two keycodes and calling a command whenever one was seen.  I then set this program up as a tiny daemon so that I can now press the key and toggle the state of the touchpad!  Why?  Because I could and because I had already wasted too much time trying to figure this out!  😀
I finally found, stole and hacked up a tiny daemon C program that DOES make it work!  You need to do the following:
1)  in rc.local or somewhere in startup scripts add: /usr/bin/setkeycodes e058 140
2)  compile this little C program “keycheckd” (gcc -o keycheckd keycheckd.c) and place the compiled binary in /usr/local/bin/, and chown 4755 keycheckd
3)  In your X desktop session’s startup script do (must be started from w/n X desktop, NOT startup or console!):

     xset -r 138 -r 140 -r 146 -r 148
     keycheckPid=`pidof keycheckd`
     [[ "X$keycheckPid" == "X" ]] && /usr/bin/nice -n 10 /usr/local/bin/keycheckd &

The source (keycheckd.c) (note: you could add other keysyms / actions, if needed):

#include <stdlib.h>>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <string.h>
#include <stdio.h>


int main(void) {
    const char *dev = "/dev/input/by-path/platform-i8042-serio-0-event-kbd";
    struct input_event ev;
    ssize_t n;
    int fd;

    fd = open(dev, O_RDONLY);
    if (fd == -1) {
        fprintf(stderr, "Cannot open %s: %s.\n", dev, strerror(errno));
        return EXIT_FAILURE;
    while (1) {
        n = read(fd, &ev, sizeof ev);
        if (n == (ssize_t)-1) {
            if (errno == EINTR)
        } else
        if (n != sizeof ev) {
            errno = EIO;
        if (ev.type == EV_KEY && ev.value >= 0 && ev.value <= 2) {
            /* printf("0x%04x (%d)\n", (int)ev.code, (int)ev.code); */
            if ((int)ev.code == 138) {
                /* TURN ON TOUCHPAD: */
                /* printf("--138: turn touchpad ON!\n"); */
                system ("/usr/bin/synclient TouchpadOff=0");
            } else if ((int)ev.code == 140) {
                /* TURN OFF TOUCHPAD: */
                /* printf("--140: turn touchpad off!\n"); */
                system ("/usr/bin/synclient TouchpadOff=1");
    fprintf(stderr, "%s.\n", strerror(errno));
    return 0;

Now, when you press this “key”, it should turn orange and actually disable your touchpad, a second press should turn it back blue and re-enable your touchpad.  I believe you could add the “/usr/bin/synclient TouchpadOff=1” in your X session startup script above where you start this daemon, and reverse the two “TouchpadOff=#” commands in it to have it start out disabled, then toggle to enabled, then disabled, etc.

Gettin’ Down & Grubby with Grub!

Last week I broke down and bought myself a shiny new (refurbished) an HP “Elitebook” 8440p lappy! :D  It’s been ten long years or so since my last computer purchase (also a corporate refurb).  My way is to buy a good used one from a generation or two back, put Linux on it and have a faster machine than most brand new ones whilst saving a ton of money.  My last one’s been great as a docked desktop paired w/a big monitor, but has become a very crappy laptop that runs hot, has no working battery, and the hinge won’t hold the lid up anymore.  Portability issues aside, it still performs very well, especially for its age.  I’ve even been complemented on how snappy it is, considering it’s age.
This “new” lappy came with a huge, terrabyte SCSI hard drive (the good ol’ fashioned spinning kind, which I prefer) loaded with a fresh install of Windows-7 Professional 64 bit to complement it’s eight gig of RAM.  I ended up shopping longer and paying a tad more in order to nail down one of the (apparently rare) ones that has the higher-resolution (HD+) screen sporting 1600×900 resolution (most come w/a crappy 1366×750 screen) combined w/the non-dedicated integrated Intel graphics.  The reason I wanted Intel graphics is that it’s no hassle to get to work well with Linux, runs cooler, and yields longer battery life than the Nvidia dedicated version.  The box arrived from Odyssey Computers via Amazon with free shipping in three days!  It contained a nice, shiny clean new-looking computer and 65 watt HP power supply wrapped in a generous supply of bubble wrap.  I plugged it in, opened the lid, turned it on and was greeted with Windows-7’s “First Use” screen.  I read the eula, signed over my first born to lifetime servitude to Bill Gates Inc., created an abUser account, and set it up. I confirmed the graphics, screen, hard drive, and RAM quickly through Windows’ Device Manager.  One fear that I had was that Windows would be set to boot under UEFI, making my task much more difficult, but I poked around in the bios and determined that, thank goodness, that was not the case.
Now, on to the Linux setup!  I remastered my current Antix Linux setup using Antix’s unique and very cool “snapshot” tool onto a DVD, inserted it and booted it right up.  First order of business was to run gparted and determine the partition layout for Windows.  This revealed three existing NTFS partitions: a 12 gig “Recovery”, a 150 meg “SYSTEM”, and the remaining 919 gig “Windows” (C:).  This meant we had the fourth and final partition slot available for creating an extended partition and filling it with logical partitions to our hearts content for Linux!  I then proceeded to create the extended partition and added logical Linux partitions for root, var, swap, and home in that order.  It’s fully ok and preferable (to avoid tiny slices of unusable disk space) to select “Alignment: None” for each one as you create it.
This is where the good ended and the bad began: ALL three were NTFS (INCLUDING the first) AND, the SECOND (NOT the first) one was marked as the “boot” partition.  This meant NO installing Grub boot-loader in the MBR (The normal location) and most likely having to modify the Windows boot-loader to launch Grub and Linux from the Linux “root” partition we would create.  Still no biggie, right? (WRONG!)  Fortunately for me, I started googling around BEFORE I attempted an install and found out that this might be a bit more difficult (little did I know yet!).  I had installed Antix once before on another Windows-7 machine with only a couple of minor hiccups involving Windows booting via “chainloading”, but that one was set up the “normal/proper” way with a FAT32 partition at the beginning for booting (just put Grub in MBR, add “hide/chainloader” entries for Win-7 and I was good to go).  I quickly learnt that GRUB would not play nice if put into an NTFS partition.  I also became acquainted with an obscure Windows program called bcdedit.  I went ahead and played with that and successfully added a second entry in the boot menu for Linux.  I then cautiously created all my Linux partitions using gparted and installed Antix. Then I carefully created the special “antix.bin” file and gently placed it into the Window’s C:\ directory as instructed in my research and rebooted.  I was quickly greeted again with my Windows boot menu containing two entries:  “Windows” and “Antix”.  I selected “Antix” and…BLACK SCREEN.  Tried again with “Windows”, Windows booted up as normal.  Oooo-kaaaay, back to Google . I then learnt that Grub Legacy (the version I use since I’ve found Grub 2 very hard to configure with a labyrinth of separate configuration files) also doesn’t play nice if installed into an ext4 partition (unless it’s the MBR/boot partition (hd0,0)).  So, rinse, spit, repeat – this time, tried making the root partition ext2 (ugh!)  This likewise did not work because, come to later find out, the Windows-7 boot loader does not like to talk to ext2 filesystems, even just to boot.  Then came a full twenty-four hour haze of gory details of experimentation that I won’t bore you with here, with little to show for it.  As a last resort, I ended up creating a separate 1 gig FAT32 “boot” partition and with a lot of kicking and screaming from Grub, I finally got it installed there and a working 512 byte “antix.bin” file in the Windows “boot” partition (not C:\) and was able to boot “manually” (It would boot to a cold bare “GRUB>” prompt (when “Antix” was selected), where I could type in a partition identifier (hd0,4), then a kernel line (see menu.lst), then an initrd line, and boot. More googling and T&E revealed that I could just type “configfile /grub/menu.lst” and boot right in. Still more led to making copies of everything in /boot/grub/ to /boot/boot/grub/ (guess we need two matching boots, LOL), and finally, VALA, Linux nirvana!
Lessons learned:
1)  To install Grub in a separate partition (other than the first in the MBR) and be accessible by the Windows-7 boot-loader, one needs to create a separate FAT32 partition and mount it in Linux as “/boot”.
2)  To create the “linux.bin” (I chose “antix.bin”) file for the Window boot-loader, you must first coax Grub into installing it in said FAT32 partition and then use the dd command to grab the first 512 bytes of THAT partition writing it to that file (antix.bin in the root directory of /dev/sda2).
3)  Grub Legacy expects to find it’s “menu.lst” file in /boot/grub/ off of THAT partition (/dev/sda5 or (hd0,4) in my case) even though Linux will have to mount that partition as /boot off of it’s (Linux’s) root (/dev/sda6) and will, along with “update-grub”, expect to find it, along with the other grub stuff in /boot/grub/ off of Linux’s root (/grub in the /boot partition).  Therefore, you must create a “/boot/boot/grub/” subdirectory (off of Linux root – when Linux is booted up) and copy everything in /boot/grub/* to there.  The logical thing to do would be to move it there and create a symlink (cd /boot; ln -s boot/grub grub), but this WON’T WORK because this is all in a FAT32 partition, a rickity old filesystem from the MS-DOS era, so you must COPY the grub tree. You will also need to update BOTH menu.lst files whenever you do “update-grub” or upgrade your kernel, then make sure both menu.lst files match!  NOTE:  It’s only grub that must be copied, NOT your kernels, etc.  They reside one level up in /boot/.
4)  You really should reinstall your kernel package (at least if installing via Antix remaster’s “cli-installer” installer) after you successfully get booted up, since I ran into a few devices modules missing, etc. as I tested things out.  All were fixed by reinstalling / updating my preferred kernel).
5)  Making a “bootable” USB-stick was a good way to test the bootability of my Linux install, but NOT a good way to configure Grub after booting up with it as the system came up with the USB stick seen as “sda” (the FIRST “hard drive”), and my hard drive as “sdB” (the SECOND) – NOT what neither I nor Grub were expecting, forcing manual typing in the boot entry each time!
6)  Grub Legacy is a total BEEACH when asked to configure itself in any way out of the ordinary as far as partitioning goes.  It really wants to reside in the MBR.  As a biased and unabashed Linux user, I expected Windows-7 to be the problem child in the sandbox, but no, it was grumpy, grubby ol’ Grub that had to be dragged kicking and screaming every step of the way and be absolutely beaten into submission!  All the while, Windows gave me no grief whatsoever nor even sneezed or snickered at me as I struggled and fought with Grub.
Ok, here’s the gory details that worked (NOTE, this is only for other unlucky souls who have a non-UEFI booting Win-7 installed with no FAT32 first partition with the “boot” flag” set and no Windows re-install disks).  Otherwise, IF non-UEFI booting, you can MAYBE, MOST LIKELY install Grub (at your own risk) the usual way in the MBR and (maybe) ignore all this!:

NOTE: THIS ASSUMES THE FOLLOWING PARTITION SETUP (I had the 1st three, shrank the third (using gparted), and created the rest and you’ll need to adjust as needed for yours):

     (hd0,0) /dev/sda1:  NTFS - Windows "Recovery"
     (hd0,1) /dev/sda2:  NTFS - Windows "SYSTEM" (boot flag set!)
     (hd0,2) /dev/sda3:  NTFS - Windows (C:)
     (hd0,3) /dev/sda4:  Extended
     (hd0,4) /dev/sda5:  FAT32 (mount as /boot in Linux)
     (hd0,5) /dev/sda6:  ext4 or any other Linux filesystem (mount as / (root) in Linux)

Boot up in Linux Live-CD:

1)  Use garted to shrink the Windows C: partition (I tried to do this in Windows, but it wouldn’t allow me to shrink it as much as I wanted, since Windows likes to put “immovable” – (to Windows), files in the middle or latter part of the partition) gparted SHOULD handle this without fuss (it did for me).

2)  Create an “extended” partition and then your Linux partitions (First one must be FAT32 and will later be mounted as “/boot” in Linux).  Next should be your Linux “root” (mounted as “/”) and be ext4 (my preference) or any other modern Linux filesystem.  Additional partitions are optional (I like to create ones for “/var”, swap, and “/home” in that order).  With 8 GIG of RAM, I don’t really need a swap, but I created an 8+GIG swap for hibernation perposes (Hibernate is a very useful feature on laptops).

3)  Install your Linux, but do NOT install Grub in the MBR!!!  Instead install it in “root” (Linux’s root directory – /dev/sda6 in my case)!  If you are lucky enough to be installing a distro that gives you Grub install choices OTHER than “MBR” or “root” (I wasn’t), then choose your FAT32 partition!  I had to choose “root” (and the slightly-buggy Antix “cli-installer” did not do THAT quite right either – I looked at the script’s code and it appeared designed for Grub-2 with options that Grub Legacy does not recognize), but at least it did not touch my MBR, thank goodness!.

4)  I had to do the following to get Grub Legacy properly installed:

Boot up (again) into my Antix live-CD and:

     mount /dev/sda6 /mnt
     mkdir /media/boot
     mount /dev/sda5 /media/boot
     mount /dev/sda6 /mnt
     vi /mnt/boot/grub/menu.lst:  #WE NEED TO CHANGE OUR "root"s in "menu.lst" AS SO (root=our Linux root (/), (hd0,4) IS OUR NEW /boot)!  (I use the Liquorix kernel, but you need an Antix kernel for the remaster/install):

         title Liquorix, kernel 4.4-6.dmz.1-liquorix-686
         root (hd0,4)
         kernel /vmlinuz-4.4-6.dmz.1-liquorix-686-pae root=/dev/sda6 quiet nosplash ro
         initrd /initrd.img-4.4-6.dmz.1-liquorix-686

         title Antix, kernel 4.0.5-antix.1-486-smp ro
         root (hd0,4)
         kernel /vmlinuz-4.0.5-antix.1-486-smp root=/dev/sda6 ro
         initrd /initrd.img-4.0.5-antix.1-486-smp

     vi /mnt/etc/fstab:  #THIS NEEDS TO PROPERLY MOUNT /dev/sda5 AS /boot!

         /dev/sda2  /media/Recovery  ntfs-3g noauto,noexec,...
         /dev/sda3  /media/Windows  ntfs-3g noauto,noexec,...
         /dev/sda5  /boot  vfat  defaults,noatime  0 0
         /dev/sda6  /  ext4  defaults,noatime  1 1

     cp -afv /mnt/boot/* /media/boot  #THIS COPIES ALL OUR BOOT STUFF (GRUB & KERNELS TO OUR /boot PARTITION):
     umount /media/boot  #MAKE SURE THIS IS UNMOUNTED!
     #NOTE:  OUR ROOT PARTITION (/dev/sda6) IS MOUNTED, OUR BOOT PARTITION. (/dev/sda5==(hd0,4)) IS *NOT* MOUNTED!
     for i in /sys /proc /run /dev; do mount --bind "$i" "/mnt$i"; done
     update-grub  #SO OUR UPDATED "menu.lst" GETS USED!
         grub>root (hd0,4)
         grub>setup (hd0,4)
     mount /dev/sda2 /media/Windows  #MOUNT OUR WINDOWS "BOOT" PARTITION:
         Boot   bootmgr   System Volume Information
dd if=/dev/sda5 of=/media/Windows/antix.bin bs=512 count=1  #(RE?)CREATE OUR BOOT FILE (antix.bin) FOR WINDOWS BOOT-LOADER:
     cd /mnt/boot
     mount /dev/sda5 /media/boot #/boot DIRECTORY
     cd /media/boot
     mkdir boot
     mkdir boot/grub
     cp -afv grub/* boot/grub  #VERY IMPORTANT: GRUB LEGACY WILL LOOK FOR menu.lst in "/boot/grub/" WHICH IS "/boot/boot/grub/" TO LINUX ROOT!  GRUB2 MAY NOTE NEED THIS?
     umount /media/boot

5)  Now reboot into Windows-7 and do:

Select Start.Accessories menu, then right-click on “Command Prompt” and choose “Run As Administrator”.
In the (admin) DOS window, do:

     bcdedit /export C:\originalbcd  #BACK UP YOUR ORIGINAL! (/import to restore if you should screw it up!)
     bcdedit /create /d "Linux" /Application BOOTSECTOR
     bcdedit /set {ID} device boot
     bcdedit /set {ID} PATH \antix.bin
     bcdedit /displayorder {ID} /addfirst  #THESE TWO WILL MAKE Antix THE FIRST AND DEFAULT ENTRY.
     bcdedit /default {ID}
     bcdedit /export C:\backupbcd  #BACK UP YOUR NEW ONE TOO!

6)  Now reboot and select “Linux” and (hopefully) boot up into your shiny new Antix Linux install!

7)  Re-install or update your kernel package and run “update-grub” – (I installed a PAE version so I could access my 8-GIG of RAM)  I found that the Antix installer did not seem to quite carry over all the kernel modules (my cd-rom disappeared, etc.) and this corrected everything.  I also backed up my “antix.bin” file somewhere on my Linux filesystem too!  (YMMV!!!)

Overall, I’m very pleased with this machine, all hardware seems to work well with Linux (Only thing I haven’t tested is the thumbprint reader).  Googling shows that it can be used in Linux.  The modem’s an Agere “losermodem” (winmodem).  I haven’t purchased a docking station yet).  The Intel Centrino Advanced-N 6200 wifi card needed:  “options iwlwifi bt_coex_active=0 swcrypto=1 11n_disable=8 led_mode=0” in a file I added to /etc/modprobe.d/ to work at proper speed with my 802.11G home wireless network, however.  The computer itself runs fast and fairly cool, and the fan is much quieter than any of the previous machines I’ve owned!  Here’s my /proc/cmdline:  root=/dev/sda6 quiet nosplash cgroup_disable=cpuset,cpu,cpuacct,blkio,memory ipv6.disable=1 libahci.ignore_sss=1 vga=0x365 ro
Links that I found very helpful along the way:

UPDATE:  The WIFI card, an “Intel Centrino Advanced-N 6200” is a bit wonky.  It seems to work find in Linux (no dropped connections, etc.), but there are a couple things I had to do due to the fact that I use a rickity old Linksys WRT54G (11G) router with Tomato firmware installed. Using iwconfig, the wireless card reports a pathetic “Bit Rate=1 Mb/s”. I tried everything I could think of or find to get it to work properly and have given up.  Every once in a while, it’ll come up showing a larger number (once showed 54)!  I’ve since determined that the card seems to be working properly ( shows my internet at the full 6.4 Mb/s on it!), but it’s just REPORTING the wrong value (1).  My final settings are (/etc/modprobe.d/iwlwifi.conf):  “options iwlwifi bt_coex_active=0 swcrypto=1 11n_disable=1 uapsd_disable=1“.  This tells it to ignore any blue-tooth interference, turns on software encryption capability, disables 802.11n service, and turns off an obscure power-saving capability (primary power management is off by default).  I also blacklisted all bluetooth modules (btusb, btintel, btrtl, btbcm, and bluetooth), as I don’t use any bluetooth devices, though if you do, this should not be necessary.  I also had to go into /lib/firmware/ and do:

     sudo ln -s iwlwifi-6000-4.ucode iwlwifi-6000-5.ucode
     sudo ln -s iwlwifi-6000-4.ucode iwlwifi-6000-6.ucode

to eliminate a complaint in dmesg about the kernel not being able to autoload the firmware.  Not doing this did not prevent the card from working, but I didn’t like the error (warning?) and wanted to make sure the correct and best firmware available (6000-4) was being loaded. The 5 and 6 versions do not appear to exist yet!

Sql*Perl Plus, E Editor, and JFM File Manager for Linux and Windows, Oh My!

(Finally) Announcing the official release of three of my all-time favorite Perl/Tk applications in both Linux and Windows versions!  These three programs are like old friends to me since I wrote them years ago and have been using them both on and off the job and improving them for years now.  They have made my work much easier and now I’ve finally had the time to actually get them ready for use by others.  They are:  “Sql*Perl Plus” – an all-purpose “Swiss Army knife” database manipulation and report-generating tool; “E Editor” – an all-purpose full-screen, full-color context-highlighting text and code editor and viewer; and JFM4 Filemanager – an all-in-one file-manager, application launcher, shell, and *FTP client for managing files, launching applications and shell commands with many unique features.  I wrote all three of these tools to improve my daily workflow and meet specific needs that were not being fully and efficiently met by other tools available to me at the time, and when I found myself just needing “something extra and unique”, and, because I could!😀 They each allowed me to hone my programming skills in different ways and learn new techniques.
Each started out as something relatively simple, designed to meet a need, but all quickly mushroomed into much larger and more capable tools as needs arose and changed.  The most liberating thing about writing and using them is that I know that whenever I think up a new need, use, or feature, I can add it.  I have decided to finally bundle each up in both a Linux/Unix tarball and create an easy-to-run Windows installable executable (using the very handy and free Inno Setup Wizard), along with all the requisite bugfixes, touchups, tweaks, and documentation polishing, in the hope that others may find one or more of them useful.  They are all fully open-source and released under the GNU public license, though I retain all copyright to the source code.  You are free to use and modify the code as permitted under that license.  However, I make no warrantees explicit or implied, thus you use this code solely at your own risk. You can download these and other open-source software I’ve created here at my software download page and / or on my CPAN page.
Sql*Perl Plus is the oldest of the three having just turned 20 this month.  It started out as a work request to make an in-house multi-database GUI tool similar to Oracle’s Sql*Plus(tm) tool.  The goal was to create SQL queries and simple reports using a GUI tool and a mouse to save a lot of typing.  Later, I added the ability to create formatted reports, and even M$-Excel spreadsheets which lead me to create the String::PictureFormat CPAN module.  I also added the ability to query database tables and generate M$-Excel spreadsheets, XML-formatted output, and DBD::Sprite tables.  This led to creating the ability to load database tables with data from M$-Excel spreadsheets as well.  Later still came the ability to auto-generate Perl scripts from queries both for batch-loading data into tables (the generated scripts can be used repeatedly as scheduled batch jobs), and for repeatedly generating reports on a scheduled basis or as-needed.  The tool can aid greatly in the creation of just the right query and formatting template for whatever the input data format is expected to be and / or the desired report layout.
E Editor provides a full-featured, but simple to use desktop application development environment, particularly for Perl development as it provides optional language-specific code syntax highlighting for dozens of different languages and markup, easy search and replace including via Perl regular expressions, a one-button Perl compile / syntax check feature and the ability to highlight code snippets and apply Perl’s eval() function to it.  There’s also named bookmarking, auto-backup on startup capability, quick temporary backup capability, Perl, C, and HTML structure insertion, reformatting, indenting, tab or space indents, choice of wrapping, fonts, colors, tagging, split-screen, and multi-tab/open files, custom configuration, etc.  Using a simple symlink, a “read-only” “viewer” version can be created in Linux/Unix using the same program executable.  I created “E” after moving from the DOS world to Linux/Unix back in the mid ’90s and having to give up my trusty full-featured, full-color “shareware” DOS editor “PC-Write“(tm) for the cryptic over-nerdy “vi” of Unix.
JFM4 is much more recent.  This started out with me wanting a graphical Norton Commander-ish filemanager with split-screen capability for easily copying and moving files about with options for more than one application-association with given file types / extensions (including directories), an enhanced command-line and command-repeat for quick shell commands (like I had on DOS with my handy “WinDOS Executive” (named after the old Windows MS-Dos Executive) I wrote for MS-DOS for the same reasons back in the ’80s.  The “something extras” I wanted was the aformentioned multi-app file assocation via a right-click popup menu (most filemanagers only offer one per file type, and with us Perl-ers are so used to “there being more than one way”), including a default (double-click) action, a separate “multi-file” association popup menu for invoking programs that can take multiple files at once / or loop to apply a program / command to all selected files, and a similar association menu for directories too that can invoke your choice of programs that can open entire directories at once like Audacious(tm).  It also has an “Action menu” of frequently-applied actions that can be performed on selected files, or just stand-alone, such as mounting frequently-used filesystems.  Another unique feature in the Action menu is one can have commands like “diff” gui-tools that can take two files, say, for comparisen.  I can select a file from the top panel and one from the bottom, select “tkdiff” from the action menu, and quickly compare the two files.  I can also craft shell commands with parameter placeholders and select files to process with the parameters being replaced with the selected and matching files in a loop.  It saves all typed-in commands, along with frequently-visited directories, and remote-host connections for quick, one-click reactivation.  There’s even a custom drop-down menu and text field to enter custom file-selection groupings, such as “Music”, “Perl”, etc.; and Perl regular-expression patterns for reducing the list of files shown in the file panels. There’s also multiple-tabs for having more than two directories and / or remote-connections open at once.  It also uses my “Net::xFTP” module to allow mounting file-systems on remote hosts as if they were local, allowing nearly all these features to be performed on remote files too!  This obsoleted another program I had previously written as a GUI wrapper to Net::xFTP called Ptkftp.  Later, to add a little eye-candy, I created the CPAN module “Tk::HMListbox” to allow for a column of tiny file-type icons to be displayed next to each file and directory.  While JFM4 does work on a limited basis on Windows and I’n not hesitant to use it on those rare occasions that I’m forced to work (“with one hand tied behind my back”) on Windows, it’s really designed to be a Linux/Unix tool, but it also comes with the install wizard for Windows.  It still could use some more work, features, and testing on that platform, however.

“JFM File Manager” screenshot; Feb. 3, 2016;  image by (©:2016) me.

“E Editor” screenshot; Feb. 3, 2016;  image by (©:2016) me.

“Sql*Perl Plus” screenshot; Feb. 3, 2016;  image by (©:2016) me.

My Current Linux Desktop

My Linux Desktop“; Jan 22, 2016;  image by (©:2016) me.
For those of you who are curious as to what my desktop looks like, this is it.  I posted this to Flickr the other day as my entry in response to an article on Lifehacker inviting people to share their Linux desktops.  As you can see, it’s somewhat “old-school” looking, since my computer (Dell Latitude D620 laptop) is somewhat old and limited in it’s power and speed.  I use the ancient Afterstep window-manager, which is fairly lean and mean, compared to “modern” desktops such as KDE and Gnome, which are absolute hogs on this hardware!  I’ve looked into switching into one of the more modern lean window-managers, such as Fluxbox, Xfce, or Icewm, but I’m used to Afterstep and would have to give up some of the features it offers.  Afterstep has a few annoying bugs / quirks, but the two reasons I stick with it are:  1)  It has “Wharf”, a Window-Maker-based launcher app. that not only provides for launch buttons, but can also “swallow” Window-maker “dock-apps”.  I wrote a dock-app years ago called “TkWeather” that can scrape three different weather sites and provide current weather info. dynamically in an icon that can be clicked on to see more information or double-clicked to pull up the full weather website.  I tried to get it to run in Fluxbox’s “slit”, but have been unable to do so.  2)  Afterstep requires modifying some text-based configuration files, but I’ve already long ago mastered how to configure Afterstep to look exactly the way I want it, and it would be a steep learning curve to have to re-configure everything the way I like it in another window-manager!  Afterstep gives me everything I want and nothing I don’t.  You can see the “wharf” (vertical row of icons) on the right.  The top button that’s grimacing will pop up an additional row of lesser-used program launch buttons.  The currently running (swallowed) dock-apps are (from top to bottom):  wmitime (clock), (my) TkWeather, wmtemp (cpu tempertures), xload (memory), wmappl (list of many more small icons that can launch apps.), wmMoonClock, and Pager.  The others are just launch button icons for terminal, browser, editors, etc.
As a career programmer, specializing in Perl and Tk, I’ve written some of the applications / tools I use regularly and hacked others.  I guess I’m a control freak and when I have to work with a tool on a daily basis to get work done.  I quickly become aware of how I want it to work to maximize my workflow and I see the shortcomings in whatever I’m using, then search for one that will do what I want to do.  It Seems that in some cases I’ve been unable to find what I’m looking for, so I’ve then written my own.  This was the case with my code editor (E) and file manager (jfm4) (both shown on this desktop image) as well as the weather app (TkWeather).  By writing a tool myself, I control exactly what it does (and doesn’t do), and can adapt it over time to meet changing requirements.  I did not write Fauxdacious, but over the years, I have hacked my favorate all-purpouse audio media player (Audacious) to work better in my environment.  I finally bundled and released all my Audacious hacks together as “Fauxdacious” after adding a VIDEO-playing capability!  As far as themeing goes, Afterstep now supports themes, but I’ve never bothered to bundle the config. files I’ve modified and all the images for release as new “themes”.  I’ve created a few different “theme” configurations that I can switch between when I get tired of one.  With Afterstep, I’ve mastered customizing (the titlebar, the buttons on the titlebar along with their functions) as Afterstep permits you to specify exactly how everything looks.  Then I’ve found themes for Firefox and skins for Fauxdacious/Audacious that closly match.  My favorite color is violet and this is reflected in this desktop.  I used the “Lavafox” theme for Firefox and then created a new “skin” for Fauxdacious/Audacious that I call “Lavadacious” to somewhat match that.  For my Perl/Tk programs, I simiply added “*tkPalette: #160028” and “*tkVpalette: #160028” to my .Xdefaults file.  You can download “Fauxdacious”, “Lavadacious”, “TkWeather”, and many of my other open-source software here at my download site!

Four new Perl modules released to CPAN

Four new Perl modules released to CPAN
I’m pleased to announce the recent release of four (4) shiny new Perl modules to CPANString::Pictureformat, Date::Fmtstr2time, Date::Time2fmtstr, and JDBIx (pronounced “Jaydeebix”).  All four either are or are derived from existing work I’ve done and have been using over the years, but had just never gotten around to fully documenting and testing them to get them in a condition fit for “prime time” release for public consumption.  This included creating proper documentation and test harnesses for each.  The first three modules involve string manipulation functions based on a formatting “mask” string.  JDBIx is a higher-level database manipulation module that makes short work of fetching, inserting, and updating vectors of data by providing a higher level interface to Perl’s fine all-purpose DBI (Database Interface) module.  This has kept me very busy of late documenting, creating test harnesses that satisify the CPAN Testers, fixing a few bugs that affected parts that I rarely used, and even adding a few new features to polish ’em up a bit.  It’s been rather entertaining for me going through some of this “old” code that I wrote years ago.  Some of it is over fifteen years old!  Fortunately for me, I apparently wrote fairly good code then, or at least have gradually cleaned some of it up and documented in fits and starts over the years as I needed it for new jobs and clients along the way.  Anyway, I finally decided to clean ’em all up and make them public (via CPAN), with the side benefit to me of being able to easily install them on new systems via CPAN’s installer the same way most other modules are installed.
This started out as a simple project to get String::Pictureformat to better format dates when using Sql*Perl Plus, another (now massive) “Swiss Army knife” tool I wrote nearly twenty years ago and repeatedly expanded to include new features for various clients and jobs I’ve had over the years.  I decided to get String::Pictureformat cleaned up, and added new date/time handling capabilities and make it public.  However, for dates, it needed two other older functions I had written for DBD::Sprite years ago which were not modular.  So, I decided to make modules out of those two functions, leading to Date::Fmtstr2time and Date::Time2fmtstr!  Now I was on a roll, so I then decided to clean up JDBIx too.  So, what started out as a small project has morphed into a huge undertaking and has taken over a month to complete.
The problem I’ve discovered over the course of the last month or so doing this is a trap that it’s rather easy as a Perl programmer to fall into that’s to some degree related to the Perl philosophy of “there are many ways to do something”.  Wnen I started out writing a module years ago, I would write it to do “this” (a specific thing).  Whilst coding, I’d realize that it was extremely easy to also make it do “this” and “that” too.  I would immediately deploy the module (tool) so I could do “this” regularly and very efficiently.  I’ve continued using the module to do “this” and occasionally “that” over the years without fuss.  A new client would come along and I’d realize that it could and should easily do “the other thing” too.  Sometimes I was fairly good at including decent comments in the code, and even added POD documentation to help me remember the tricky parts.  Now as I attempt to document all the functions and their options, I discover that the module not only does “this”, “that”, and “the other thing”, but I also had coded it to do “this”, “this”, “this”, and “even this” too, but these other rarely or ever used features also contain a few bugs.  As you can see, this made the documentation and testing work much more complicated and time consuming!  Fortunately, the end result is worth it as now I have a module that does this, this, this, even this, that, and the other thing well, is documented for easy lookup, is easily installable from anywhere with an internet connection, will play nice with other modules and programs, and is now freely available for others to avail themselves!
Here are the four modules and their abstracts:

  • String::Pictureformat – Functions to format and unformat strings based on a “Picture” (mask) format string.  Provides format and unformat functions that, given a string of data and a special mask string, will return a string formatted / justified / padded / etc. based on the mask string.  It includes the ability to format dollar values with floating dollar signs, decimals, accounting notation, etc.  It also includes the ability to round to a certain decimal place, and now the ability to format dates and times to desired layouts, word or character wrap long sentence strings, etc.  I originally wrote this for producing much more humanly-readable reports via Sql*Perl Plus.
  • Date::Fmtstr2time – Functions to format and unformat date/time strings into a Perl “Time” integer based on a “Picture” format (mask) string.  This was originally written to add the Oracle(tm) “TO_DATE()” function to my DBD::Sprite flat-file Oracle-simulation module.  It is now used (if installed) by String::Pictureformat for format date / time strings into Unix/Perl “Time” integers.
  • Date::Time2fmtstr – Functions to format and unformat Unix/Perl “Time” integers to strings based on a “Picture” format string.  This was originally written to add the Oracle(tm) “TO_CHAR()” function to my DBD::Sprite flat-file Oracle-simulation module.  It is now used (if installed) by String::Pictureformat for format Unix/Perl “time” integers into pretty, humanly-readable formats as desired.
  • JDBIx – Object-oriented higher-level DBI interface for select into arrays, placeholders, sequences, etc.  This began as a package of a few handy functions to make life developing database-driven programs and websites with Perl’s DBI module much simpler and straight forward by providing simple, one-line functions that could do “select” queries into vector arrays corresponding to columns of data in tables, and take similar vectors of data and insert or update database tables accordingly.  Instead of having to do “prepare()”, “execute()”, “bind()”, “fetch()”, cursors, loops, etc.  Single function calls can handle most “select”, “insert”s, “update”s, and “delete”s in database tables!  I called this package “DBIx” (DBI EXtra), but it was non-modular, having originally been written on the job using Perl 4 and “Oraperl” back in the nineties.  JDBIx combined all this into a modular, object-oriented format permitting multiple databases to be opened and manipulated at once.  I’ve been using JDBIx for several years on some of my own projects and websites, but had never documented it’s functions properly.

Running of the Bulls, by (© 2016) me.
"Running of the Bulls", by (© 2016) me.
This has been somewhat easy since that the holidays are over and the weather’s been cold, and I haven’t wanted to venture outside that much lately.  One of the advantages of Texas Winters is that we do get “breaks” every week or so with a nice cool, but pleasant sunny day randomly thrown in every now and then.  I’ve taken advantage of these lately too, going out with a buddy or two and taking some photos!  Last week, we went Northwest up to Wichita Falls, and stopped in Windthorst, Perrin, Archer City, and a few road-side stops in between.  On another day three of us went and took photos at the Fort Worth Stockyards, including the abandoned Swift meat-packing plant, and the “Running of the Bulls” (a daily longhorn cattle-drive down one of downtown Fort Worth’s major streets) for tourists.  This photo at left shows one of the bulls briefly straying off the street onto the sidewalk.  He appears to have a “bulls eye” on me but quickly rejoins the herd.  Probably just bored and wanted to do something a little different!  Please visit my Flickr site these and other photos.

Get every new post delivered to your Inbox.

%d bloggers like this: