///////////////////////////////////////////////////////
| 79 | |
| 80 | //////////////////////////////////////////////////////////// |
| 81 | std::shared_ptr<_XIM> openXim() |
| 82 | { |
| 83 | const std::lock_guard lock(UnixDisplayImpl::mutex); |
| 84 | |
| 85 | assert(!UnixDisplayImpl::weakSharedDisplay.expired() && |
| 86 | "Display is not initialized. Call priv::openDisplay() to initialize it."); |
| 87 | |
| 88 | static std::weak_ptr<_XIM> xim; |
| 89 | |
| 90 | auto sharedXIM = xim.lock(); |
| 91 | if (!sharedXIM) |
| 92 | { |
| 93 | // Create a new XIM instance |
| 94 | |
| 95 | // We need the default (environment) locale and X locale for opening |
| 96 | // the IM and properly receiving text |
| 97 | // First save the previous ones (this might be able to be written more elegantly?) |
| 98 | const char* p = nullptr; |
| 99 | const std::string prevLoc((p = std::setlocale(LC_ALL, nullptr)) ? p : ""); |
| 100 | const std::string prevXLoc((p = XSetLocaleModifiers(nullptr)) ? p : ""); |
| 101 | |
| 102 | // Set the locales from environment |
| 103 | std::setlocale(LC_ALL, ""); |
| 104 | XSetLocaleModifiers(""); |
| 105 | |
| 106 | // Create the input context |
| 107 | const auto closeIM = [](XIM im) |
| 108 | { |
| 109 | if (im) |
| 110 | XCloseIM(im); |
| 111 | }; |
| 112 | sharedXIM.reset(XOpenIM(UnixDisplayImpl::weakSharedDisplay.lock().get(), nullptr, nullptr, nullptr), closeIM); |
| 113 | xim = sharedXIM; |
| 114 | |
| 115 | // Restore the previous locale |
| 116 | if (!prevLoc.empty()) |
| 117 | std::setlocale(LC_ALL, prevLoc.c_str()); |
| 118 | |
| 119 | if (!prevXLoc.empty()) |
| 120 | XSetLocaleModifiers(prevXLoc.c_str()); |
| 121 | } |
| 122 | |
| 123 | return sharedXIM; |
| 124 | } |
| 125 | |
| 126 | |
| 127 | //////////////////////////////////////////////////////////// |
no test coverage detected