1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-19 12:28:22 +01:00
Files
wmaker/WPrefs.app/MouseSettings.c
Christophe CURIS 0382dd5dd7 WPrefs: Fixed empty list of Mouse Grab Modifier problem
The original code was assuming that the Xkb extension is available
everywhere, which is not the case. This resulted in all modifiers
to be seen as NoSymbol, thus the empty list.

Now we initialize properly the Xkb extension at the start of the
program, and provide a work-around with the historical function in
the case the ext would not be available.

Signed-off-by: Christophe CURIS <christophe.curis@free.fr>
2013-06-16 18:53:05 +01:00

810 lines
20 KiB
C

/* MouseSettings.c- mouse options (some are equivalent to xset)
*
* WPrefs - Window Maker Preferences Program
*
* Copyright (c) 1998-2003 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "WPrefs.h"
#include <X11/Xutil.h>
#include <X11/XKBlib.h>
#include <unistd.h>
#include <math.h>
#define XSET "xset"
typedef struct _Panel {
WMBox *box;
char *sectionName;
char *description;
CallbackRec callbacks;
WMWidget *parent;
WMFrame *speedF;
WMLabel *speedL;
WMSlider *speedS;
WMLabel *acceL;
WMTextField *acceT;
WMLabel *threL;
WMTextField *threT;
WMFrame *ddelaF;
WMButton *ddelaB[5];
WMTextField *ddelaT;
WMLabel *ddelaL;
DoubleTest *tester;
WMFrame *menuF;
WMLabel *button1L;
WMLabel *button2L;
WMLabel *button3L;
WMLabel *wheelL;
WMPopUpButton *button1P;
WMPopUpButton *button2P;
WMPopUpButton *button3P;
WMPopUpButton *wheelP;
WMButton *disaB;
WMFrame *grabF;
WMPopUpButton *grabP;
/**/ int maxThreshold;
float acceleration;
} _Panel;
#define ICON_FILE "mousesettings"
#define SPEED_ICON_FILE "mousespeed"
#define DELAY_ICON "timer%i"
#define DELAY_ICON_S "timer%is"
/* need access to the double click variables */
#include <WINGs/WINGsP.h>
static char *modifierNames[8];
static char *buttonActions[4];
static char *wheelActions[2];
#define DELAY(i) ((i)*75+170)
static void setMouseAccel(WMScreen * scr, float accel, int threshold)
{
int n, d;
d = 10;
n = accel * d;
XChangePointerControl(WMScreenDisplay(scr), True, True, n, d, threshold);
}
static void speedChange(WMWidget * w, void *data)
{
_Panel *panel = (_Panel *) data;
int i;
char buffer[64];
int threshold;
char *tmp;
if (w == NULL) {
float accel;
tmp = WMGetTextFieldText(panel->acceT);
if (sscanf(tmp, "%f", &accel) != 1 || accel < 0) {
WMRunAlertPanel(WMWidgetScreen(panel->acceT), GetWindow(panel),
_("Error"),
_("Invalid mouse acceleration value. Must be a positive real value."),
_("OK"), NULL, NULL);
wfree(tmp);
return;
}
panel->acceleration = accel;
wfree(tmp);
} else {
i = (int)WMGetSliderValue(panel->speedS);
panel->acceleration = 0.25 + (i * 0.25);
sprintf(buffer, "%.2f", 0.25 + (i * 0.25));
WMSetTextFieldText(panel->acceT, buffer);
}
tmp = WMGetTextFieldText(panel->threT);
if (sscanf(tmp, "%i", &threshold) != 1 || threshold < 0 || threshold > panel->maxThreshold) {
WMRunAlertPanel(WMWidgetScreen(panel->parent), GetWindow(panel), _("Error"),
_
("Invalid mouse acceleration threshold value. Must be the number of pixels to travel before accelerating."),
_("OK"), NULL, NULL);
} else {
setMouseAccel(WMWidgetScreen(panel->parent), panel->acceleration, threshold);
}
wfree(tmp);
}
static void returnPressed(void *observerData, WMNotification * notification)
{
_Panel *panel = (_Panel *) observerData;
speedChange(NULL, panel);
}
static void doubleClick(WMWidget * w, void *data)
{
_Panel *panel = (_Panel *) data;
int i;
char buffer[32];
for (i = 0; i < 5; i++) {
if (panel->ddelaB[i] == w)
break;
}
WINGsConfiguration.doubleClickDelay = DELAY(i);
sprintf(buffer, "%i", DELAY(i));
WMSetTextFieldText(panel->ddelaT, buffer);
}
static int getButtonAction(const char *str)
{
if (!str)
return -2;
if (strcasecmp(str, "None") == 0)
return 0;
else if (strcasecmp(str, "OpenApplicationsMenu") == 0)
return 1;
else if (strcasecmp(str, "OpenWindowListMenu") == 0)
return 2;
else if (strcasecmp(str, "SelectWindows") == 0)
return 3;
else
return -1;
}
static int getWheelAction(const char *str)
{
if (!str)
return -2;
if (strcasecmp(str, "None") == 0)
return 0;
else if (strcasecmp(str, "SwitchWorkspaces") == 0)
return 1;
else
return -1;
}
static void getMouseParameters(Display * dpy, float *accel, int *thre)
{
int n, d;
XGetPointerControl(dpy, &n, &d, thre);
*accel = (float)n / (float)d;
}
static void showData(_Panel * panel)
{
char *str;
int i;
int a = -1, b = -1, c = -1, w = -1;
float accel;
char buffer[32];
Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->parent));
str = GetStringForKey("MouseLeftButtonAction");
i = getButtonAction(str);
if (i < 0) {
a = 3;
if (i == -1) {
wwarning(_("bad value %s for option %s"), str, "MouseLeftButtonAction");
}
} else {
a = i;
}
WMSetPopUpButtonSelectedItem(panel->button1P, a);
str = GetStringForKey("MouseMiddleButtonAction");
i = getButtonAction(str);
if (i < 0) {
b = 2;
if (i == -1) {
wwarning(_("bad value %s for option %s"), str, "MouseMiddleButtonAction");
}
} else {
b = i;
}
WMSetPopUpButtonSelectedItem(panel->button2P, b);
str = GetStringForKey("MouseRightButtonAction");
i = getButtonAction(str);
if (i < 0) {
c = 1;
if (i == -1) {
wwarning(_("bad value %s for option %s"), str, "MouseRightButtonAction");
}
} else {
c = i;
}
WMSetPopUpButtonSelectedItem(panel->button3P, c);
str = GetStringForKey("MouseWheelAction");
i = getWheelAction(str);
if (i < 0) {
w = 0;
if (i == -1) {
wwarning(_("bad value %s for option %s"), str, "MouseWheelAction");
}
} else {
w = i;
}
WMSetPopUpButtonSelectedItem(panel->wheelP, w);
WMSetButtonSelected(panel->disaB, GetBoolForKey("DisableWSMouseActions"));
/**/ getMouseParameters(dpy, &accel, &a);
panel->maxThreshold = WidthOfScreen(DefaultScreenOfDisplay(dpy));
if (a > panel->maxThreshold) {
panel->maxThreshold = a;
}
sprintf(buffer, "%i", a);
WMSetTextFieldText(panel->threT, buffer);
WMSetSliderValue(panel->speedS, (accel - 0.25) / 0.25);
panel->acceleration = accel;
sprintf(buffer, "%.2f", accel);
WMSetTextFieldText(panel->acceT, buffer);
/**/ b = GetIntegerForKey("DoubleClickTime");
/* find best match */
a = -1;
for (i = 0; i < 5; i++) {
if (DELAY(i) == b)
a = i;
}
if (a >= 0)
WMPerformButtonClick(panel->ddelaB[a]);
sprintf(buffer, "%i", b);
WMSetTextFieldText(panel->ddelaT, buffer);
/**/ str = GetStringForKey("ModifierKey");
if (!str)
str = "mod1";
a = ModifierFromKey(dpy, str);
if (a != -1) {
str = modifierNames[a];
a = 0;
for (i = 0; i < WMGetPopUpButtonNumberOfItems(panel->grabP); i++) {
if (strstr(WMGetPopUpButtonItem(panel->grabP, i), str)) {
WMSetPopUpButtonSelectedItem(panel->grabP, i);
a = 1;
break;
}
}
}
if (a < 1) {
char *previous;
previous = WMGetPopUpButtonItem(panel->grabP, 0);
if (previous != NULL)
WMSetPopUpButtonSelectedItem(panel->grabP, 0);
wwarning(_("modifier key %s for option ModifierKey was not recognized. Using %s as default"),
str, previous?previous:"(empty)");
}
}
static void fillModifierPopUp(WMPopUpButton * pop)
{
XModifierKeymap *mapping;
Display *dpy = WMScreenDisplay(WMWidgetScreen(pop));
int i, j;
char *str;
char buffer[64];
mapping = XGetModifierMapping(dpy);
if (!mapping || mapping->max_keypermod == 0) {
WMAddPopUpButtonItem(pop, "Mod1");
WMAddPopUpButtonItem(pop, "Mod2");
WMAddPopUpButtonItem(pop, "Mod3");
WMAddPopUpButtonItem(pop, "Mod4");
WMAddPopUpButtonItem(pop, "Mod5");
wwarning(_("could not retrieve keyboard modifier mapping"));
return;
}
for (j = 0; j < 8; j++) {
int idx;
char *array[8];
int a;
KeySym ksym;
int k;
char *ptr;
char *tmp;
a = 0;
memset(array, 0, sizeof(char *) * 8);
for (i = 0; i < mapping->max_keypermod; i++) {
idx = i + j * mapping->max_keypermod;
if (mapping->modifiermap[idx] != 0) {
int l;
for (l = 0; l < 4; l++) {
if (xext_xkb_supported)
ksym = XkbKeycodeToKeysym(dpy, mapping->modifiermap[idx], 0, l);
else
ksym = XKeycodeToKeysym(dpy, mapping->modifiermap[idx], 0);
if (ksym != NoSymbol)
break;
}
if (ksym != NoSymbol)
str = XKeysymToString(ksym);
else
str = NULL;
if (str && !strstr(str, "_Lock") && !strstr(str, "Shift")
&& !strstr(str, "Control")) {
array[a++] = wstrdup(str);
}
}
}
for (k = 0; k < a; k++) {
if (array[k] == NULL)
continue;
tmp = wstrdup(array[k]);
ptr = strstr(tmp, "_L");
if (ptr)
*ptr = 0;
ptr = strstr(tmp, "_R");
if (ptr)
*ptr = 0;
sprintf(buffer, "%s (%s)", modifierNames[j], tmp);
/*sprintf(buffer, "%s", tmp); */
WMAddPopUpButtonItem(pop, buffer);
for (i = k + 1; i < a; i++) {
if (array[i] == NULL)
continue;
if (strstr(array[i], tmp)) {
wfree(array[i]);
array[i] = NULL;
break;
}
}
wfree(tmp);
}
while (--a > 0) {
if (array[a])
wfree(array[a]);
}
}
if (mapping)
XFreeModifiermap(mapping);
}
static void createPanel(Panel * p)
{
_Panel *panel = (_Panel *) p;
WMScreen *scr = WMWidgetScreen(panel->parent);
WMPixmap *icon;
char *buf1, *buf2;
int i;
RColor color;
char *path;
color.red = 0xae;
color.green = 0xaa;
color.blue = 0xae;
panel->box = WMCreateBox(panel->parent);
WMSetViewExpandsToParent(WMWidgetView(panel->box), 2, 2, 2, 2);
/**************** Mouse Speed ****************/
panel->speedF = WMCreateFrame(panel->box);
WMResizeWidget(panel->speedF, 245, 100);
WMMoveWidget(panel->speedF, 15, 5);
WMSetFrameTitle(panel->speedF, _("Mouse Speed"));
panel->speedL = WMCreateLabel(panel->speedF);
WMResizeWidget(panel->speedL, 40, 46);
WMMoveWidget(panel->speedL, 15, 14);
WMSetLabelImagePosition(panel->speedL, WIPImageOnly);
path = LocateImage(SPEED_ICON_FILE);
if (path) {
icon = WMCreateBlendedPixmapFromFile(scr, path, &color);
if (icon) {
WMSetLabelImage(panel->speedL, icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon %s"), path);
}
wfree(path);
}
panel->speedS = WMCreateSlider(panel->speedF);
WMResizeWidget(panel->speedS, 160, 15);
WMMoveWidget(panel->speedS, 70, 35);
WMSetSliderMinValue(panel->speedS, 0);
WMSetSliderMaxValue(panel->speedS, 40);
WMSetSliderContinuous(panel->speedS, False);
WMSetSliderAction(panel->speedS, speedChange, panel);
panel->acceL = WMCreateLabel(panel->speedF);
WMResizeWidget(panel->acceL, 70, 16);
WMMoveWidget(panel->acceL, 10, 67);
WMSetLabelTextAlignment(panel->acceL, WARight);
WMSetLabelText(panel->acceL, _("Acceler.:"));
panel->acceT = WMCreateTextField(panel->speedF);
WMResizeWidget(panel->acceT, 40, 20);
WMMoveWidget(panel->acceT, 80, 65);
WMAddNotificationObserver(returnPressed, panel, WMTextDidEndEditingNotification, panel->acceT);
panel->threL = WMCreateLabel(panel->speedF);
WMResizeWidget(panel->threL, 80, 16);
WMMoveWidget(panel->threL, 120, 67);
WMSetLabelTextAlignment(panel->threL, WARight);
WMSetLabelText(panel->threL, _("Threshold:"));
panel->threT = WMCreateTextField(panel->speedF);
WMResizeWidget(panel->threT, 30, 20);
WMMoveWidget(panel->threT, 200, 65);
WMAddNotificationObserver(returnPressed, panel, WMTextDidEndEditingNotification, panel->threT);
WMMapSubwidgets(panel->speedF);
/***************** Doubleclick Delay ****************/
panel->ddelaF = WMCreateFrame(panel->box);
WMResizeWidget(panel->ddelaF, 245, 105);
WMMoveWidget(panel->ddelaF, 15, 115);
WMSetFrameTitle(panel->ddelaF, _("Double-Click Delay"));
buf1 = wmalloc(strlen(DELAY_ICON) + 2);
buf2 = wmalloc(strlen(DELAY_ICON_S) + 2);
for (i = 0; i < 5; i++) {
panel->ddelaB[i] = WMCreateCustomButton(panel->ddelaF, WBBStateChangeMask);
WMResizeWidget(panel->ddelaB[i], 25, 25);
WMMoveWidget(panel->ddelaB[i], 30 + (40 * i), 25);
WMSetButtonBordered(panel->ddelaB[i], False);
WMSetButtonImagePosition(panel->ddelaB[i], WIPImageOnly);
WMSetButtonAction(panel->ddelaB[i], doubleClick, panel);
if (i > 0) {
WMGroupButtons(panel->ddelaB[0], panel->ddelaB[i]);
}
sprintf(buf1, DELAY_ICON, i + 1);
sprintf(buf2, DELAY_ICON_S, i + 1);
path = LocateImage(buf1);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonImage(panel->ddelaB[i], icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
wfree(path);
}
path = LocateImage(buf2);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonAltImage(panel->ddelaB[i], icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
wfree(path);
}
}
wfree(buf1);
wfree(buf2);
panel->tester = CreateDoubleTest(panel->ddelaF, _("Test"));
WMResizeWidget(panel->tester, 84, 29);
WMMoveWidget(panel->tester, 35, 60);
panel->ddelaT = WMCreateTextField(panel->ddelaF);
WMResizeWidget(panel->ddelaT, 40, 20);
WMMoveWidget(panel->ddelaT, 140, 65);
panel->ddelaL = WMCreateLabel(panel->ddelaF);
WMResizeWidget(panel->ddelaL, 40, 16);
WMMoveWidget(panel->ddelaL, 185, 70);
{
WMFont *font;
WMColor *color;
font = WMSystemFontOfSize(scr, 10);
color = WMDarkGrayColor(scr);
WMSetLabelTextColor(panel->ddelaL, color);
WMSetLabelFont(panel->ddelaL, font);
WMReleaseFont(font);
WMReleaseColor(color);
}
WMSetLabelText(panel->ddelaL, _("msec"));
WMMapSubwidgets(panel->ddelaF);
/* ************** Workspace Action Buttons **************** */
panel->menuF = WMCreateFrame(panel->box);
WMResizeWidget(panel->menuF, 240, 160);
WMMoveWidget(panel->menuF, 270, 5);
WMSetFrameTitle(panel->menuF, _("Workspace Mouse Actions"));
panel->disaB = WMCreateSwitchButton(panel->menuF);
WMResizeWidget(panel->disaB, 205, 18);
WMMoveWidget(panel->disaB, 10, 18);
WMSetButtonText(panel->disaB, _("Disable mouse actions"));
panel->button1L = WMCreateLabel(panel->menuF);
WMResizeWidget(panel->button1L, 87, 20);
WMMoveWidget(panel->button1L, 5, 45);
WMSetLabelTextAlignment(panel->button1L, WARight);
WMSetLabelText(panel->button1L, _("Left Button"));
panel->button1P = WMCreatePopUpButton(panel->menuF);
WMResizeWidget(panel->button1P, 135, 20);
WMMoveWidget(panel->button1P, 95, 45);
panel->button2L = WMCreateLabel(panel->menuF);
WMResizeWidget(panel->button2L, 87, 20);
WMMoveWidget(panel->button2L, 5, 73);
WMSetLabelTextAlignment(panel->button2L, WARight);
WMSetLabelText(panel->button2L, _("Middle Button"));
panel->button2P = WMCreatePopUpButton(panel->menuF);
WMResizeWidget(panel->button2P, 135, 20);
WMMoveWidget(panel->button2P, 95, 73);
panel->button3L = WMCreateLabel(panel->menuF);
WMResizeWidget(panel->button3L, 87, 20);
WMMoveWidget(panel->button3L, 5, 101);
WMSetLabelTextAlignment(panel->button3L, WARight);
WMSetLabelText(panel->button3L, _("Right Button"));
panel->button3P = WMCreatePopUpButton(panel->menuF);
WMResizeWidget(panel->button3P, 135, 20);
WMMoveWidget(panel->button3P, 95, 101);
panel->wheelL = WMCreateLabel(panel->menuF);
WMResizeWidget(panel->wheelL, 87, 20);
WMMoveWidget(panel->wheelL, 5, 129);
WMSetLabelTextAlignment(panel->wheelL, WARight);
WMSetLabelText(panel->wheelL, _("Mouse Wheel"));
panel->wheelP = WMCreatePopUpButton(panel->menuF);
WMResizeWidget(panel->wheelP, 135, 20);
WMMoveWidget(panel->wheelP, 95, 129);
for (i = 0; i < sizeof(buttonActions) / sizeof(buttonActions[0]); i++) {
WMAddPopUpButtonItem(panel->button1P, buttonActions[i]);
WMAddPopUpButtonItem(panel->button2P, buttonActions[i]);
WMAddPopUpButtonItem(panel->button3P, buttonActions[i]);
}
for (i = 0; i < sizeof(wheelActions) / sizeof(wheelActions[0]); i++) {
WMAddPopUpButtonItem(panel->wheelP, wheelActions[i]);
}
WMMapSubwidgets(panel->menuF);
/* ************** Grab Modifier **************** */
panel->grabF = WMCreateFrame(panel->box);
WMResizeWidget(panel->grabF, 240, 50);
WMMoveWidget(panel->grabF, 270, 170);
WMSetFrameTitle(panel->grabF, _("Mouse Grab Modifier"));
WMSetBalloonTextForView(_("Keyboard modifier to use for actions that\n"
"involve dragging windows with the mouse,\n"
"clicking inside the window."), WMWidgetView(panel->grabF));
panel->grabP = WMCreatePopUpButton(panel->grabF);
WMResizeWidget(panel->grabP, 160, 20);
WMMoveWidget(panel->grabP, 40, 20);
fillModifierPopUp(panel->grabP);
WMMapSubwidgets(panel->grabF);
WMRealizeWidget(panel->box);
WMMapSubwidgets(panel->box);
showData(panel);
}
static void storeCommandInScript(const char *cmd, const char *line)
{
char *path;
FILE *f;
char buffer[128];
path = wstrconcat(wusergnusteppath(), "/Library/WindowMaker/autostart");
f = fopen(path, "rb");
if (!f) {
f = fopen(path, "wb");
if (!f) {
werror(_("could not create %s"), path);
goto end;
}
fprintf(f, "#!/bin/sh\n");
fputs(line, f);
fputs("\n", f);
} else {
int len = strlen(cmd);
int ok = 0;
char *tmppath;
FILE *fo;
tmppath = wstrconcat(wusergnusteppath(), "/Library/WindowMaker/autostart.tmp");
fo = fopen(tmppath, "wb");
if (!fo) {
werror(_("could not create temporary file %s"), tmppath);
wfree(tmppath);
goto end;
}
while (!feof(f)) {
if (!fgets(buffer, 127, f)) {
break;
}
if (buffer[0] == '\n') {
/* don't write empty lines, else the file will grow
* indefinitely (one '\n' added at end of file on each save).
*/
continue;
}
if (strncmp(buffer, cmd, len) == 0) {
if (!ok) {
fputs(line, fo);
fputs("\n", fo);
ok = 1;
}
} else {
fputs(buffer, fo);
}
}
if (!ok) {
fputs(line, fo);
fputs("\n", fo);
}
fsync(fileno(fo));
fclose(fo);
if (rename(tmppath, path) != 0) {
werror(_("could not rename file %s to %s"), tmppath, path);
}
wfree(tmppath);
}
sprintf(buffer, "chmod u+x %s", path);
system(buffer);
end:
wfree(path);
if (f) {
fsync(fileno(f)); /* this may be rw */
fclose(f);
}
}
static void storeData(_Panel * panel)
{
char buffer[64];
int i;
char *tmp, *p;
static char *button[4] = { "None", "OpenApplicationsMenu", "OpenWindowListMenu", "SelectWindows" };
static char *wheel[2] = { "None", "SwitchWorkspaces" };
WMUserDefaults *udb = WMGetStandardUserDefaults();
if (!WMGetUDBoolForKey(udb, "NoXSetStuff")) {
tmp = WMGetTextFieldText(panel->threT);
if (strlen(tmp) == 0) {
wfree(tmp);
tmp = wstrdup("4");
}
sprintf(buffer, XSET " m %i/%i %s\n", (int)(panel->acceleration * 10), 10, tmp);
storeCommandInScript(XSET " m", buffer);
wfree(tmp);
}
tmp = WMGetTextFieldText(panel->ddelaT);
if (sscanf(tmp, "%i", &i) == 1 && i > 0)
SetIntegerForKey(i, "DoubleClickTime");
SetBoolForKey(WMGetButtonSelected(panel->disaB), "DisableWSMouseActions");
i = WMGetPopUpButtonSelectedItem(panel->button1P);
SetStringForKey(button[i], "MouseLeftButtonAction");
i = WMGetPopUpButtonSelectedItem(panel->button2P);
SetStringForKey(button[i], "MouseMiddleButtonAction");
i = WMGetPopUpButtonSelectedItem(panel->button3P);
SetStringForKey(button[i], "MouseRightButtonAction");
i = WMGetPopUpButtonSelectedItem(panel->wheelP);
SetStringForKey(wheel[i], "MouseWheelAction");
tmp = WMGetPopUpButtonItem(panel->grabP, WMGetPopUpButtonSelectedItem(panel->grabP));
tmp = wstrdup(tmp);
p = strchr(tmp, ' ');
*p = 0;
SetStringForKey(tmp, "ModifierKey");
wfree(tmp);
}
Panel *InitMouseSettings(WMScreen * scr, WMWidget * parent)
{
_Panel *panel;
modifierNames[0] = wstrdup(_("Shift"));
modifierNames[1] = wstrdup(_("Lock"));
modifierNames[2] = wstrdup(_("Control"));
modifierNames[3] = wstrdup(_("Mod1"));
modifierNames[4] = wstrdup(_("Mod2"));
modifierNames[5] = wstrdup(_("Mod3"));
modifierNames[6] = wstrdup(_("Mod4"));
modifierNames[7] = wstrdup(_("Mod5"));
buttonActions[0] = wstrdup(_("None"));
buttonActions[1] = wstrdup(_("Applications Menu"));
buttonActions[2] = wstrdup(_("Window List Menu"));
buttonActions[3] = wstrdup(_("Select Windows"));
wheelActions[0] = wstrdup(_("None"));
wheelActions[1] = wstrdup(_("Switch Workspaces"));
panel = wmalloc(sizeof(_Panel));
panel->sectionName = _("Mouse Preferences");
panel->description = _("Mouse speed/acceleration, double click delay,\n" "mouse button bindings etc.");
panel->parent = parent;
panel->callbacks.createWidgets = createPanel;
panel->callbacks.updateDomain = storeData;
AddSection(panel, ICON_FILE);
return panel;
}