fix
[wmaker-crm.git] / WPrefs.app / MouseSettings.c
blob01fd74c8308e5ef0eb27c68d043ddf14cd6f83cc
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 char *description;
47 CallbackRec callbacks;
49 WMWindow *win;
51 WMFrame *speedF;
52 WMLabel *speedL;
53 WMSlider *speedS;
54 WMLabel *acceL;
55 WMTextField *acceT;
56 WMLabel *threL;
57 WMTextField *threT;
59 WMFrame *ddelaF;
60 WMButton *ddelaB[5];
61 WMTextField *ddelaT;
62 WMLabel *ddelaL;
63 DoubleTest *tester;
65 WMFrame *menuF;
66 WMLabel *listL;
67 WMLabel *appL;
68 WMLabel *selL;
69 WMLabel *mblL;
70 WMLabel *mbmL;
71 WMLabel *mbrL;
72 WMButton *lmb[3];
73 WMButton *amb[3];
74 WMButton *smb[3];
77 WMButton *disaB;
79 WMFrame *grabF;
80 WMPopUpButton *grabP;
82 /**/
83 int maxThreshold;
84 float acceleration;
85 } _Panel;
88 #define ICON_FILE "mousesettings"
90 #define SPEED_ICON_FILE "mousespeed"
92 #define DELAY_ICON "timer%i"
93 #define DELAY_ICON_S "timer%is"
95 #define MOUSEB_L "minimouseleft"
96 #define MOUSEB_M "minimousemiddle"
97 #define MOUSEB_R "minimouseright"
99 /* need access to the double click variables */
100 #include "WINGsP.h"
104 static char *modifierNames[] = {
105 "Shift",
106 "Lock",
107 "Control",
108 "Mod1",
109 "Mod2",
110 "Mod3",
111 "Mod4",
112 "Mod5"
116 #define DELAY(i) ((i)*75+170)
119 int ModifierFromKey(Display *dpy, char *key);
122 static void
123 setMouseAccel(WMScreen *scr, float accel, int threshold)
125 int n, d;
127 d = 10;
128 n = accel*d;
130 XChangePointerControl(WMScreenDisplay(scr), True, True, n, d, threshold);
134 static void
135 speedChange(WMWidget *w, void *data)
137 _Panel *panel = (_Panel*)data;
138 int i;
139 char buffer[64];
140 int threshold;
141 char *tmp;
143 if (w == NULL) {
144 float accel;
146 tmp = WMGetTextFieldText(panel->acceT);
147 if (sscanf(tmp, "%f", &accel)!=1 || accel < 0) {
148 WMRunAlertPanel(WMWidgetScreen(panel->acceT), GetWindow(panel),
149 _("Error"),
150 _("Invalid mouse acceleration value. Must be a positive real value."),
151 _("OK"), NULL, NULL);
152 free(tmp);
153 return;
155 panel->acceleration = accel;
156 free(tmp);
157 } else {
158 i = (int)WMGetSliderValue(panel->speedS);
160 panel->acceleration = 0.25+(i*0.25);
162 sprintf(buffer, "%.2f", 0.25+(i*0.25));
163 WMSetTextFieldText(panel->acceT, buffer);
166 tmp = WMGetTextFieldText(panel->threT);
167 if (sscanf(tmp, "%i", &threshold)!=1 || threshold < 0
168 || threshold > panel->maxThreshold) {
169 WMRunAlertPanel(WMWidgetScreen(panel->win), GetWindow(panel), _("Error"),
170 _("Invalid mouse acceleration threshold value. Must be the number of pixels to travel before accelerating."),
171 _("OK"), NULL, NULL);
172 } else {
173 setMouseAccel(WMWidgetScreen(panel->win), panel->acceleration,
174 threshold);
176 free(tmp);
180 static void
181 returnPressed(void *observerData, WMNotification *notification)
183 _Panel *panel = (_Panel*)observerData;
185 speedChange(NULL, panel);
189 static void
190 doubleClick(WMWidget *w, void *data)
192 _Panel *panel = (_Panel*)data;
193 int i;
194 extern _WINGsConfiguration WINGsConfiguration;
195 char buffer[32];
197 for (i=0; i<5; i++) {
198 if (panel->ddelaB[i]==w)
199 break;
201 WINGsConfiguration.doubleClickDelay = DELAY(i);
203 sprintf(buffer, "%i", DELAY(i));
204 WMSetTextFieldText(panel->ddelaT, buffer);
210 getbutton(char *str)
212 if (!str)
213 return -2;
215 if (strcasecmp(str, "left")==0)
216 return 0;
217 else if (strcasecmp(str, "middle")==0)
218 return 1;
219 else if (strcasecmp(str, "right")==0)
220 return 2;
221 else if (strcasecmp(str, "button1")==0)
222 return 0;
223 else if (strcasecmp(str, "button2")==0)
224 return 1;
225 else if (strcasecmp(str, "button3")==0)
226 return 2;
227 else if (strcasecmp(str, "button4")==0
228 || strcasecmp(str, "button5")==0) {
229 wwarning(_("mouse button %s not supported by WPrefs."), str);
230 return -2;
231 } else {
232 return -1;
237 static void
238 getMouseParameters(Display *dpy, float *accel, int *thre)
240 int n, d;
242 XGetPointerControl(dpy, &n, &d, thre);
244 *accel = (float)n/(float)d;
249 static void
250 showData(_Panel *panel)
252 char *str;
253 int i;
254 int a=-1, b=-1, c=-1;
255 float accel;
256 char buffer[32];
257 Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->win));
259 str = GetStringForKey("SelectWindowsMouseButton");
260 if (!str)
261 str = "left";
262 i = getbutton(str);
263 if (i==-1) {
264 a = 0;
265 wwarning(_("bad value %s for option %s"),str, "SelectWindowsMouseButton");
266 WMPerformButtonClick(panel->smb[0]);
267 } else if (i>=0) {
268 a = i;
269 WMPerformButtonClick(panel->smb[i]);
272 str = GetStringForKey("WindowListMouseButton");
273 if (!str)
274 str = "middle";
275 i = getbutton(str);
276 if (i==-1) {
277 b = 0;
278 wwarning(_("bad value %s for option %s"), str, "WindowListMouseButton");
279 WMPerformButtonClick(panel->lmb[1]);
280 } else if (i>=0) {
281 b = i;
282 WMPerformButtonClick(panel->lmb[i]);
285 str = GetStringForKey("ApplicationMenuMouseButton");
286 if (!str)
287 str = "right";
288 i = getbutton(str);
289 if (i==-1) {
290 c = 0;
291 wwarning(_("bad value %s for option %s"), str, "ApplicationMenuMouseButton");
292 WMPerformButtonClick(panel->amb[2]);
293 } else if (i>=0) {
294 c = i;
295 WMPerformButtonClick(panel->amb[i]);
299 WMSetButtonSelected(panel->disaB, GetBoolForKey("DisableWSMouseActions"));
301 /**/
302 getMouseParameters(dpy, &accel, &a);
303 panel->maxThreshold = WidthOfScreen(DefaultScreenOfDisplay(dpy));
304 if (a > panel->maxThreshold) {
305 panel->maxThreshold = a;
307 sprintf(buffer, "%i", a);
308 WMSetTextFieldText(panel->threT, buffer);
310 WMSetSliderValue(panel->speedS, (accel - 0.25)/0.25);
312 panel->acceleration = accel;
313 sprintf(buffer, "%.2f", accel);
314 WMSetTextFieldText(panel->acceT, buffer);
316 /**/
317 b = GetIntegerForKey("DoubleClickTime");
318 /* find best match */
319 a = -1;
320 for (i=0; i<5; i++) {
321 if (DELAY(i) == b)
322 a = i;
324 if (a >= 0)
325 WMPerformButtonClick(panel->ddelaB[a]);
326 sprintf(buffer, "%i", b);
327 WMSetTextFieldText(panel->ddelaT, buffer);
329 /**/
330 str = GetStringForKey("ModifierKey");
331 if (!str)
332 str = "mod1";
333 a = ModifierFromKey(dpy, str);
335 if (a != -1) {
336 str = modifierNames[a];
338 a = 0;
339 for (i=0; i<WMGetPopUpButtonNumberOfItems(panel->grabP); i++) {
340 if (strstr(WMGetPopUpButtonItem(panel->grabP, i), str)) {
341 WMSetPopUpButtonSelectedItem(panel->grabP, i);
342 a = 1;
343 break;
348 if (a < 1) {
349 sscanf(WMGetPopUpButtonItem(panel->grabP, 0), "%s", buffer);
350 WMSetPopUpButtonSelectedItem(panel->grabP, 0);
351 wwarning(_("modifier key %s for option ModifierKey was not recognized. Using %s as default"),
352 str, buffer);
358 static void
359 fillModifierPopUp(WMPopUpButton *pop)
361 XModifierKeymap *mapping;
362 Display *dpy = WMScreenDisplay(WMWidgetScreen(pop));
363 int i, j;
364 char *str;
365 char buffer[64];
368 mapping = XGetModifierMapping(dpy);
370 if (!mapping || mapping->max_keypermod==0) {
371 WMAddPopUpButtonItem(pop, "Mod1");
372 WMAddPopUpButtonItem(pop, "Mod2");
373 WMAddPopUpButtonItem(pop, "Mod3");
374 WMAddPopUpButtonItem(pop, "Mod4");
375 WMAddPopUpButtonItem(pop, "Mod5");
376 wwarning(_("could not retrieve keyboard modifier mapping"));
377 return;
381 for (j=0; j<8; j++) {
382 int idx;
383 char *array[8];
384 int a;
385 KeySym ksym;
386 int k;
387 char *ptr;
388 char *tmp;
390 a = 0;
391 memset(array, 0, sizeof(char*)*8);
392 for (i=0; i < mapping->max_keypermod; i++) {
393 idx = i+j*mapping->max_keypermod;
394 if (mapping->modifiermap[idx]!=0) {
395 int l;
396 for (l=0; l<4; l++) {
397 ksym = XKeycodeToKeysym(dpy, mapping->modifiermap[idx], l);
398 if (ksym!=NoSymbol)
399 break;
401 if (ksym!=NoSymbol)
402 str = XKeysymToString(ksym);
403 else
404 str = NULL;
405 if (str && !strstr(str, "_Lock") && !strstr(str, "Shift")
406 && !strstr(str, "Control")) {
407 array[a++] = wstrdup(str);
412 for (k=0; k<a; k++) {
413 if (array[k]==NULL)
414 continue;
415 tmp = wstrdup(array[k]);
416 ptr = strstr(tmp, "_L");
417 if (ptr)
418 *ptr = 0;
419 ptr = strstr(tmp, "_R");
420 if (ptr)
421 *ptr = 0;
422 sprintf(buffer, "%s (%s)", modifierNames[j], tmp);
423 WMAddPopUpButtonItem(pop, buffer);
424 for (i=k+1; i<a; i++) {
425 if (strstr(array[i], tmp)) {
426 free(array[i]);
427 array[i]=NULL;
428 break;
431 free(tmp);
434 while (--a>0) {
435 if (array[a])
436 free(array[a]);
440 if (mapping)
441 XFreeModifiermap(mapping);
446 static void
447 mouseButtonClickA(WMWidget *w, void *data)
449 _Panel *panel = (_Panel*)data;
450 int i;
452 for (i=0; i<3; i++) {
453 if (panel->amb[i]==w)
454 break;
456 if (i==3)
457 return;
458 if (WMGetButtonSelected(panel->lmb[i]))
459 WMSetButtonSelected(panel->lmb[i], False);
460 if (WMGetButtonSelected(panel->smb[i]))
461 WMSetButtonSelected(panel->smb[i], False);
464 static void
465 mouseButtonClickL(WMWidget *w, void *data)
467 _Panel *panel = (_Panel*)data;
468 int i;
470 for (i=0; i<3; i++) {
471 if (panel->lmb[i]==w)
472 break;
474 if (i==3)
475 return;
476 if (WMGetButtonSelected(panel->smb[i]))
477 WMSetButtonSelected(panel->smb[i], False);
478 if (WMGetButtonSelected(panel->amb[i]))
479 WMSetButtonSelected(panel->amb[i], False);
482 static void
483 mouseButtonClickS(WMWidget *w, void *data)
485 _Panel *panel = (_Panel*)data;
486 int i;
488 for (i=0; i<3; i++) {
489 if (panel->smb[i]==w)
490 break;
492 if (i==3)
493 return;
494 if (WMGetButtonSelected(panel->lmb[i]))
495 WMSetButtonSelected(panel->lmb[i], False);
496 if (WMGetButtonSelected(panel->amb[i]))
497 WMSetButtonSelected(panel->amb[i], False);
500 static void
501 createPanel(Panel *p)
503 _Panel *panel = (_Panel*)p;
504 WMScreen *scr = WMWidgetScreen(panel->win);
505 WMPixmap *icon;
506 char *buf1, *buf2;
507 int i;
508 RColor color;
509 char *path;
511 color.red = 0xaa;
512 color.green = 0xae;
513 color.blue = 0xaa;
515 panel->frame = WMCreateFrame(panel->win);
516 WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
517 WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
519 /**************** Mouse Speed ****************/
520 panel->speedF = WMCreateFrame(panel->frame);
521 WMResizeWidget(panel->speedF, 245, 100);
522 WMMoveWidget(panel->speedF, 15, 15);
523 WMSetFrameTitle(panel->speedF, _("Mouse Speed"));
525 panel->speedL = WMCreateLabel(panel->speedF);
526 WMResizeWidget(panel->speedL, 40, 46);
527 WMMoveWidget(panel->speedL, 15, 14);
528 WMSetLabelImagePosition(panel->speedL, WIPImageOnly);
529 path = LocateImage(SPEED_ICON_FILE);
530 if (path) {
531 icon = WMCreateBlendedPixmapFromFile(scr, path, &color);
532 if (icon) {
533 WMSetLabelImage(panel->speedL, icon);
534 WMReleasePixmap(icon);
535 } else {
536 wwarning(_("could not load icon %s"), path);
538 free(path);
541 panel->speedS = WMCreateSlider(panel->speedF);
542 WMResizeWidget(panel->speedS, 160, 15);
543 WMMoveWidget(panel->speedS, 70, 35);
544 WMSetSliderMinValue(panel->speedS, 0);
545 WMSetSliderMaxValue(panel->speedS, 40);
546 WMSetSliderContinuous(panel->speedS, False);
547 WMSetSliderAction(panel->speedS, speedChange, panel);
549 panel->acceL = WMCreateLabel(panel->speedF);
550 WMResizeWidget(panel->acceL, 70, 16);
551 WMMoveWidget(panel->acceL, 10, 67);
552 WMSetLabelTextAlignment(panel->acceL, WARight);
553 WMSetLabelText(panel->acceL, _("Acceler.:"));
555 panel->acceT = WMCreateTextField(panel->speedF);
556 WMResizeWidget(panel->acceT, 40, 20);
557 WMMoveWidget(panel->acceT, 80, 65);
558 WMAddNotificationObserver(returnPressed, panel,
559 WMTextDidEndEditingNotification, panel->acceT);
562 panel->threL = WMCreateLabel(panel->speedF);
563 WMResizeWidget(panel->threL, 80, 16);
564 WMMoveWidget(panel->threL, 120, 67);
565 WMSetLabelTextAlignment(panel->threL, WARight);
566 WMSetLabelText(panel->threL, _("Threshold:"));
568 panel->threT = WMCreateTextField(panel->speedF);
569 WMResizeWidget(panel->threT, 30, 20);
570 WMMoveWidget(panel->threT, 200, 65);
571 WMAddNotificationObserver(returnPressed, panel,
572 WMTextDidEndEditingNotification, panel->threT);
574 WMMapSubwidgets(panel->speedF);
576 /***************** Doubleclick Delay ****************/
578 panel->ddelaF = WMCreateFrame(panel->frame);
579 WMResizeWidget(panel->ddelaF, 245, 95);
580 WMMoveWidget(panel->ddelaF, 15, 125);
581 WMSetFrameTitle(panel->ddelaF, _("Double-Click Delay"));
583 buf1 = wmalloc(strlen(DELAY_ICON)+2);
584 buf2 = wmalloc(strlen(DELAY_ICON_S)+2);
586 for (i = 0; i < 5; i++) {
587 panel->ddelaB[i] = WMCreateCustomButton(panel->ddelaF,
588 WBBStateChangeMask);
589 WMResizeWidget(panel->ddelaB[i], 25, 25);
590 WMMoveWidget(panel->ddelaB[i], 30+(40*i), 20);
591 WMSetButtonBordered(panel->ddelaB[i], False);
592 WMSetButtonImagePosition(panel->ddelaB[i], WIPImageOnly);
593 WMSetButtonAction(panel->ddelaB[i], doubleClick, panel);
594 if (i>0) {
595 WMGroupButtons(panel->ddelaB[0], panel->ddelaB[i]);
597 sprintf(buf1, DELAY_ICON, i+1);
598 sprintf(buf2, DELAY_ICON_S, i+1);
599 path = LocateImage(buf1);
600 if (path) {
601 icon = WMCreatePixmapFromFile(scr, path);
602 if (icon) {
603 WMSetButtonImage(panel->ddelaB[i], icon);
604 WMReleasePixmap(icon);
605 } else {
606 wwarning(_("could not load icon file %s"), path);
608 free(path);
610 path = LocateImage(buf2);
611 if (path) {
612 icon = WMCreatePixmapFromFile(scr, path);
613 if (icon) {
614 WMSetButtonAltImage(panel->ddelaB[i], icon);
615 WMReleasePixmap(icon);
616 } else {
617 wwarning(_("could not load icon file %s"), path);
619 free(path);
622 free(buf1);
623 free(buf2);
625 panel->tester = CreateDoubleTest(panel->ddelaF, _("Test"));
626 WMResizeWidget(panel->tester, 84, 29);
627 WMMoveWidget(panel->tester, 35, 55);
629 panel->ddelaT = WMCreateTextField(panel->ddelaF);
630 WMResizeWidget(panel->ddelaT, 40, 20);
631 WMMoveWidget(panel->ddelaT, 140, 60);
633 panel->ddelaL = WMCreateLabel(panel->ddelaF);
634 WMResizeWidget(panel->ddelaL, 40, 16);
635 WMMoveWidget(panel->ddelaL, 185, 65);
637 WMFont *font;
638 WMColor *color;
640 font = WMSystemFontOfSize(scr, 10);
641 color = WMDarkGrayColor(scr);
642 WMSetLabelTextColor(panel->ddelaL, color);
643 WMSetLabelFont(panel->ddelaL, font);
644 WMReleaseFont(font);
645 WMReleaseColor(color);
647 WMSetLabelText(panel->ddelaL, "msec");
649 WMMapSubwidgets(panel->ddelaF);
651 /* ************** Workspace Action Buttons **************** */
652 panel->menuF = WMCreateFrame(panel->frame);
653 WMResizeWidget(panel->menuF, 240, 145);
654 WMMoveWidget(panel->menuF, 270, 15);
655 WMSetFrameTitle(panel->menuF, _("Workspace Mouse Actions"));
657 panel->disaB = WMCreateSwitchButton(panel->menuF);
658 WMResizeWidget(panel->disaB, 205, 18);
659 WMMoveWidget(panel->disaB, 10, 20);
660 WMSetButtonText(panel->disaB, _("Disable mouse actions"));
662 panel->mblL = WMCreateLabel(panel->menuF);
663 WMResizeWidget(panel->mblL, 16, 22);
664 WMMoveWidget(panel->mblL, 135, 40);
665 WMSetLabelImagePosition(panel->mblL, WIPImageOnly);
666 path = LocateImage(MOUSEB_L);
667 if (path) {
668 icon = WMCreatePixmapFromFile(scr, path);
669 if (icon) {
670 WMSetLabelImage(panel->mblL, icon);
671 WMReleasePixmap(icon);
672 } else {
673 wwarning(_("could not load icon file %s"), path);
675 free(path);
677 panel->mbmL = WMCreateLabel(panel->menuF);
678 WMResizeWidget(panel->mbmL, 16, 22);
679 WMMoveWidget(panel->mbmL, 170, 40);
680 WMSetLabelImagePosition(panel->mbmL, WIPImageOnly);
681 path = LocateImage(MOUSEB_M);
682 if (path) {
683 icon = WMCreatePixmapFromFile(scr, path);
684 if (icon) {
685 WMSetLabelImage(panel->mbmL, icon);
686 WMReleasePixmap(icon);
687 } else {
688 wwarning(_("could not load icon file %s"), path);
690 free(path);
693 panel->mbrL = WMCreateLabel(panel->menuF);
694 WMResizeWidget(panel->mbrL, 16, 22);
695 WMMoveWidget(panel->mbrL, 205, 40);
696 WMSetLabelImagePosition(panel->mbrL, WIPImageOnly);
697 path = LocateImage(MOUSEB_R);
698 if (path) {
699 icon = WMCreatePixmapFromFile(scr, path);
700 if (icon) {
701 WMSetLabelImage(panel->mbrL, icon);
702 WMReleasePixmap(icon);
703 } else {
704 wwarning(_("could not load icon file %s"), path);
706 free(path);
709 panel->appL = WMCreateLabel(panel->menuF);
710 WMResizeWidget(panel->appL, 125, 16);
711 WMMoveWidget(panel->appL, 5, 65);
712 WMSetLabelTextAlignment(panel->appL, WARight);
713 WMSetLabelText(panel->appL, _("Applications menu"));
715 panel->listL = WMCreateLabel(panel->menuF);
716 WMResizeWidget(panel->listL, 125, 16);
717 WMMoveWidget(panel->listL, 5, 90);
718 WMSetLabelTextAlignment(panel->listL, WARight);
719 WMSetLabelText(panel->listL, _("Window list menu"));
721 panel->selL = WMCreateLabel(panel->menuF);
722 WMResizeWidget(panel->selL, 125, 16);
723 WMMoveWidget(panel->selL, 5, 115);
724 WMSetLabelTextAlignment(panel->selL, WARight);
725 WMSetLabelText(panel->selL, _("Select windows"));
728 for (i=0; i<3; i++) {
729 panel->amb[i] = WMCreateRadioButton(panel->menuF);
730 WMResizeWidget(panel->amb[i], 24, 24);
731 WMMoveWidget(panel->amb[i], 135+35*i, 65);
732 WMSetButtonText(panel->amb[i], NULL);
733 WMSetButtonAction(panel->amb[i], mouseButtonClickA, panel);
735 panel->lmb[i] = WMCreateRadioButton(panel->menuF);
736 WMResizeWidget(panel->lmb[i], 24, 24);
737 WMMoveWidget(panel->lmb[i], 135+35*i, 90);
738 WMSetButtonText(panel->lmb[i], NULL);
739 WMSetButtonAction(panel->lmb[i], mouseButtonClickL, panel);
741 panel->smb[i] = WMCreateRadioButton(panel->menuF);
742 WMResizeWidget(panel->smb[i], 24, 24);
743 WMMoveWidget(panel->smb[i], 135+35*i, 115);
744 WMSetButtonText(panel->smb[i], NULL);
745 WMSetButtonAction(panel->smb[i], mouseButtonClickS, panel);
747 if (i>0) {
748 WMGroupButtons(panel->lmb[0], panel->lmb[i]);
749 WMGroupButtons(panel->amb[0], panel->amb[i]);
750 WMGroupButtons(panel->smb[0], panel->smb[i]);
754 WMMapSubwidgets(panel->menuF);
756 /* ************** Grab Modifier **************** */
757 panel->grabF = WMCreateFrame(panel->frame);
758 WMResizeWidget(panel->grabF, 240, 55);
759 WMMoveWidget(panel->grabF, 270, 165);
760 WMSetFrameTitle(panel->grabF, _("Mouse Grab Modifier"));
762 WMSetBalloonTextForView(_("Keyboard modifier to use for actions that\n"
763 "involve dragging windows with the mouse,\n"
764 "clicking inside the window."),
765 WMWidgetView(panel->grabF));
767 panel->grabP = WMCreatePopUpButton(panel->grabF);
768 WMResizeWidget(panel->grabP, 160, 20);
769 WMMoveWidget(panel->grabP, 40, 25);
771 fillModifierPopUp(panel->grabP);
773 WMMapSubwidgets(panel->grabF);
775 WMRealizeWidget(panel->frame);
776 WMMapSubwidgets(panel->frame);
779 showData(panel);
783 static void
784 storeCommandInScript(char *cmd, char *line)
786 char *path;
787 FILE *f;
788 char buffer[128];
790 path = wstrappend(wusergnusteppath(), "/Library/WindowMaker/autostart");
792 f = fopen(path, "r");
793 if (!f) {
794 f = fopen(path, "w");
795 if (!f) {
796 wsyserror(_("could not create %s"), path);
797 goto end;
799 fprintf(f, "#!/bin/sh\n");
800 fputs(line, f);
801 fputs("\n", f);
802 } else {
803 int len = strlen(cmd);
804 int ok = 0;
805 char *tmppath;
806 FILE *fo;
808 tmppath = wstrappend(wusergnusteppath(),
809 "/Library/WindowMaker/autostart.tmp");
810 fo = fopen(tmppath, "w");
811 if (!fo) {
812 wsyserror(_("could not create temporary file %s"), tmppath);
813 goto end;
816 while (!feof(f)) {
817 if (!fgets(buffer, 127, f)) {
818 break;
820 if (buffer[0] == '\n') {
821 /* don't write empty lines, else the file will grow
822 * indefinitely (one '\n' added at end of file on each save).
824 continue;
826 if (strncmp(buffer, cmd, len)==0) {
827 if (!ok) {
828 fputs(line, fo);
829 fputs("\n", fo);
830 ok = 1;
832 } else {
833 fputs(buffer, fo);
836 if (!ok) {
837 fputs(line, fo);
838 fputs("\n", fo);
840 fclose(fo);
842 if (rename(tmppath, path)!=0) {
843 wsyserror(_("could not rename file %s to %s\n"), tmppath, path);
845 free(tmppath);
847 sprintf(buffer, "chmod u+x %s", path);
848 system(buffer);
850 end:
851 free(path);
852 if (f)
853 fclose(f);
857 static void
858 storeData(_Panel *panel)
860 char buffer[64];
861 int i;
862 char *tmp, *p;
863 static char *button[3] = {"left", "middle", "right"};
864 WMUserDefaults *udb = WMGetStandardUserDefaults();
866 if (!WMGetUDBoolForKey(udb, "NoXSetStuff")) {
867 tmp = WMGetTextFieldText(panel->threT);
868 if (strlen(tmp)==0) {
869 free(tmp);
870 tmp = wstrdup("4");
873 sprintf(buffer, XSET" m %i/%i %s\n", (int)(panel->acceleration*10),
874 10, tmp);
875 storeCommandInScript(XSET" m", buffer);
877 free(tmp);
880 tmp = WMGetTextFieldText(panel->ddelaT);
881 if (sscanf(tmp, "%i", &i) == 1 && i > 0)
882 SetIntegerForKey(i, "DoubleClickTime");
884 SetBoolForKey(WMGetButtonSelected(panel->disaB), "DisableWSMouseActions");
886 for (i=0; i<3; i++) {
887 if (WMGetButtonSelected(panel->amb[i]))
888 break;
890 if (i<3)
891 SetStringForKey(button[i], "ApplicationMenuMouseButton");
893 for (i=0; i<3; i++) {
894 if (WMGetButtonSelected(panel->lmb[i]))
895 break;
897 if (i<3)
898 SetStringForKey(button[i], "WindowListMouseButton");
900 for (i=0; i<3; i++) {
901 if (WMGetButtonSelected(panel->smb[i]))
902 break;
904 if (i<3)
905 SetStringForKey(button[i], "SelectWindowsMouseButton");
907 tmp = WMGetPopUpButtonItem(panel->grabP,
908 WMGetPopUpButtonSelectedItem(panel->grabP));
909 tmp = wstrdup(tmp);
910 p = strchr(tmp, ' ');
911 *p = 0;
913 SetStringForKey(tmp, "ModifierKey");
915 free(tmp);
919 Panel*
920 InitMouseSettings(WMScreen *scr, WMWindow *win)
922 _Panel *panel;
924 panel = wmalloc(sizeof(_Panel));
925 memset(panel, 0, sizeof(_Panel));
927 panel->sectionName = _("Mouse Preferences");
929 panel->description = _("Mouse speed/acceleration, double click delay,\n"
930 "mouse button bindings etc.");
932 panel->win = win;
934 panel->callbacks.createWidgets = createPanel;
935 panel->callbacks.updateDomain = storeData;
937 AddSection(panel, ICON_FILE);
939 return panel;