1 /* 2 * XKb Switch API for using in vim libcall() 3 * 4 * Copyright (C) 2013 by Alexei Rad'kov 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the Free 8 * Software Foundation; either version 3 of the License, or (at your option) 9 * any later version. 10 */ 11 12 #include <algorithm> 13 #include "XKeyboard.hpp" 14 15 using namespace std; 16 using namespace kb; 17 18 namespace 19 { 20 class XKeyboardWrapper 21 { 22 public: XKeyboardWrapper()23 XKeyboardWrapper() : xkb( NULL ), unusable( false ) 24 {} 25 ~XKeyboardWrapper()26 ~XKeyboardWrapper() 27 { 28 delete xkb; 29 } 30 get(void)31 XKeyboard * get( void ) 32 { 33 if ( unusable ) 34 return NULL; 35 36 if ( xkb ) 37 return xkb; 38 39 try 40 { 41 xkb = new XKeyboard((size_t)(-1)); 42 xkb->open_display(); 43 } 44 catch( ... ) 45 { 46 unusable = true; 47 return NULL; 48 } 49 50 return xkb; 51 } 52 53 private: 54 XKeyboard * xkb; 55 bool unusable; 56 57 } xkb; 58 59 string_vector symNames; 60 getSymNames(void)61 string_vector & getSymNames( void ) 62 { 63 static bool loaded = false; 64 65 if ( loaded ) 66 return symNames; 67 68 XKeyboard * xkb = ::xkb.get(); 69 70 if ( ! xkb ) 71 { 72 loaded = true; 73 return symNames; 74 } 75 76 loaded = true; 77 xkb->build_layout(symNames); 78 return symNames; 79 } 80 } 81 82 83 extern "C" 84 { Xkb_Switch_getXkbLayout(const char *)85 const char * Xkb_Switch_getXkbLayout( const char * /* unused */ ) 86 { 87 try 88 { 89 XKeyboard * xkb = ::xkb.get(); 90 91 if ( ! xkb ) 92 return ""; 93 94 string_vector & syms = getSymNames(); 95 96 return syms.at( xkb->get_group() ).c_str(); 97 } 98 catch( ... ) 99 { 100 } 101 102 return NULL; 103 } 104 105 Xkb_Switch_setXkbLayout(const char * newgrp)106 const char * Xkb_Switch_setXkbLayout( const char * newgrp ) 107 { 108 try 109 { 110 XKeyboard * xkb = ::xkb.get(); 111 112 if ( ! xkb ) 113 return ""; 114 115 string_vector & syms = getSymNames(); 116 117 if ( newgrp == NULL || newgrp[ 0 ] == '\0' ) 118 return NULL; 119 120 string_vector::iterator i = find( syms.begin(), syms.end(), 121 newgrp ); 122 123 if ( i == syms.end() ) 124 return NULL; 125 126 xkb->set_group( i - syms.begin() ); 127 } 128 catch( ... ) 129 { 130 } 131 132 return NULL; 133 } 134 } 135 136