various bug fixes
[wmaker-crm.git] / WPrefs.app / MouseSettings.c
blobc48154c65061e7280ecea6b9422cc19262042fd8
2 /* MouseSettings.c- mouse options (some are equivalent to xset)
3 *
4 * WPrefs - Window Maker Preferences Program
5 *
6 * Copyright (c) 1998 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.
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.
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.
25 #include "WPrefs.h"
27 #include <X11/Xutil.h>
29 #include <math.h>
31 /* double-click tester */
32 #include "double.h"
36 #define XSET "xset"
40 typedef struct _Panel {
41 WMFrame *frame;
43 char *sectionName;
45 CallbackRec callbacks;
47 WMWindow *win;
49 WMFrame *speedF;
50 WMLabel *speedL;
51 WMSlider *speedS;
52 WMLabel *acceL;
53 WMTextField *acceT;
54 WMLabel *threL;
55 WMTextField *threT;
57 WMFrame *ddelaF;
58 WMButton *ddelaB[5];
59 WMTextField *ddelaT;
60 WMLabel *ddelaL;
61 DoubleTest *tester;
63 WMFrame *menuF;
64 WMLabel *listL;
65 WMLabel *appL;
66 WMLabel *selL;
67 WMLabel *mblL;
68 WMLabel *mbmL;
69 WMLabel *mbrL;
70 WMButton *lmb[3];
71 WMButton *amb[3];
72 WMButton *smb[3];
75 WMButton *disaB;
77 WMFrame *grabF;
78 WMPopUpButton *grabP;
80 /**/
81 int maxThreshold;
82 float acceleration;
83 } _Panel;
86 #define ICON_FILE "mousesettings"
88 #define SPEED_ICON_FILE "mousespeed"
90 #define DELAY_ICON "timer%i"
91 #define DELAY_ICON_S "timer%is"
93 #define MOUSEB_L "minimouseleft"
94 #define MOUSEB_M "minimousemiddle"
95 #define MOUSEB_R "minimouseright"
97 /* need access to the double click variables */
98 #include "WINGsP.h"
102 static char *modifierNames[] = {
103 "Shift",
104 "Lock",
105 "Control",
106 "Mod1",
107 "Mod2",
108 "Mod3",
109 "Mod4",
110 "Mod5"
114 #define DELAY(i) ((i)*75+170)
117 int ModifierFromKey(Display *dpy, char *key);
120 static void
121 setMouseAccel(WMScreen *scr, float accel, int threshold)
123 int n, d;
125 d = 10;
126 n = accel*d;
128 XChangePointerControl(WMScreenDisplay(scr), True, True, n, d, threshold);
132 static void
133 speedChange(WMWidget *w, void *data)
135 _Panel *panel = (_Panel*)data;
136 int i;
137 char buffer[64];
138 int threshold;
139 char *tmp;
141 if (w == NULL) {
142 float accel;
144 tmp = WMGetTextFieldText(panel->acceT);
145 if (sscanf(tmp, "%f", &accel)!=1 || accel < 0) {
146 WMRunAlertPanel(WMWidgetScreen(panel->acceT), GetWindow(panel),
147 _("Error"),
148 _("Invalid mouse acceleration value. Must be a positive real value."),
149 _("OK"), NULL, NULL);
150 free(tmp);
151 return;
153 panel->acceleration = accel;
154 free(tmp);
155 } else {
156 i = (int)WMGetSliderValue(panel->speedS);
158 panel->acceleration = 0.25+(i*0.25);
160 sprintf(buffer, "%.2f", 0.25+(i*0.25));
161 WMSetTextFieldText(panel->acceT, buffer);
164 tmp = WMGetTextFieldText(panel->threT);
165 if (sscanf(tmp, "%i", &threshold)!=1 || threshold < 0
166 || threshold > panel->maxThreshold) {
167 WMRunAlertPanel(WMWidgetScreen(panel->win), GetWindow(panel), _("Error"),
168 _("Invalid mouse acceleration threshold value. Must be the number of pixels to travel before accelerating."),
169 _("OK"), NULL, NULL);
170 } else {
171 setMouseAccel(WMWidgetScreen(panel->win), panel->acceleration,
172 threshold);
174 free(tmp);
178 static void
179 returnPressed(void *observerData, WMNotification *notification)
181 _Panel *panel = (_Panel*)observerData;
183 speedChange(NULL, panel);
187 static void
188 doubleClick(WMWidget *w, void *data)
190 _Panel *panel = (_Panel*)data;
191 int i;
192 extern _WINGsConfiguration WINGsConfiguration;
193 char buffer[32];
195 for (i=0; i<5; i++) {
196 if (panel->ddelaB[i]==w)
197 break;
199 WINGsConfiguration.doubleClickDelay = DELAY(i);
201 sprintf(buffer, "%i", DELAY(i));
202 WMSetTextFieldText(panel->ddelaT, buffer);
208 getbutton(char *str)
210 if (!str)
211 return -2;
213 if (strcasecmp(str, "left")==0)
214 return 0;
215 else if (strcasecmp(str, "middle")==0)
216 return 1;
217 else if (strcasecmp(str, "right")==0)
218 return 2;
219 else if (strcasecmp(str, "button1")==0)
220 return 0;
221 else if (strcasecmp(str, "button2")==0)
222 return 1;
223 else if (strcasecmp(str, "button3")==0)
224 return 2;
225 else if (strcasecmp(str, "button4")==0
226 || strcasecmp(str, "button5")==0) {
227 wwarning(_("mouse button %s not supported by WPrefs."), str);
228 return -2;
229 } else {
230 return -1;
235 static void
236 getMouseParameters(Display *dpy, float *accel, int *thre)
238 int n, d;
240 XGetPointerControl(dpy, &n, &d, thre);
242 *accel = (float)n/(float)d;
247 static void
248 showData(_Panel *panel)
250 char *str;
251 int i;
252 int a=-1, b=-1, c=-1;
253 float accel;
254 char buffer[32];
255 Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->win));
257 str = GetStringForKey("SelectWindowsMouseButton");
258 if (!str)
259 str = "left";
260 i = getbutton(str);
261 if (i==-1) {
262 a = 0;
263 wwarning(_("bad value %s for option %s"),str, "SelectWindowsMouseButton");
264 WMPerformButtonClick(panel->smb[0]);
265 } else if (i>=0) {
266 a = i;
267 WMPerformButtonClick(panel->smb[i]);
270 str = GetStringForKey("WindowListMouseButton");
271 if (!str)
272 str = "middle";
273 i = getbutton(str);
274 if (i==-1) {
275 b = 0;
276 wwarning(_("bad value %s for option %s"), str, "WindowListMouseButton");
277 WMPerformButtonClick(panel->lmb[1]);
278 } else if (i>=0) {
279 b = i;
280 WMPerformButtonClick(panel->lmb[i]);
283 str = GetStringForKey("ApplicationMenuMouseButton");
284 if (!str)
285 str = "right";
286 i = getbutton(str);
287 if (i==-1) {
288 c = 0;
289 wwarning(_("bad value %s for option %s"), str, "ApplicationMenuMouseButton");
290 WMPerformButtonClick(panel->amb[2]);
291 } else if (i>=0) {
292 c = i;
293 WMPerformButtonClick(panel->amb[i]);
297 WMSetButtonSelected(panel->disaB, GetBoolForKey("DisableWSMouseActions"));
299 /**/
300 getMouseParameters(dpy, &accel, &a);
301 panel->maxThreshold = WidthOfScreen(DefaultScreenOfDisplay(dpy));
302 if (a > panel->maxThreshold) {
303 panel->maxThreshold = a;
305 sprintf(buffer, "%i", a);
306 WMSetTextFieldText(panel->threT, buffer);
308 WMSetSliderValue(panel->speedS, (accel - 0.25)/0.25);
310 panel->acceleration = accel;
311 sprintf(buffer, "%.2f", accel);
312 WMSetTextFieldText(panel->acceT, buffer);
314 /**/
315 b = GetIntegerForKey("DoubleClickTime");
316 /* find best match */
317 a = -1;
318 for (i=0; i<5; i++) {
319 if (DELAY(i) == b)
320 a = i;
322 if (a >= 0)
323 WMPerformButtonClick(panel->ddelaB[a]);
324 sprintf(buffer, "%i", b);
325 WMSetTextFieldText(panel->ddelaT, buffer);
327 /**/
328 str = GetStringForKey("ModifierKey");
329 if (!str)
330 str = "mod1";
331 a = ModifierFromKey(dpy, str);
333 if (a != -1) {
334 str = modifierNames[a];
336 a = 0;
337 for (i=0; i<WMGetPopUpButtonNumberOfItems(panel->grabP); i++) {
338 if (strstr(WMGetPopUpButtonItem(panel->grabP, i), str)) {
339 WMSetPopUpButtonSelectedItem(panel->grabP, i);
340 a = 1;
341 break;
346 if (a < 1) {
347 sscanf(WMGetPopUpButtonItem(panel->grabP, 0), "%s", buffer);
348 WMSetPopUpButtonSelectedItem(panel->grabP, 0);
349 wwarning(_("modifier key %s for option ModifierKey was not recognized. Using %s as default"),
350 str, buffer);
356 static void
357 fillModifierPopUp(WMPopUpButton *pop)
359 XModifierKeymap *mapping;
360 Display *dpy = WMScreenDisplay(WMWidgetScreen(pop));
361 int i, j;
362 char *str;
363 char buffer[64];
366 mapping = XGetModifierMapping(dpy);
368 if (!mapping || mapping->max_keypermod==0) {
369 WMAddPopUpButtonItem(pop, "Mod1");
370 WMAddPopUpButtonItem(pop, "Mod2");
371 WMAddPopUpButtonItem(pop, "Mod3");
372 WMAddPopUpButtonItem(pop, "Mod4");
373 WMAddPopUpButtonItem(pop, "Mod5");
374 wwarning(_("could not retrieve keyboard modifier mapping"));
375 return;
379 for (j=0; j<8; j++) {
380 int idx;
381 char *array[8];
382 int a;
383 KeySym ksym;
384 int k;
385 char *ptr;
386 char *tmp;
388 a = 0;
389 memset(array, 0, sizeof(char*)*8);
390 for (i=0; i < mapping->max_keypermod; i++) {
391 idx = i+j*mapping->max_keypermod;
392 if (mapping->modifiermap[idx]!=0) {
393 int l;
394 for (l=0; l<4; l++) {
395 ksym = XKeycodeToKeysym(dpy, mapping->modifiermap[idx], l);
396 if (ksym!=NoSymbol)
397 break;
399 if (ksym!=NoSymbol)
400 str = XKeysymToString(ksym);
401 else
402 str = NULL;
403 if (str && !strstr(str, "_Lock") && !strstr(str, "Shift")
404 && !strstr(str, "Control")) {
405 array[a++] = wstrdup(str);
410 for (k=0; k<a; k++) {
411 if (array[k]==NULL)
412 continue;
413 tmp = wstrdup(array[k]);
414 ptr = strstr(tmp, "_L");
415 if (ptr)
416 *ptr = 0;
417 ptr = strstr(tmp, "_R");
418 if (ptr)
419 *ptr = 0;
420 sprintf(buffer, "%s (%s)", modifierNames[j], tmp);
421 WMAddPopUpButtonItem(pop, buffer);
422 for (i=k+1; i<a; i++) {
423 if (strstr(array[i], tmp)) {
424 free(array[i]);
425 array[i]=NULL;
426 break;
429 free(tmp);
432 while (--a>0) {
433 if (array[a])
434 free(array[a]);
438 if (mapping)
439 XFreeModifiermap(mapping);
444 static void
445 mouseButtonClickA(WMWidget *w, void *data)
447 _Panel *panel = (_Panel*)data;
448 int i;
450 for (i=0; i<3; i++) {
451 if (panel->amb[i]==w)
452 break;
454 if (i==3)
455 return;
456 if (WMGetButtonSelected(panel->lmb[i]))
457 WMSetButtonSelected(panel->lmb[i], False);
458 if (WMGetButtonSelected(panel->smb[i]))
459 WMSetButtonSelected(panel->smb[i], False);
462 static void
463 mouseButtonClickL(WMWidget *w, void *data)
465 _Panel *panel = (_Panel*)data;
466 int i;
468 for (i=0; i<3; i++) {
469 if (panel->lmb[i]==w)
470 break;
472 if (i==3)
473 return;
474 if (WMGetButtonSelected(panel->smb[i]))
475 WMSetButtonSelected(panel->smb[i], False);
476 if (WMGetButtonSelected(panel->amb[i]))
477 WMSetButtonSelected(panel->amb[i], False);
480 static void
481 mouseButtonClickS(WMWidget *w, void *data)
483 _Panel *panel = (_Panel*)data;
484 int i;
486 for (i=0; i<3; i++) {
487 if (panel->smb[i]==w)
488 break;
490 if (i==3)
491 return;
492 if (WMGetButtonSelected(panel->lmb[i]))
493 WMSetButtonSelected(panel->lmb[i], False);
494 if (WMGetButtonSelected(panel->amb[i]))
495 WMSetButtonSelected(panel->amb[i], False);
498 static void
499 createPanel(Panel *p)
501 _Panel *panel = (_Panel*)p;
502 WMScreen *scr = WMWidgetScreen(panel->win);
503 WMPixmap *icon;
504 char *buf1, *buf2;
505 int i;
506 RColor color;
507 char *path;
509 color.red = 0xaa;
510 color.green = 0xae;
511 color.blue = 0xaa;
513 panel->frame = WMCreateFrame(panel->win);
514 WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
515 WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
517 /**************** Mouse Speed ****************/
518 panel->speedF = WMCreateFrame(panel->frame);
519 WMResizeWidget(panel->speedF, 245, 100);
520 WMMoveWidget(panel->speedF, 15, 15);
521 WMSetFrameTitle(panel->speedF, _("Mouse Speed"));
523 panel->speedL = WMCreateLabel(panel->speedF);
524 WMResizeWidget(panel->speedL, 40, 46);
525 WMMoveWidget(panel->speedL, 15, 14);
526 WMSetLabelImagePosition(panel->speedL, WIPImageOnly);
527 path = LocateImage(SPEED_ICON_FILE);
528 if (path) {
529 icon = WMCreateBlendedPixmapFromFile(scr, path, &color);
530 if (icon) {
531 WMSetLabelImage(panel->speedL, icon);
532 WMReleasePixmap(icon);
533 } else {
534 wwarning(_("could not load icon %s"), path);
536 free(path);
539 panel->speedS = WMCreateSlider(panel->speedF);
540 WMResizeWidget(panel->speedS, 160, 15);
541 WMMoveWidget(panel->speedS, 70, 35);
542 WMSetSliderMinValue(panel->speedS, 0);
543 WMSetSliderMaxValue(panel->speedS, 40);
544 WMSetSliderContinuous(panel->speedS, False);
545 WMSetSliderAction(panel->speedS, speedChange, panel);
547 panel->acceL = WMCreateLabel(panel->speedF);
548 WMResizeWidget(panel->acceL, 70, 16);
549 WMMoveWidget(panel->acceL, 10, 67);
550 WMSetLabelTextAlignment(panel->acceL, WARight);
551 WMSetLabelText(panel->acceL, _("Acceler.:"));
553 panel->acceT = WMCreateTextField(panel->speedF);
554 WMResizeWidget(panel->acceT, 40, 20);
555 WMMoveWidget(panel->acceT, 80, 65);
556 WMAddNotificationObserver(returnPressed, panel,
557 WMTextDidEndEditingNotification, panel->acceT);
560 panel->threL = WMCreateLabel(panel->speedF);
561 WMResizeWidget(panel->threL, 80, 16);
562 WMMoveWidget(panel->threL, 120, 67);
563 WMSetLabelTextAlignment(panel->threL, WARight);
564 WMSetLabelText(panel->threL, _("Threshold:"));
566 panel->threT = WMCreateTextField(panel->speedF);
567 WMResizeWidget(panel->threT, 30, 20);
568 WMMoveWidget(panel->threT, 200, 65);
569 WMAddNotificationObserver(returnPressed, panel,
570 WMTextDidEndEditingNotification, panel->threT);
572 WMMapSubwidgets(panel->speedF);
574 /***************** Doubleclick Delay ****************/
576 panel->ddelaF = WMCreateFrame(panel->frame);
577 WMResizeWidget(panel->ddelaF, 245, 95);
578 WMMoveWidget(panel->ddelaF, 15, 125);
579 WMSetFrameTitle(panel->ddelaF, _("Double-Click Delay"));
581 buf1 = wmalloc(strlen(DELAY_ICON)+2);
582 buf2 = wmalloc(strlen(DELAY_ICON_S)+2);
584 for (i = 0; i < 5; i++) {
585 panel->ddelaB[i] = WMCreateCustomButton(panel->ddelaF,
586 WBBStateChangeMask);
587 WMResizeWidget(panel->ddelaB[i], 25, 25);
588 WMMoveWidget(panel->ddelaB[i], 30+(40*i), 20);
589 WMSetButtonBordered(panel->ddelaB[i], False);
590 WMSetButtonImagePosition(panel->ddelaB[i], WIPImageOnly);
591 WMSetButtonAction(panel->ddelaB[i], doubleClick, panel);
592 if (i>0) {
593 WMGroupButtons(panel->ddelaB[0], panel->ddelaB[i]);
595 sprintf(buf1, DELAY_ICON, i+1);
596 sprintf(buf2, DELAY_ICON_S, i+1);
597 path = LocateImage(buf1);
598 if (path) {
599 icon = WMCreatePixmapFromFile(scr, path);
600 if (icon) {
601 WMSetButtonImage(panel->ddelaB[i], icon);
602 WMReleasePixmap(icon);
603 } else {
604 wwarning(_("could not load icon file %s"), path);
606 free(path);
608 path = LocateImage(buf2);
609 if (path) {
610 icon = WMCreatePixmapFromFile(scr, path);
611 if (icon) {
612 WMSetButtonAltImage(panel->ddelaB[i], icon);
613 WMReleasePixmap(icon);
614 } else {
615 wwarning(_("could not load icon file %s"), path);
617 free(path);
620 free(buf1);
621 free(buf2);
623 panel->tester = CreateDoubleTest(panel->ddelaF, _("Test"));
624 WMResizeWidget(panel->tester, 84, 29);
625 WMMoveWidget(panel->tester, 35, 55);
627 panel->ddelaT = WMCreateTextField(panel->ddelaF);
628 WMResizeWidget(panel->ddelaT, 40, 20);
629 WMMoveWidget(panel->ddelaT, 140, 60);
631 panel->ddelaL = WMCreateLabel(panel->ddelaF);
632 WMResizeWidget(panel->ddelaL, 40, 16);
633 WMMoveWidget(panel->ddelaL, 185, 65);
635 WMFont *font;
636 WMColor *color;
638 font = WMSystemFontOfSize(scr, 10);
639 color = WMDarkGrayColor(scr);
640 WMSetLabelTextColor(panel->ddelaL, color);
641 WMSetLabelFont(panel->ddelaL, font);
642 WMReleaseFont(font);
643 WMReleaseColor(color);
645 WMSetLabelText(panel->ddelaL, "msec");
647 WMMapSubwidgets(panel->ddelaF);
649 /* ************** Workspace Action Buttons **************** */
650 panel->menuF = WMCreateFrame(panel->frame);
651 WMResizeWidget(panel->menuF, 240, 145);
652 WMMoveWidget(panel->menuF, 270, 15);
653 WMSetFrameTitle(panel->menuF, _("Workspace Mouse Actions"));
655 panel->disaB = WMCreateSwitchButton(panel->menuF);
656 WMResizeWidget(panel->disaB, 205, 18);
657 WMMoveWidget(panel->disaB, 10, 20);
658 WMSetButtonText(panel->disaB, _("Disable mouse actions"));
660 panel->mblL = WMCreateLabel(panel->menuF);
661 WMResizeWidget(panel->mblL, 16, 22);
662 WMMoveWidget(panel->mblL, 135, 40);
663 WMSetLabelImagePosition(panel->mblL, WIPImageOnly);
664 path = LocateImage(MOUSEB_L);
665 if (path) {
666 icon = WMCreatePixmapFromFile(scr, path);
667 if (icon) {
668 WMSetLabelImage(panel->mblL, icon);
669 WMReleasePixmap(icon);
670 } else {
671 wwarning(_("could not load icon file %s"), path);
673 free(path);
675 panel->mbmL = WMCreateLabel(panel->menuF);
676 WMResizeWidget(panel->mbmL, 16, 22);
677 WMMoveWidget(panel->mbmL, 170, 40);
678 WMSetLabelImagePosition(panel->mbmL, WIPImageOnly);
679 path = LocateImage(MOUSEB_M);
680 if (path) {
681 icon = WMCreatePixmapFromFile(scr, path);
682 if (icon) {
683 WMSetLabelImage(panel->mbmL, icon);
684 WMReleasePixmap(icon);
685 } else {
686 wwarning(_("could not load icon file %s"), path);
688 free(path);
691 panel->mbrL = WMCreateLabel(panel->menuF);
692 WMResizeWidget(panel->mbrL, 16, 22);
693 WMMoveWidget(panel->mbrL, 205, 40);
694 WMSetLabelImagePosition(panel->mbrL, WIPImageOnly);
695 path = LocateImage(MOUSEB_R);
696 if (path) {
697 icon = WMCreatePixmapFromFile(scr, path);
698 if (icon) {
699 WMSetLabelImage(panel->mbrL, icon);
700 WMReleasePixmap(icon);
701 } else {
702 wwarning(_("could not load icon file %s"), path);
704 free(path);
707 panel->appL = WMCreateLabel(panel->menuF);
708 WMResizeWidget(panel->appL, 125, 16);
709 WMMoveWidget(panel->appL, 5, 65);
710 WMSetLabelTextAlignment(panel->appL, WARight);
711 WMSetLabelText(panel->appL, _("Applications menu"));
713 panel->listL = WMCreateLabel(panel->menuF);
714 WMResizeWidget(panel->listL, 125, 16);
715 WMMoveWidget(panel->listL, 5, 90);
716 WMSetLabelTextAlignment(panel->listL, WARight);
717 WMSetLabelText(panel->listL, _("Window list menu"));
719 panel->selL = WMCreateLabel(panel->menuF);
720 WMResizeWidget(panel->selL, 125, 16);
721 WMMoveWidget(panel->selL, 5, 115);
722 WMSetLabelTextAlignment(panel->selL, WARight);
723 WMSetLabelText(panel->selL, _("Select windows"));
726 for (i=0; i<3; i++) {
727 panel->amb[i] = WMCreateRadioButton(panel->menuF);
728 WMResizeWidget(panel->amb[i], 24, 24);
729 WMMoveWidget(panel->amb[i], 135+35*i, 65);
730 WMSetButtonText(panel->amb[i], NULL);
731 WMSetButtonAction(panel->amb[i], mouseButtonClickA, panel);
733 panel->lmb[i] = WMCreateRadioButton(panel->menuF);
734 WMResizeWidget(panel->lmb[i], 24, 24);
735 WMMoveWidget(panel->lmb[i], 135+35*i, 90);
736 WMSetButtonText(panel->lmb[i], NULL);
737 WMSetButtonAction(panel->lmb[i], mouseButtonClickL, panel);
739 panel->smb[i] = WMCreateRadioButton(panel->menuF);
740 WMResizeWidget(panel->smb[i], 24, 24);
741 WMMoveWidget(panel->smb[i], 135+35*i, 115);
742 WMSetButtonText(panel->smb[i], NULL);
743 WMSetButtonAction(panel->smb[i], mouseButtonClickS, panel);
745 if (i>0) {
746 WMGroupButtons(panel->lmb[0], panel->lmb[i]);
747 WMGroupButtons(panel->amb[0], panel->amb[i]);
748 WMGroupButtons(panel->smb[0], panel->smb[i]);
752 WMMapSubwidgets(panel->menuF);
754 /* ************** Grab Modifier **************** */
755 panel->grabF = WMCreateFrame(panel->frame);
756 WMResizeWidget(panel->grabF, 240, 55);
757 WMMoveWidget(panel->grabF, 270, 165);
758 WMSetFrameTitle(panel->grabF, _("Mouse Grab Modifier"));
760 panel->grabP = WMCreatePopUpButton(panel->grabF);
761 WMResizeWidget(panel->grabP, 160, 20);
762 WMMoveWidget(panel->grabP, 40, 25);
764 fillModifierPopUp(panel->grabP);
766 WMMapSubwidgets(panel->grabF);
768 WMRealizeWidget(panel->frame);
769 WMMapSubwidgets(panel->frame);
772 showData(panel);
776 static void
777 storeCommandInScript(char *cmd, char *line)
779 char *path;
780 FILE *f;
781 char buffer[128];
783 path = wstrappend(wusergnusteppath(), "/Library/WindowMaker/autostart");
785 f = fopen(path, "r");
786 if (!f) {
787 f = fopen(path, "w");
788 if (!f) {
789 wsyserror(_("could not create %s"), path);
790 goto end;
792 fprintf(f, "#!/bin/sh\n");
793 fputs(line, f);
794 fputs("\n", f);
795 } else {
796 int len = strlen(cmd);
797 int ok = 0;
798 char *tmppath;
799 FILE *fo;
801 tmppath = wstrappend(wusergnusteppath(),
802 "/Library/WindowMaker/autostart.tmp");
803 fo = fopen(tmppath, "w");
804 if (!fo) {
805 wsyserror(_("could not create temporary file %s"), tmppath);
806 goto end;
809 while (!feof(f)) {
810 if (!fgets(buffer, 127, f)) {
811 break;
813 if (buffer[0] == '\n') {
814 /* don't write empty lines, else the file will grow
815 * indefinitely (one '\n' added at end of file on each save).
817 continue;
819 if (strncmp(buffer, cmd, len)==0) {
820 if (!ok) {
821 fputs(line, fo);
822 fputs("\n", fo);
823 ok = 1;
825 } else {
826 fputs(buffer, fo);
829 if (!ok) {
830 fputs(line, fo);
831 fputs("\n", fo);
833 fclose(fo);
835 if (rename(tmppath, path)!=0) {
836 wsyserror(_("could not rename file %s to %s\n"), tmppath, path);
838 free(tmppath);
840 sprintf(buffer, "chmod u+x %s", path);
841 system(buffer);
843 end:
844 free(path);
845 if (f)
846 fclose(f);
850 static void
851 storeData(_Panel *panel)
853 char buffer[64];
854 int i;
855 char *tmp, *p;
856 static char *button[3] = {"left", "middle", "right"};
857 WMUserDefaults *udb = WMGetStandardUserDefaults();
859 if (!WMGetUDBoolForKey(udb, "NoXSetStuff")) {
860 tmp = WMGetTextFieldText(panel->threT);
861 if (strlen(tmp)==0) {
862 free(tmp);
863 tmp = wstrdup("4");
866 sprintf(buffer, XSET" m %i/%i %s\n", (int)(panel->acceleration*10),
867 10, tmp);
868 storeCommandInScript(XSET" m", buffer);
870 free(tmp);
873 tmp = WMGetTextFieldText(panel->ddelaT);
874 if (sscanf(tmp, "%i", &i) == 1 && i > 0)
875 SetIntegerForKey(i, "DoubleClickTime");
877 SetBoolForKey(WMGetButtonSelected(panel->disaB), "DisableWSMouseActions");
879 for (i=0; i<3; i++) {
880 if (WMGetButtonSelected(panel->amb[i]))
881 break;
883 if (i<3)
884 SetStringForKey(button[i], "ApplicationMenuMouseButton");
886 for (i=0; i<3; i++) {
887 if (WMGetButtonSelected(panel->lmb[i]))
888 break;
890 if (i<3)
891 SetStringForKey(button[i], "WindowListMouseButton");
893 for (i=0; i<3; i++) {
894 if (WMGetButtonSelected(panel->smb[i]))
895 break;
897 if (i<3)
898 SetStringForKey(button[i], "SelectWindowsMouseButton");
900 tmp = WMGetPopUpButtonItem(panel->grabP,
901 WMGetPopUpButtonSelectedItem(panel->grabP));
902 tmp = wstrdup(tmp);
903 p = strchr(tmp, ' ');
904 *p = 0;
906 SetStringForKey(tmp, "ModifierKey");
908 free(tmp);
912 Panel*
913 InitMouseSettings(WMScreen *scr, WMWindow *win)
915 _Panel *panel;
917 panel = wmalloc(sizeof(_Panel));
918 memset(panel, 0, sizeof(_Panel));
920 panel->sectionName = _("Mouse Preferences");
922 panel->win = win;
924 panel->callbacks.createWidgets = createPanel;
925 panel->callbacks.updateDomain = storeData;
927 AddSection(panel, ICON_FILE);
929 return panel;