pcb 4.1.1
An interactive printed circuit board layout editor.
|
00001 #include <string.h> 00002 #include <stdlib.h> 00003 #include <errno.h> 00004 00005 #include "global.h" 00006 #include "hid.h" 00007 #include "resource.h" 00008 #include "hid/common/hid_resource.h" 00009 00010 /* #define DEBUG_HID_RESOURCE */ 00011 00012 static int button_count; // number of buttons we have actions for 00013 static int *button_nums; // list of button numbers 00014 static int *mod_count; // how many mods they have 00015 static unsigned *mods; // mods, in order, one button after another 00016 static Resource** actions; // actions, in order, one button after another 00017 00018 static Resource * 00019 res_wrap (char *value) 00020 { 00021 Resource *tmp; 00022 tmp = resource_create (0); 00023 resource_add_val (tmp, 0, value, 0); 00024 return tmp; 00025 } 00026 00027 static unsigned 00028 parse_mods (char *value) 00029 { 00030 unsigned m = 0; 00031 long int mod_num; 00032 char *s; 00033 00034 for (s=value; *s; s++) 00035 *s = tolower(*s); 00036 00037 s = strstr(value, "mod"); 00038 if (s) 00039 { 00040 s += 3; // skip "mod" to get to number 00041 errno = 0; 00042 mod_num = strtol(s, (char**) NULL, 0); 00043 if (!errno) 00044 m |= M_Mod(mod_num); 00045 } 00046 if (strstr(value, "shift")) 00047 m |= M_Shift; 00048 if (strstr(value, "ctrl")) 00049 m |= M_Ctrl; 00050 if (strstr(value, "alt")) 00051 m |= M_Alt; 00052 if (strstr(value, "up")) 00053 m |= M_Release; 00054 return m; 00055 } 00056 00057 static int 00058 button_name_to_num (const char *name) 00059 { 00060 /* All mouse-related resources must be named. The name is the 00061 mouse button number. */ 00062 if (!name) 00063 return -1; 00064 else if (strcasecmp (name, "left") == 0) 00065 return 1; 00066 else if (strcasecmp (name, "middle") == 0) 00067 return 2; 00068 else if (strcasecmp (name, "right") == 0) 00069 return 3; 00070 else if (strcasecmp (name, "up") == 0) 00071 return 4; 00072 else if (strcasecmp (name, "down") == 0) 00073 return 5; 00074 else if (strcasecmp (name, "scroll-left") == 0) 00075 return 6; 00076 else if (strcasecmp (name, "scroll-right") == 0) 00077 return 7; 00078 else 00079 return atoi (name); 00080 } 00081 00082 void 00083 load_mouse_resource (const Resource *res) 00084 { 00085 int bi, mi, a; 00086 int action_count; 00087 #ifdef DEBUG_HID_RESOURCE 00088 fprintf(stderr, "note mouse resource:\n"); 00089 resource_dump (res); 00090 #endif 00091 00092 button_count = res->c; 00093 button_nums = (int *)malloc(res->c * sizeof(int)); 00094 mod_count = (int *)malloc(res->c * sizeof(int)); 00095 action_count = 0; 00096 for (bi=0; bi<res->c; bi++) 00097 { 00098 if (res->v[bi].value) 00099 action_count++; 00100 00101 if (res->v[bi].subres) 00102 action_count += res->v[bi].subres->c; 00103 00104 } 00105 mods = (unsigned int *)malloc(action_count * sizeof(int)); 00106 actions = (Resource **)malloc(action_count * sizeof(Resource*)); 00107 00108 a = 0; 00109 for (bi=0; bi<res->c; bi++) 00110 { 00111 int button_num = button_name_to_num(res->v[bi].name); 00112 00113 if (button_num < 0) 00114 continue; 00115 00116 button_nums[bi] = button_num; 00117 mod_count[bi] = 0; 00118 00119 if (res->v[bi].value) 00120 { 00121 mods[a] = 0; 00122 actions[a++] = res_wrap (res->v[bi].value); 00123 mod_count[bi] = 1; 00124 } 00125 00126 if (res->v[bi].subres) 00127 { 00128 Resource *m = res->v[bi].subres; 00129 mod_count[bi] += m->c; 00130 00131 for (mi=0; mi<m->c; mi++, a++) 00132 { 00133 switch (resource_type (m->v[mi])) 00134 { 00135 case 1: /* subres only */ 00136 mods[a] = 0; 00137 actions[a] = m->v[mi].subres; 00138 break; 00139 00140 case 10: /* value only */ 00141 mods[a] = 0; 00142 actions[a] = res_wrap (m->v[mi].value); 00143 break; 00144 00145 case 101: /* name = subres */ 00146 mods[a] = parse_mods (m->v[mi].name); 00147 actions[a] = m->v[mi].subres; 00148 break; 00149 00150 case 110: /* name = value */ 00151 mods[a] = parse_mods (m->v[mi].name); 00152 actions[a] = res_wrap (m->v[mi].value); 00153 break; 00154 } 00155 } 00156 } 00157 } 00158 } 00159 00160 static Resource* 00161 find_best_action (int button, int start, unsigned mod_mask) 00162 { 00163 int i, j; 00164 int count = mod_count[button]; 00165 unsigned search_mask = mod_mask & ~M_Release; 00166 unsigned release_mask = mod_mask & M_Release; 00167 00168 // look for exact mod match 00169 for (i=start; i<start+count; i++) 00170 if (mods[i] == mod_mask) { 00171 return actions[i]; 00172 } 00173 00174 for (j=search_mask-1; j>=0; j--) 00175 if ((j & search_mask) == j) // this would work 00176 for (i=start; i<start+count; i++) // search for it 00177 if (mods[i] == (j | release_mask)) 00178 return actions[i]; 00179 00180 return NULL; 00181 } 00182 00183 void 00184 do_mouse_action (int button, int mod_mask) 00185 { 00186 Resource *action = NULL; 00187 int bi, i, a; 00188 00189 // find the right set of actions; 00190 a = 0; 00191 for (bi=0; bi<button_count && !action; bi++) 00192 if (button_nums[bi] == button) 00193 { 00194 action = find_best_action(bi, a, mod_mask); 00195 break; 00196 } 00197 else 00198 a += mod_count[bi]; // skip this buttons actions 00199 00200 if (!action) 00201 return; 00202 00203 for (i = 0; i < action->c; i++) 00204 if (action->v[i].value) 00205 if (hid_parse_actions (action->v[i].value)) 00206 return; 00207 }