+/* key combo handling, to be called by drivers that support it */
+void in_combos_find(int *binds, int last_key, int *combo_keys, int *combo_acts)
+{
+ int act, u;
+
+ *combo_keys = *combo_acts = 0;
+ for (act = 0; act < sizeof(binds[0]) * 8; act++)
+ {
+ int keyc = 0;
+ for (u = 0; u <= last_key; u++)
+ if (binds[u] & (1 << act))
+ keyc++;
+
+ if (keyc > 1)
+ {
+ // loop again and mark those keys and actions as combo
+ for (u = 0; u <= last_key; u++)
+ {
+ if (binds[u] & (1 << act)) {
+ *combo_keys |= 1 << u;
+ *combo_acts |= 1 << act;
+ }
+ }
+ }
+ }
+}
+
+int in_combos_do(int keys, int *binds, int last_key, int combo_keys, int combo_acts)
+{
+ int i, ret = 0;
+
+ for (i = 0; i <= last_key; i++)
+ {
+ int acts;
+ if (!(keys & (1 << i)))
+ continue;
+
+ acts = binds[i];
+ if (!acts)
+ continue;
+
+ if (combo_keys & (1 << i))
+ {
+ int acts_c = acts & combo_acts;
+ int u = last_key;
+ if (acts_c) {
+ // let's try to find the other one
+ for (u = i + 1; u <= last_key; u++)
+ if ( (keys & (1 << u)) && (binds[u] & acts_c) ) {
+ ret |= acts_c & binds[u];
+ keys &= ~((1 << i) | (1 << u));
+ break;
+ }
+ }
+ // add non-combo actions if combo ones were not found
+ if (u >= last_key)
+ ret |= acts & ~combo_acts;
+ } else
+ ret |= acts;
+ }
+
+ return ret;
+}
+