void key_listener::expand_keys(int logical_key, const SDL_keysym& sym, const SDLMod& processed_mask, int depth) { SDL_keysym tmp; tmp = sym; static const int NUM_CHUNKS = 4; static const SDLMod chunks[NUM_CHUNKS] = { (SDLMod)KMOD_SHIFT, (SDLMod)KMOD_ALT, (SDLMod)KMOD_CTRL, (SDLMod)KMOD_META }; static const SDLMod ALL_CHUNKS = (SDLMod)(KMOD_SHIFT | KMOD_ALT | KMOD_CTRL | KMOD_META); static const int NUM_BITS = sizeof(SDLMod)*8; int bit_idx[NUM_BITS]; int remaining = ALL_CHUNKS & sym.mod & ~processed_mask; if(remaining == 0) { bind_key(logical_key, sym, false); return; } for(int i =0;i<NUM_CHUNKS;++i) { if(sym.mod & chunks[i] && !(processed_mask & chunks[i])) { SDLMod newmask = (SDLMod)(processed_mask | chunks[i]); SDLMod newmod = (SDLMod)(sym.mod & ~chunks[i]); int bit_count = 0; for(int j=0;j<NUM_BITS;++j) { if(chunks[i] & (1 << j)) { bit_idx[bit_count++] = j; } } int k_max = 1 << bit_count; for(int k=1;k < k_max;++k) { tmp.mod = newmod; for(int j=0;j<bit_count;++j) { int bit = 1 << j; if(k & bit) { tmp.mod = (SDLMod)(tmp.mod | (1 << bit_idx[j])); } } expand_keys(logical_key, tmp, newmask, depth+1); } return; } } }
varargs mapping SetManipulate(mixed key, mixed desc){ if( !key ){ key = "default"; } if( !desc ){ if( mapp(key) ){ Manipulate = expand_keys(key); } else { Manipulate["default"] = key; } } else { Manipulate[key] = desc; } return Manipulate; }
varargs mapping SetPull(mixed key, mixed desc){ if( !key ){ key = "default"; } if( !desc ){ if( mapp(key) ){ Pull = expand_keys(key); } else { Pull["default"] = key; } } else { Pull[key] = desc; } return Pull; }
varargs mapping SetScratch(mixed key, mixed desc){ if( !key ){ key = "default"; } if( !desc ){ if( mapp(key) ){ Scratch = expand_keys(key); } else { Scratch["default"] = key; } } else { Scratch[key] = desc; } return Scratch; }
varargs mapping SetKnock(mixed key, mixed desc){ if( !key ){ key = "default"; } if( !desc ){ if( mapp(key) ){ Knock = expand_keys(key); } else { Knock["default"] = key; } } else { Knock[key] = desc; } return Knock; }
void key_listener::bind_key(int logical_key, const SDL_keysym& sym, bool collapse_doubles) { if(collapse_doubles) { expand_keys(logical_key, sym, KMOD_NONE,0); return; } unbind_key(sym); binding_map::iterator binding_itor = bindings_.find(sym.sym); if(binding_itor == bindings_.end()) { mod_map m; bindings_[sym.sym] = m; binding_itor = bindings_.find(sym.sym); } assert(binding_itor != bindings_.end()); binding_itor->second[static_cast<SDLMod>(sym.mod)] = logical_key; }
string flat_map(mapping mp) { mapping carte = ([]); mixed key, val; string retkey, retval, retstring; retstring = ""; carte = expand_keys(mp); foreach( key, val in carte){ if(arrayp(key)){ if(!sizeof(key)) retkey = "BLANK ARRAY"; else retkey = "ARRAY ("+implode(key,", ")+")"; } else if(objectp(key)) retkey = "OBJECT ("+file_name(key)+")"; else if(intp(key)) retkey = ""+key; else retkey = key; if(arrayp(val)){ if(!sizeof(val)) retval = "BLANK ARRAY"; else retval = "ARRAY ("+implode(val,", ")+")"; } else if(objectp(val)) retval = "OBJECT ("+file_name(val)+")"; else if(intp(val)) retval = ""+val; else retval = val; if(!retstring || retstring == "") retstring = retkey+":"+retval; else retstring += ", "+retkey+":"+retval; } return retstring;