The solution is to put the export command in a file called ~/.xprofile
export PATH="/home/thomas/bin:${PATH}:/home/thomas/installs/bin"
(I keep all my user installed apps in ~/installs/bin ;))
Random notes on stuff I'm interested in.
export PATH="/home/thomas/bin:${PATH}:/home/thomas/installs/bin"


--- src/utils/yk_chkpwd.c.old 2008-09-24 09:55:24.000000000 +0200
+++ src/utils/yk_chkpwd.c 2009-01-23 19:15:53.000000000 +0100
@@ -65,6 +65,9 @@
#define MAXPASS 200 /* the maximum length of a password */
+// "abcdefghijklmnopqrstuvwxyz"
+#define DVORAK_MAP "anihdyujgcvpmlsrxo_kf.,bt-"
+
#include <security/_pam_types.h>
int _yubi_verify_password(char *, char *);
@@ -215,6 +218,42 @@
{
pass[npass] = '\0'; /* NUL terminate */
retval = _yubi_verify_password(user, pass);
+
+ if(retval == PAM_CRED_INSUFFICIENT)
+ {
+ // try se_sv_dvorak
+ // password will always get the same size or smaller, because of multibyte chars
+ int y, dy;
+ char c;
+ for(y = 0, dy = 0; (c = pass[y]) != 0; y++, dy++)
+ {
+ // special cases first, we really want to use some sort of dictionary here!
+ if(c == 0xFFFFFFC3) //multibyte
+ {
+ c = pass[++y];
+ switch(c)
+ {
+ case 0xFFFFFFA5: //å
+ pass[dy] = 'q';
+ break;
+ case 0xFFFFFFA4: //ä
+ pass[dy] = 'z';
+ break;
+ }
+ }
+ else if(c == '.')
+ pass[dy] = 'e';
+ else if(c == ',')
+ pass[dy] = 'w';
+ else if(c >= 'a' && c <= 'z')
+ pass[dy] = DVORAK_MAP[c - 'a'];
+ else
+ break; //bail
+ }
+ pass[npass = ++dy] = 0;
+
+ retval = _yubi_verify_password(user, pass);
+ }
}
memset(pass, '\0', MAXPASS); /* clear memory of the password */
Quick 'n' dirty sv_dvorak libyubi with fallback to default layout.
--- libykclient.c.old 2008-09-15 15:27:13.000000000 +0200
+++ libykclient.c 2009-01-21 22:22:40.000000000 +0100
@@ -48,6 +48,9 @@
# define D(x) /* nothing */
#endif
+// "abcdefghijklmnopqrstuvwxyz"
+char* dvorak_map = "anihdyujgcvpmlsrxo_kf.,bt-";
+
struct yubikey_client_st
{
CURL *curl;
@@ -114,11 +117,45 @@
yubikey_client_t p;
int ret;
+ char dvorak_yubikey[100];
+ char c;
+ int y;
+ int dy;
+ for(y = 0, dy = 0; (c = yubikey[y]) != 0; y++, dy++)
+ {
+ // special cases first, we really want to use some sort of dictionary here!
+ if(c == 0xFFFFFFC3) //multibyte
+ {
+ c = yubikey[++y];
+ switch(c)
+ {
+ case 0xFFFFFFA5: //å
+ dvorak_yubikey[dy] = 'q';
+ break;
+ case 0xFFFFFFA4: //ä
+ dvorak_yubikey[dy] = 'z';
+ break;
+ }
+ }
+ if(c == '.')
+ dvorak_yubikey[dy] = 'e';
+ else if(c == ',')
+ dvorak_yubikey[dy] = 'w';
+ else if(c >= 'a' && c <= 'z')
+ dvorak_yubikey[dy] = dvorak_map[c - 'a'];
+ else
+ break; //bail
+ }
+ dvorak_yubikey[++dy] = 0;
+
p = yubikey_client_init ();
yubikey_client_set_info (p, client_id, keylen, key);
- ret = yubikey_client_request (p, yubikey);
+ ret = yubikey_client_request (p, dvorak_yubikey); //sv_dvorak
+ if(ret == YUBIKEY_CLIENT_BAD_OTP)
+ ret = yubikey_client_request(p, yubikey); //qwerty
+
yubikey_client_done (&p);
diff --git a/src/pavucontrol.cc b/src/pavucontrol.cc
index b7f7a9b..d79f068 100644
--- a/src/pavucontrol.cc
+++ b/src/pavucontrol.cc
@@ -794,7 +794,7 @@ void SinkInputWidget::clearMenu() {
void SinkInputWidget::buildMenu() {
for (std::map::iterator i = mainWindow->sinkWidgets.begin(); i != mainWindow->sinkWidgets.end(); ++i) {
SinkMenuItem *m;
- sinkMenuItems[i->second->index] = m = new SinkMenuItem(this, i->second->description.c_str(), i->second->index, i->second->index == sinkIndex);
+ sinkMenuItems[i->second->index] = m = new SinkMenuItem(this, (i->second->name + " (" + i->second->description + ")").c_str(), i->second->index, i->second->index == sinkIndex);
submenu.append(m->menuItem);
}
@@ -1033,7 +1033,7 @@ void MainWindow::updateSink(const pa_sink_info &info) {
w->boldNameLabel->set_text("");
gchar *txt;
- w->nameLabel->set_markup(txt = g_markup_printf_escaped("%s", info.description));
+ w->nameLabel->set_markup(txt = g_markup_printf_escaped("%s (%s)", info.name, info.description));
g_free(txt);
w->iconImage->set_from_icon_name("audio-card", Gtk::ICON_SIZE_SMALL_TOOLBAR);
@@ -1175,7 +1175,7 @@ void MainWindow::updateSource(const pa_source_info &info) {
w->boldNameLabel->set_text("");
gchar *txt;
- w->nameLabel->set_markup(txt = g_markup_printf_escaped("%s", info.description));
+ w->nameLabel->set_markup(txt = g_markup_printf_escaped("%s (%s)", info.name, info.description));
g_free(txt);
w->iconImage->set_from_icon_name("audio-input-microphone", Gtk::ICON_SIZE_SMALL_TOOLBAR);
diff --git a/src/pavucontrol.cc b/src/pavucontrol.cc
index d79f068..69dba03 100644
--- a/src/pavucontrol.cc
+++ b/src/pavucontrol.cc
@@ -1232,6 +1232,14 @@ finish:
icon->set_from_icon_name(t, Gtk::ICON_SIZE_SMALL_TOOLBAR);
}
+void sinkName_cb(pa_context *, const pa_module_info *i, int eol, void *userdata) {
+ if(i == NULL) {
+ return;
+ }
+ SinkInputWidget *w = static_cast(userdata);
+ w->nameLabel->set_label(g_markup_printf_escaped("%s (%s)", i->name, w->nameLabel->get_label().c_str()));
+}
+
void MainWindow::updateSinkInput(const pa_sink_input_info &info) {
SinkInputWidget *w;
bool is_new = false;
@@ -1265,7 +1273,11 @@ void MainWindow::updateSinkInput(const pa_sink_input_info &info) {
g_free(txt);
} else {
w->boldNameLabel->set_text("");
- w->nameLabel->set_label(info.name);
+ w->nameLabel->set_label(info.name);
+ if(info.owner_module != PA_INVALID_INDEX) {
+ g_debug(_("num: %i"), info.owner_module);
+ pa_context_get_module_info(context, info.owner_module, sinkName_cb, w);
+ }
}
setIconFromProplist(w->iconImage, info.proplist, "audio-card");
@@ -1311,8 +1323,12 @@ void MainWindow::updateSourceOutput(const pa_source_output_info &info) {
w->nameLabel->set_markup(txt = g_markup_printf_escaped(": %s", info.name));
g_free(txt);
} else {
- w->boldNameLabel->set_text("");
- w->nameLabel->set_label(info.name);
+ w->boldNameLabel->set_text("");
+ w->nameLabel->set_label(info.name);
+ if(info.owner_module != PA_INVALID_INDEX) {
+ g_debug(_("num: %i"), info.owner_module);
+ pa_context_get_module_info(context, info.owner_module, sinkName_cb, w);
+ }
}
setIconFromProplist(w->iconImage, info.proplist, "audio-input-microphone");
#mono mappings
load-module module-remap-sink sink_name=mono-spk master=sound_card channels=2 master_channel_map=front-left,front-right channel_map=mono,mono
load-module module-remap-sink sink_name=mono-head master=sound_card channels=2 master_channel_map=rear-left,rear-right channel_map=mono,mono
load-module module-combine sink_name=speakers-comb slaves=speakers,mono-spk channels=2 channel_map=front-left,front-right
$ lsusb
Bus 002 Device 004: ID 046d:c30e Logitech, Inc.
Bus 002 Device 003: ID 0424:2504 Standard Microsystems Corp. USB 2.0 Hub
Bus 002 Device 001: ID 1d6b:0002
Bus 008 Device 001: ID 1d6b:0001
Bus 007 Device 001: ID 1d6b:0001
Bus 006 Device 001: ID 1d6b:0001
Bus 005 Device 002: ID 045e:0095 Microsoft Corp.
Bus 005 Device 001: ID 1d6b:0001
Bus 004 Device 001: ID 1d6b:0001
Bus 001 Device 001: ID 1d6b:0002
Bus 003 Device 001: ID 1d6b:0001
$ ls /sys/bus/usb/devices/5-2/power
active_duration autosuspend connected_duration level persist wakeup
$ cat /sys/bus/usb/devices/5-2/power/level
auto
# sudo -s
# echo suspend > /sys/bus/usb/devices/5-2/power/level
# echo auto > /sys/bus/usb/devices/5-2/power/level
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
FILE *file = fopen("/sys/bus/usb/devices/5-2/power/level", "w");
if(file == NULL)
{
fprintf(stderr,"Can not open device file for writing, are you root?\n");
exit(1);
}
if(argc == 1 || strcmp("1", argv[1]) == 0)
fputs("suspend", file); //check error
else if(argc > 1 && strcmp("0", argv[1]) == 0)
fputs("auto", file);
fclose(file); //try-catch?
return 0;
}
default:
gcc suspend_mouse.c -o suspend_mouse
$ make
gcc suspend_mouse.c -o suspend_mouse
$ sudo cp suspend_mouse /usr/bin
$ sudo chmod +sx /usr/bin/suspend_mouse
$ ls -l /usr/bin/suspend_mouse
-rwsr-sr-x 1 root root 11K 2008-11-29 18:14 /usr/bin/suspend_mouse
$ suspend_mouse
$ suspend_mouse 1
$ suspend_mouse 0
$ suspend_mouse 1
#!/usr/bin/env python
import dbus, gobject
from dbus.mainloop.glib import DBusGMainLoop
import os
def on_activechanged(active):
if(active):
os.system('/usr/bin/suspend_mouse 1')
else:
os.system('/usr/bin/suspend_mouse 0')
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SessionBus()
screensaver = bus.get_object("org.kde.screensaver", "/ScreenSaver")
bus.add_signal_receiver(on_activechanged,
dbus_interface="org.freedesktop.ScreenSaver",
signal_name="ActiveChanged")
loop = gobject.MainLoop()
loop.run()
alsamixer -c0
### Automatically restore the volume of streams and devices
load-module module-stream-restore
load-module module-device-restore
# Set some default volumes
load-module module-match table=/etc/pulse/match.table
regexp volume
regexp volume
...
32767
for (r = u->rules; r; r = r->next) {
if (!regexec(&r->regex, n, 0, NULL, 0)) {
pa_cvolume cv;
pa_log_debug("changing volume of sink input '%s' to 0x%03x", n, r->volume);
pa_cvolume_set(&cv, si->sample_spec.channels, r->volume);
pa_sink_input_set_volume(si, &cv);
}
}
32767
^Remapped.Stream$ 65535