Change to the linux kernel coding style
[wmaker-crm.git] / WPrefs.app / MouseSettings.c
1
2 /* MouseSettings.c- mouse options (some are equivalent to xset)
3  *
4  *  WPrefs - Window Maker Preferences Program
5  *
6  *  Copyright (c) 1998-2003 Alfredo K. Kojima
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21  *  USA.
22  */
23
24 #include "WPrefs.h"
25
26 #include <X11/Xutil.h>
27
28 #include <math.h>
29
30 /* double-click tester */
31 #include "double.h"
32
33 #define XSET    "xset"
34
35 typedef struct _Panel {
36         WMBox *box;
37
38         char *sectionName;
39
40         char *description;
41
42         CallbackRec callbacks;
43
44         WMWidget *parent;
45
46         WMFrame *speedF;
47         WMLabel *speedL;
48         WMSlider *speedS;
49         WMLabel *acceL;
50         WMTextField *acceT;
51         WMLabel *threL;
52         WMTextField *threT;
53
54         WMFrame *ddelaF;
55         WMButton *ddelaB[5];
56         WMTextField *ddelaT;
57         WMLabel *ddelaL;
58         DoubleTest *tester;
59
60         WMFrame *menuF;
61         WMLabel *button1L;
62         WMLabel *button2L;
63         WMLabel *button3L;
64         WMLabel *wheelL;
65         WMPopUpButton *button1P;
66         WMPopUpButton *button2P;
67         WMPopUpButton *button3P;
68         WMPopUpButton *wheelP;
69
70         WMButton *disaB;
71
72         WMFrame *grabF;
73         WMPopUpButton *grabP;
74
75          /**/ int maxThreshold;
76         float acceleration;
77 } _Panel;
78
79 #define ICON_FILE "mousesettings"
80
81 #define SPEED_ICON_FILE "mousespeed"
82
83 #define DELAY_ICON "timer%i"
84 #define DELAY_ICON_S "timer%is"
85
86 /* need access to the double click variables */
87 #include <WINGs/WINGsP.h>
88
89 static char *modifierNames[8];
90
91 static char *buttonActions[4];
92
93 static char *wheelActions[2];
94
95 #define DELAY(i)                ((i)*75+170)
96
97 int ModifierFromKey(Display * dpy, char *key);
98
99 static void setMouseAccel(WMScreen * scr, float accel, int threshold)
100 {
101         int n, d;
102
103         d = 10;
104         n = accel * d;
105
106         XChangePointerControl(WMScreenDisplay(scr), True, True, n, d, threshold);
107 }
108
109 static void speedChange(WMWidget * w, void *data)
110 {
111         _Panel *panel = (_Panel *) data;
112         int i;
113         char buffer[64];
114         int threshold;
115         char *tmp;
116
117         if (w == NULL) {
118                 float accel;
119
120                 tmp = WMGetTextFieldText(panel->acceT);
121                 if (sscanf(tmp, "%f", &accel) != 1 || accel < 0) {
122                         WMRunAlertPanel(WMWidgetScreen(panel->acceT), GetWindow(panel),
123                                         _("Error"),
124                                         _("Invalid mouse acceleration value. Must be a positive real value."),
125                                         _("OK"), NULL, NULL);
126                         wfree(tmp);
127                         return;
128                 }
129                 panel->acceleration = accel;
130                 wfree(tmp);
131         } else {
132                 i = (int)WMGetSliderValue(panel->speedS);
133
134                 panel->acceleration = 0.25 + (i * 0.25);
135
136                 sprintf(buffer, "%.2f", 0.25 + (i * 0.25));
137                 WMSetTextFieldText(panel->acceT, buffer);
138         }
139
140         tmp = WMGetTextFieldText(panel->threT);
141         if (sscanf(tmp, "%i", &threshold) != 1 || threshold < 0 || threshold > panel->maxThreshold) {
142                 WMRunAlertPanel(WMWidgetScreen(panel->parent), GetWindow(panel), _("Error"),
143                                 _
144                                 ("Invalid mouse acceleration threshold value. Must be the number of pixels to travel before accelerating."),
145                                 _("OK"), NULL, NULL);
146         } else {
147                 setMouseAccel(WMWidgetScreen(panel->parent), panel->acceleration, threshold);
148         }
149         wfree(tmp);
150 }
151
152 static void returnPressed(void *observerData, WMNotification * notification)
153 {
154         _Panel *panel = (_Panel *) observerData;
155
156         speedChange(NULL, panel);
157 }
158
159 static void doubleClick(WMWidget * w, void *data)
160 {
161         _Panel *panel = (_Panel *) data;
162         int i;
163         extern _WINGsConfiguration WINGsConfiguration;
164         char buffer[32];
165
166         for (i = 0; i < 5; i++) {
167                 if (panel->ddelaB[i] == w)
168                         break;
169         }
170         WINGsConfiguration.doubleClickDelay = DELAY(i);
171
172         sprintf(buffer, "%i", DELAY(i));
173         WMSetTextFieldText(panel->ddelaT, buffer);
174 }
175
176 static int getButtonAction(char *str)
177 {
178         if (!str)
179                 return -2;
180
181         if (strcasecmp(str, "None") == 0)
182                 return 0;
183         else if (strcasecmp(str, "OpenApplicationsMenu") == 0)
184                 return 1;
185         else if (strcasecmp(str, "OpenWindowListMenu") == 0)
186                 return 2;
187         else if (strcasecmp(str, "SelectWindows") == 0)
188                 return 3;
189         else
190                 return -1;
191
192 }
193
194 static int getWheelAction(char *str)
195 {
196         if (!str)
197                 return -2;
198
199         if (strcasecmp(str, "None") == 0)
200                 return 0;
201         else if (strcasecmp(str, "SwitchWorkspaces") == 0)
202                 return 1;
203         else
204                 return -1;
205
206 }
207
208 static void getMouseParameters(Display * dpy, float *accel, int *thre)
209 {
210         int n, d;
211
212         XGetPointerControl(dpy, &n, &d, thre);
213
214         *accel = (float)n / (float)d;
215 }
216
217 static void showData(_Panel * panel)
218 {
219         char *str;
220         int i;
221         int a = -1, b = -1, c = -1, w = -1;
222         float accel;
223         char buffer[32];
224         Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->parent));
225
226         str = GetStringForKey("MouseLeftButtonAction");
227         i = getButtonAction(str);
228         if (i < 0) {
229                 a = 3;
230                 if (i == -1) {
231                         wwarning(_("bad value %s for option %s"), str, "MouseLeftButtonAction");
232                 }
233         } else {
234                 a = i;
235         }
236         WMSetPopUpButtonSelectedItem(panel->button1P, a);
237
238         str = GetStringForKey("MouseMiddleButtonAction");
239         i = getButtonAction(str);
240         if (i < 0) {
241                 b = 2;
242                 if (i == -1) {
243                         wwarning(_("bad value %s for option %s"), str, "MouseMiddleButtonAction");
244                 }
245         } else {
246                 b = i;
247         }
248         WMSetPopUpButtonSelectedItem(panel->button2P, b);
249
250         str = GetStringForKey("MouseRightButtonAction");
251         i = getButtonAction(str);
252         if (i < 0) {
253                 c = 1;
254                 if (i == -1) {
255                         wwarning(_("bad value %s for option %s"), str, "MouseRightButtonAction");
256                 }
257         } else {
258                 c = i;
259         }
260         WMSetPopUpButtonSelectedItem(panel->button3P, c);
261
262         str = GetStringForKey("MouseWheelAction");
263         i = getWheelAction(str);
264         if (i < 0) {
265                 w = 0;
266                 if (i == -1) {
267                         wwarning(_("bad value %s for option %s"), str, "MouseWheelAction");
268                 }
269         } else {
270                 w = i;
271         }
272         WMSetPopUpButtonSelectedItem(panel->wheelP, w);
273
274         WMSetButtonSelected(panel->disaB, GetBoolForKey("DisableWSMouseActions"));
275
276          /**/ getMouseParameters(dpy, &accel, &a);
277         panel->maxThreshold = WidthOfScreen(DefaultScreenOfDisplay(dpy));
278         if (a > panel->maxThreshold) {
279                 panel->maxThreshold = a;
280         }
281         sprintf(buffer, "%i", a);
282         WMSetTextFieldText(panel->threT, buffer);
283
284         WMSetSliderValue(panel->speedS, (accel - 0.25) / 0.25);
285
286         panel->acceleration = accel;
287         sprintf(buffer, "%.2f", accel);
288         WMSetTextFieldText(panel->acceT, buffer);
289
290          /**/ b = GetIntegerForKey("DoubleClickTime");
291         /* find best match */
292         a = -1;
293         for (i = 0; i < 5; i++) {
294                 if (DELAY(i) == b)
295                         a = i;
296         }
297         if (a >= 0)
298                 WMPerformButtonClick(panel->ddelaB[a]);
299         sprintf(buffer, "%i", b);
300         WMSetTextFieldText(panel->ddelaT, buffer);
301
302          /**/ str = GetStringForKey("ModifierKey");
303         if (!str)
304                 str = "mod1";
305         a = ModifierFromKey(dpy, str);
306
307         if (a != -1) {
308                 str = modifierNames[a];
309
310                 a = 0;
311                 for (i = 0; i < WMGetPopUpButtonNumberOfItems(panel->grabP); i++) {
312                         if (strstr(WMGetPopUpButtonItem(panel->grabP, i), str)) {
313                                 WMSetPopUpButtonSelectedItem(panel->grabP, i);
314                                 a = 1;
315                                 break;
316                         }
317                 }
318         }
319
320         if (a < 1) {
321                 sscanf(WMGetPopUpButtonItem(panel->grabP, 0), "%s", buffer);
322                 WMSetPopUpButtonSelectedItem(panel->grabP, 0);
323                 wwarning(_("modifier key %s for option ModifierKey was not recognized. Using %s as default"),
324                          str, buffer);
325         }
326 }
327
328 static void fillModifierPopUp(WMPopUpButton * pop)
329 {
330         XModifierKeymap *mapping;
331         Display *dpy = WMScreenDisplay(WMWidgetScreen(pop));
332         int i, j;
333         char *str;
334         char buffer[64];
335
336         mapping = XGetModifierMapping(dpy);
337
338         if (!mapping || mapping->max_keypermod == 0) {
339                 WMAddPopUpButtonItem(pop, "Mod1");
340                 WMAddPopUpButtonItem(pop, "Mod2");
341                 WMAddPopUpButtonItem(pop, "Mod3");
342                 WMAddPopUpButtonItem(pop, "Mod4");
343                 WMAddPopUpButtonItem(pop, "Mod5");
344                 wwarning(_("could not retrieve keyboard modifier mapping"));
345                 return;
346         }
347
348         for (j = 0; j < 8; j++) {
349                 int idx;
350                 char *array[8];
351                 int a;
352                 KeySym ksym;
353                 int k;
354                 char *ptr;
355                 char *tmp;
356
357                 a = 0;
358                 memset(array, 0, sizeof(char *) * 8);
359                 for (i = 0; i < mapping->max_keypermod; i++) {
360                         idx = i + j * mapping->max_keypermod;
361                         if (mapping->modifiermap[idx] != 0) {
362                                 int l;
363                                 for (l = 0; l < 4; l++) {
364                                         ksym = XKeycodeToKeysym(dpy, mapping->modifiermap[idx], l);
365                                         if (ksym != NoSymbol)
366                                                 break;
367                                 }
368                                 if (ksym != NoSymbol)
369                                         str = XKeysymToString(ksym);
370                                 else
371                                         str = NULL;
372                                 if (str && !strstr(str, "_Lock") && !strstr(str, "Shift")
373                                     && !strstr(str, "Control")) {
374                                         array[a++] = wstrdup(str);
375                                 }
376                         }
377                 }
378
379                 for (k = 0; k < a; k++) {
380                         if (array[k] == NULL)
381                                 continue;
382                         tmp = wstrdup(array[k]);
383                         ptr = strstr(tmp, "_L");
384                         if (ptr)
385                                 *ptr = 0;
386                         ptr = strstr(tmp, "_R");
387                         if (ptr)
388                                 *ptr = 0;
389                         sprintf(buffer, "%s (%s)", modifierNames[j], tmp);
390                         /*sprintf(buffer, "%s", tmp); */
391                         WMAddPopUpButtonItem(pop, buffer);
392                         for (i = k + 1; i < a; i++) {
393                                 if (array[i] == NULL)
394                                         continue;
395                                 if (strstr(array[i], tmp)) {
396                                         wfree(array[i]);
397                                         array[i] = NULL;
398                                         break;
399                                 }
400                         }
401                         wfree(tmp);
402                 }
403
404                 while (--a > 0) {
405                         if (array[a])
406                                 wfree(array[a]);
407                 }
408         }
409
410         if (mapping)
411                 XFreeModifiermap(mapping);
412 }
413
414 static void createPanel(Panel * p)
415 {
416         _Panel *panel = (_Panel *) p;
417         WMScreen *scr = WMWidgetScreen(panel->parent);
418         WMPixmap *icon;
419         char *buf1, *buf2;
420         int i;
421         RColor color;
422         char *path;
423
424         color.red = 0xae;
425         color.green = 0xaa;
426         color.blue = 0xae;
427
428         panel->box = WMCreateBox(panel->parent);
429         WMSetViewExpandsToParent(WMWidgetView(panel->box), 2, 2, 2, 2);
430
431     /**************** Mouse Speed ****************/
432         panel->speedF = WMCreateFrame(panel->box);
433         WMResizeWidget(panel->speedF, 245, 100);
434         WMMoveWidget(panel->speedF, 15, 5);
435         WMSetFrameTitle(panel->speedF, _("Mouse Speed"));
436
437         panel->speedL = WMCreateLabel(panel->speedF);
438         WMResizeWidget(panel->speedL, 40, 46);
439         WMMoveWidget(panel->speedL, 15, 14);
440         WMSetLabelImagePosition(panel->speedL, WIPImageOnly);
441         path = LocateImage(SPEED_ICON_FILE);
442         if (path) {
443                 icon = WMCreateBlendedPixmapFromFile(scr, path, &color);
444                 if (icon) {
445                         WMSetLabelImage(panel->speedL, icon);
446                         WMReleasePixmap(icon);
447                 } else {
448                         wwarning(_("could not load icon %s"), path);
449                 }
450                 wfree(path);
451         }
452
453         panel->speedS = WMCreateSlider(panel->speedF);
454         WMResizeWidget(panel->speedS, 160, 15);
455         WMMoveWidget(panel->speedS, 70, 35);
456         WMSetSliderMinValue(panel->speedS, 0);
457         WMSetSliderMaxValue(panel->speedS, 40);
458         WMSetSliderContinuous(panel->speedS, False);
459         WMSetSliderAction(panel->speedS, speedChange, panel);
460
461         panel->acceL = WMCreateLabel(panel->speedF);
462         WMResizeWidget(panel->acceL, 70, 16);
463         WMMoveWidget(panel->acceL, 10, 67);
464         WMSetLabelTextAlignment(panel->acceL, WARight);
465         WMSetLabelText(panel->acceL, _("Acceler.:"));
466
467         panel->acceT = WMCreateTextField(panel->speedF);
468         WMResizeWidget(panel->acceT, 40, 20);
469         WMMoveWidget(panel->acceT, 80, 65);
470         WMAddNotificationObserver(returnPressed, panel, WMTextDidEndEditingNotification, panel->acceT);
471
472         panel->threL = WMCreateLabel(panel->speedF);
473         WMResizeWidget(panel->threL, 80, 16);
474         WMMoveWidget(panel->threL, 120, 67);
475         WMSetLabelTextAlignment(panel->threL, WARight);
476         WMSetLabelText(panel->threL, _("Threshold:"));
477
478         panel->threT = WMCreateTextField(panel->speedF);
479         WMResizeWidget(panel->threT, 30, 20);
480         WMMoveWidget(panel->threT, 200, 65);
481         WMAddNotificationObserver(returnPressed, panel, WMTextDidEndEditingNotification, panel->threT);
482
483         WMMapSubwidgets(panel->speedF);
484
485     /***************** Doubleclick Delay ****************/
486
487         panel->ddelaF = WMCreateFrame(panel->box);
488         WMResizeWidget(panel->ddelaF, 245, 105);
489         WMMoveWidget(panel->ddelaF, 15, 115);
490         WMSetFrameTitle(panel->ddelaF, _("Double-Click Delay"));
491
492         buf1 = wmalloc(strlen(DELAY_ICON) + 2);
493         buf2 = wmalloc(strlen(DELAY_ICON_S) + 2);
494
495         for (i = 0; i < 5; i++) {
496                 panel->ddelaB[i] = WMCreateCustomButton(panel->ddelaF, WBBStateChangeMask);
497                 WMResizeWidget(panel->ddelaB[i], 25, 25);
498                 WMMoveWidget(panel->ddelaB[i], 30 + (40 * i), 25);
499                 WMSetButtonBordered(panel->ddelaB[i], False);
500                 WMSetButtonImagePosition(panel->ddelaB[i], WIPImageOnly);
501                 WMSetButtonAction(panel->ddelaB[i], doubleClick, panel);
502                 if (i > 0) {
503                         WMGroupButtons(panel->ddelaB[0], panel->ddelaB[i]);
504                 }
505                 sprintf(buf1, DELAY_ICON, i + 1);
506                 sprintf(buf2, DELAY_ICON_S, i + 1);
507                 path = LocateImage(buf1);
508                 if (path) {
509                         icon = WMCreatePixmapFromFile(scr, path);
510                         if (icon) {
511                                 WMSetButtonImage(panel->ddelaB[i], icon);
512                                 WMReleasePixmap(icon);
513                         } else {
514                                 wwarning(_("could not load icon file %s"), path);
515                         }
516                         wfree(path);
517                 }
518                 path = LocateImage(buf2);
519                 if (path) {
520                         icon = WMCreatePixmapFromFile(scr, path);
521                         if (icon) {
522                                 WMSetButtonAltImage(panel->ddelaB[i], icon);
523                                 WMReleasePixmap(icon);
524                         } else {
525                                 wwarning(_("could not load icon file %s"), path);
526                         }
527                         wfree(path);
528                 }
529         }
530         wfree(buf1);
531         wfree(buf2);
532
533         panel->tester = CreateDoubleTest(panel->ddelaF, _("Test"));
534         WMResizeWidget(panel->tester, 84, 29);
535         WMMoveWidget(panel->tester, 35, 60);
536
537         panel->ddelaT = WMCreateTextField(panel->ddelaF);
538         WMResizeWidget(panel->ddelaT, 40, 20);
539         WMMoveWidget(panel->ddelaT, 140, 65);
540
541         panel->ddelaL = WMCreateLabel(panel->ddelaF);
542         WMResizeWidget(panel->ddelaL, 40, 16);
543         WMMoveWidget(panel->ddelaL, 185, 70);
544         {
545                 WMFont *font;
546                 WMColor *color;
547
548                 font = WMSystemFontOfSize(scr, 10);
549                 color = WMDarkGrayColor(scr);
550                 WMSetLabelTextColor(panel->ddelaL, color);
551                 WMSetLabelFont(panel->ddelaL, font);
552                 WMReleaseFont(font);
553                 WMReleaseColor(color);
554         }
555         WMSetLabelText(panel->ddelaL, _("msec"));
556
557         WMMapSubwidgets(panel->ddelaF);
558
559         /* ************** Workspace Action Buttons **************** */
560         panel->menuF = WMCreateFrame(panel->box);
561         WMResizeWidget(panel->menuF, 240, 160);
562         WMMoveWidget(panel->menuF, 270, 5);
563         WMSetFrameTitle(panel->menuF, _("Workspace Mouse Actions"));
564
565         panel->disaB = WMCreateSwitchButton(panel->menuF);
566         WMResizeWidget(panel->disaB, 205, 18);
567         WMMoveWidget(panel->disaB, 10, 18);
568         WMSetButtonText(panel->disaB, _("Disable mouse actions"));
569
570         panel->button1L = WMCreateLabel(panel->menuF);
571         WMResizeWidget(panel->button1L, 87, 20);
572         WMMoveWidget(panel->button1L, 5, 45);
573         WMSetLabelTextAlignment(panel->button1L, WARight);
574         WMSetLabelText(panel->button1L, _("Left Button"));
575
576         panel->button1P = WMCreatePopUpButton(panel->menuF);
577         WMResizeWidget(panel->button1P, 135, 20);
578         WMMoveWidget(panel->button1P, 95, 45);
579
580         panel->button2L = WMCreateLabel(panel->menuF);
581         WMResizeWidget(panel->button2L, 87, 20);
582         WMMoveWidget(panel->button2L, 5, 73);
583         WMSetLabelTextAlignment(panel->button2L, WARight);
584         WMSetLabelText(panel->button2L, _("Middle Button"));
585
586         panel->button2P = WMCreatePopUpButton(panel->menuF);
587         WMResizeWidget(panel->button2P, 135, 20);
588         WMMoveWidget(panel->button2P, 95, 73);
589
590         panel->button3L = WMCreateLabel(panel->menuF);
591         WMResizeWidget(panel->button3L, 87, 20);
592         WMMoveWidget(panel->button3L, 5, 101);
593         WMSetLabelTextAlignment(panel->button3L, WARight);
594         WMSetLabelText(panel->button3L, _("Right Button"));
595
596         panel->button3P = WMCreatePopUpButton(panel->menuF);
597         WMResizeWidget(panel->button3P, 135, 20);
598         WMMoveWidget(panel->button3P, 95, 101);
599
600         panel->wheelL = WMCreateLabel(panel->menuF);
601         WMResizeWidget(panel->wheelL, 87, 20);
602         WMMoveWidget(panel->wheelL, 5, 129);
603         WMSetLabelTextAlignment(panel->wheelL, WARight);
604         WMSetLabelText(panel->wheelL, _("Mouse Wheel"));
605
606         panel->wheelP = WMCreatePopUpButton(panel->menuF);
607         WMResizeWidget(panel->wheelP, 135, 20);
608         WMMoveWidget(panel->wheelP, 95, 129);
609
610         for (i = 0; i < sizeof(buttonActions) / sizeof(char *); i++) {
611                 WMAddPopUpButtonItem(panel->button1P, buttonActions[i]);
612                 WMAddPopUpButtonItem(panel->button2P, buttonActions[i]);
613                 WMAddPopUpButtonItem(panel->button3P, buttonActions[i]);
614         }
615
616         for (i = 0; i < sizeof(wheelActions) / sizeof(char *); i++) {
617                 WMAddPopUpButtonItem(panel->wheelP, wheelActions[i]);
618         }
619
620         WMMapSubwidgets(panel->menuF);
621
622         /* ************** Grab Modifier **************** */
623         panel->grabF = WMCreateFrame(panel->box);
624         WMResizeWidget(panel->grabF, 240, 50);
625         WMMoveWidget(panel->grabF, 270, 170);
626         WMSetFrameTitle(panel->grabF, _("Mouse Grab Modifier"));
627
628         WMSetBalloonTextForView(_("Keyboard modifier to use for actions that\n"
629                                   "involve dragging windows with the mouse,\n"
630                                   "clicking inside the window."), WMWidgetView(panel->grabF));
631
632         panel->grabP = WMCreatePopUpButton(panel->grabF);
633         WMResizeWidget(panel->grabP, 160, 20);
634         WMMoveWidget(panel->grabP, 40, 20);
635
636         fillModifierPopUp(panel->grabP);
637
638         WMMapSubwidgets(panel->grabF);
639
640         WMRealizeWidget(panel->box);
641         WMMapSubwidgets(panel->box);
642
643         showData(panel);
644 }
645
646 static void storeCommandInScript(char *cmd, char *line)
647 {
648         char *path;
649         FILE *f;
650         char buffer[128];
651
652         path = wstrconcat(wusergnusteppath(), "/Library/WindowMaker/autostart");
653
654         f = fopen(path, "rb");
655         if (!f) {
656                 f = fopen(path, "wb");
657                 if (!f) {
658                         wsyserror(_("could not create %s"), path);
659                         goto end;
660                 }
661                 fprintf(f, "#!/bin/sh\n");
662                 fputs(line, f);
663                 fputs("\n", f);
664         } else {
665                 int len = strlen(cmd);
666                 int ok = 0;
667                 char *tmppath;
668                 FILE *fo;
669
670                 tmppath = wstrconcat(wusergnusteppath(), "/Library/WindowMaker/autostart.tmp");
671                 fo = fopen(tmppath, "wb");
672                 if (!fo) {
673                         wsyserror(_("could not create temporary file %s"), tmppath);
674                         wfree(tmppath);
675                         goto end;
676                 }
677
678                 while (!feof(f)) {
679                         if (!fgets(buffer, 127, f)) {
680                                 break;
681                         }
682                         if (buffer[0] == '\n') {
683                                 /* don't write empty lines, else the file will grow
684                                  * indefinitely (one '\n' added at end of file on each save).
685                                  */
686                                 continue;
687                         }
688                         if (strncmp(buffer, cmd, len) == 0) {
689                                 if (!ok) {
690                                         fputs(line, fo);
691                                         fputs("\n", fo);
692                                         ok = 1;
693                                 }
694                         } else {
695                                 fputs(buffer, fo);
696                         }
697                 }
698                 if (!ok) {
699                         fputs(line, fo);
700                         fputs("\n", fo);
701                 }
702                 fclose(fo);
703
704                 if (rename(tmppath, path) != 0) {
705                         wsyserror(_("could not rename file %s to %s\n"), tmppath, path);
706                 }
707                 wfree(tmppath);
708         }
709         sprintf(buffer, "chmod u+x %s", path);
710         system(buffer);
711
712  end:
713         wfree(path);
714         if (f)
715                 fclose(f);
716 }
717
718 static void storeData(_Panel * panel)
719 {
720         char buffer[64];
721         int i;
722         char *tmp, *p;
723         static char *button[4] = { "None", "OpenApplicationsMenu", "OpenWindowListMenu", "SelectWindows" };
724         static char *wheel[2] = { "None", "SwitchWorkspaces" };
725         WMUserDefaults *udb = WMGetStandardUserDefaults();
726
727         if (!WMGetUDBoolForKey(udb, "NoXSetStuff")) {
728                 tmp = WMGetTextFieldText(panel->threT);
729                 if (strlen(tmp) == 0) {
730                         wfree(tmp);
731                         tmp = wstrdup("4");
732                 }
733
734                 sprintf(buffer, XSET " m %i/%i %s\n", (int)(panel->acceleration * 10), 10, tmp);
735                 storeCommandInScript(XSET " m", buffer);
736
737                 wfree(tmp);
738         }
739
740         tmp = WMGetTextFieldText(panel->ddelaT);
741         if (sscanf(tmp, "%i", &i) == 1 && i > 0)
742                 SetIntegerForKey(i, "DoubleClickTime");
743
744         SetBoolForKey(WMGetButtonSelected(panel->disaB), "DisableWSMouseActions");
745
746         i = WMGetPopUpButtonSelectedItem(panel->button1P);
747         SetStringForKey(button[i], "MouseLeftButtonAction");
748
749         i = WMGetPopUpButtonSelectedItem(panel->button2P);
750         SetStringForKey(button[i], "MouseMiddleButtonAction");
751
752         i = WMGetPopUpButtonSelectedItem(panel->button3P);
753         SetStringForKey(button[i], "MouseRightButtonAction");
754
755         i = WMGetPopUpButtonSelectedItem(panel->wheelP);
756         SetStringForKey(wheel[i], "MouseWheelAction");
757
758         tmp = WMGetPopUpButtonItem(panel->grabP, WMGetPopUpButtonSelectedItem(panel->grabP));
759         tmp = wstrdup(tmp);
760         p = strchr(tmp, ' ');
761         *p = 0;
762
763         SetStringForKey(tmp, "ModifierKey");
764
765         wfree(tmp);
766 }
767
768 Panel *InitMouseSettings(WMScreen * scr, WMWidget * parent)
769 {
770         _Panel *panel;
771
772         modifierNames[0] = wstrdup(_("Shift"));
773         modifierNames[1] = wstrdup(_("Lock"));
774         modifierNames[2] = wstrdup(_("Control"));
775         modifierNames[3] = wstrdup(_("Mod1"));
776         modifierNames[4] = wstrdup(_("Mod2"));
777         modifierNames[5] = wstrdup(_("Mod3"));
778         modifierNames[6] = wstrdup(_("Mod4"));
779         modifierNames[7] = wstrdup(_("Mod5"));
780
781         buttonActions[0] = wstrdup(_("None"));
782         buttonActions[1] = wstrdup(_("Applications Menu"));
783         buttonActions[2] = wstrdup(_("Window List Menu"));
784         buttonActions[3] = wstrdup(_("Select Windows"));
785
786         wheelActions[0] = wstrdup(_("None"));
787         wheelActions[1] = wstrdup(_("Switch Workspaces"));
788
789         panel = wmalloc(sizeof(_Panel));
790         memset(panel, 0, sizeof(_Panel));
791
792         panel->sectionName = _("Mouse Preferences");
793
794         panel->description = _("Mouse speed/acceleration, double click delay,\n" "mouse button bindings etc.");
795
796         panel->parent = parent;
797
798         panel->callbacks.createWidgets = createPanel;
799         panel->callbacks.updateDomain = storeData;
800
801         AddSection(panel, ICON_FILE);
802
803         return panel;
804 }