1 /*
2 xrus - keyboard switcher/indicator
3 Copyright (c) 1996 Alexander V. Lukyanov
4 This is free software with no warranty.
5 See COPYING for details.
6 */
7 #include <config.h>
8 #include <stdio.h>
9
10 #include <X11/Xlib.h>
11 #include <X11/Intrinsic.h>
12
13 #include "keycomb.h"
14 #include "xrus.h"
15
16 #include "xalloca.h"
17
ParseKeyCombination(const char * str,struct KeyCombination * kc,char * err)18 void ParseKeyCombination(const char *str,struct KeyCombination *kc,char *err)
19 {
20 char *plus;
21 char *scan;
22 KeySym ks;
23 int i;
24
25 scan=alloca(strlen(str)+1);
26 strcpy(scan,str);
27
28 kc->KeysNum=0;
29 err[0]=0;
30 for(;;)
31 {
32 plus=strchr(scan,'+');
33 if(plus==NULL)
34 {
35 if(*scan==0)
36 break;
37 }
38 else
39 {
40 *plus=0;
41 }
42 ks=XStringToKeysym(scan);
43 if(ks==NoSymbol)
44 {
45 sprintf(err+strlen(err),"Invalid key name (%s)\n",scan);
46 }
47 else
48 {
49 for(i=0; i<kc->KeysNum; i++)
50 {
51 if(kc->Keys[i]==ks)
52 break;
53 }
54 if(i==kc->KeysNum)
55 {
56 if(kc->KeysNum==sizeof(kc->Keys)/sizeof(kc->Keys[0]))
57 {
58 sprintf(err+strlen(err),"Too much keys\n");
59 break;
60 }
61 kc->Keys[kc->KeysNum++]=ks;
62 }
63 }
64 if(plus!=NULL)
65 scan=plus+1;
66 else
67 break;
68 }
69 kc->KeysPressed=0;
70 kc->KeysArmed=0;
71 }
72
KeyCombinationProcessKeyPress(struct KeyCombination * kc,KeySym ks)73 void KeyCombinationProcessKeyPress(struct KeyCombination *kc,KeySym ks)
74 {
75 int oldKeysPressed;
76 int i;
77
78 oldKeysPressed=kc->KeysPressed;
79 for(i=0; i<kc->KeysNum; i++)
80 {
81 if(kc->Keys[i]==ks)
82 kc->KeysPressed|=(1<<i);
83 }
84 if(kc->KeysPressed!=oldKeysPressed && kc->KeysPressed==(1<<kc->KeysNum)-1)
85 kc->KeysArmed=1;
86 else
87 kc->KeysArmed=0;
88 }
89
KeyCombinationProcessKeyRelease(struct KeyCombination * kc,KeySym ks,int fire)90 int KeyCombinationProcessKeyRelease(struct KeyCombination *kc,KeySym ks,int fire)
91 {
92 int oldKeysPressed;
93 int i;
94
95 oldKeysPressed=kc->KeysPressed;
96 for(i=0; i<kc->KeysNum; i++)
97 {
98 if(kc->Keys[i]==ks)
99 kc->KeysPressed&=~(1<<i);
100 }
101 i=0;
102 if(kc->KeysPressed!=oldKeysPressed && oldKeysPressed==(1<<kc->KeysNum)-1 && kc->KeysArmed)
103 {
104 if(fire && kc->Fire)
105 kc->Fire();
106 i=1;
107 }
108 kc->KeysArmed=0;
109 return i;
110 }
111
PrintParseErrors(const char * resource,char * err)112 void PrintParseErrors(const char *resource,char *err)
113 {
114 if(*err)
115 {
116 char *nl=err-1;
117 char *nl1;
118 while((nl1=strchr(nl+1,'\n'))!=NULL)
119 {
120 *nl1=0;
121 fprintf(stderr,"%s: %s parse error: %s\n",program,resource,nl+1);
122 nl=nl1;
123 }
124 }
125 }
126