Back to index

im-sdk  12.3.91
XIMPublic.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 
00043 #ifdef HAVE_CONFIG_H
00044 #include <config.h>
00045 #endif
00046 
00047 #include <stdlib.h>
00048 #include <sys/types.h>
00049 #include <X11/Xlib.h>
00050 #include <X11/Xutil.h>
00051 #include "XIMPublic.hh"
00052 #include "Xlcint.h"
00053 
00054 #include <dlfcn.h>
00055 
00056 static void *dl_module = 0;
00057 static XIM (*im_openIM)(XLCd, Display*, XrmDatabase, char*, char*)
00058   = (XIM(*)(XLCd, Display*, XrmDatabase, char*, char*))0;
00059 
00060 extern "C" {
00061   extern char *XSetIMValues(
00062 #if NeedVarargsPrototypes
00063                          XIM /* im */, ...
00064 #endif
00065                          );
00066           }
00067 
00068 #ifdef sun
00069 #define XIIIMP_PATH     "/usr/openwin/lib/locale/common/xiiimp.so.2"
00070 #else /* Linux */
00071 #define XIIIMP_PATH     IIIMLIBDIR "/xiiimp.so.2"
00072 #endif /* Linux */
00073 
00074 #include <stdio.h>
00075 
00076 void
00077 XIMPublic::OpenIM() {
00078   char *tmpmodifiers = NULL;
00079 
00080   if (!dl_module) {
00081     dl_module = dlopen(XIIIMP_PATH, RTLD_LAZY);
00082     if (!dl_module) return; // fatal error
00083     im_openIM =
00084       (XIM(*)(XLCd, Display*, XrmDatabase, char*, char*))dlsym(dl_module,
00085                                                         "_IIIMP_OpenIM");
00086     if (!im_openIM) return; // fatal error
00087   }
00088   /* 
00089      Untidy hack.  When users set XMODIFIERS environment variable beforehand,
00090      XLC regard it as the modifier specification.   Therefore, if it specifies
00091      XIM-based IM, _IIIMP_OpenIM would fail to open IM because it could deal with
00092      only IIIMP-based IM.
00093   */
00094 
00095   tmpmodifiers = getenv("XMODIFIERS");
00096   if (tmpmodifiers) {
00097     unsetenv("XMODIFIERS");
00098     XSetLocaleModifiers("");
00099   }
00100   XLCd lcd = _XlcCurrentLC();
00101   if (tmpmodifiers) {
00102     setenv("XMODIFIERS", tmpmodifiers, 1);
00103     XSetLocaleModifiers("");
00104   }
00105 
00106   xim = (*im_openIM)(lcd, display, (XrmDatabase) NULL,
00107                    (char*)0, (char *)0);
00108 
00109   if (xim) {
00110     char *ret;
00111 
00112     if (ifname.length())
00113       ret = XSetIMValues(xim,
00114                       "engineInterfaceName", (char*)ifname,
00115                       "applicationType", (char*)application_name,
00116                       0);
00117     else
00118       ret = XSetIMValues(xim,
00119                       "applicationType", (char*)application_name,
00120                       0);
00121     if (default_font_name.length())
00122       ret = XSetIMValues(xim,
00123                       "defaultFontName", (char*)default_font_name,
00124                       0);
00125 
00126     // create a root IC for X-AUX initialization
00127     root_xic =
00128       XCreateIC(xim,
00129               XNInputStyle, XIMPreeditCallbacks|XIMStatusCallbacks,
00130               0);
00131     if (root_xic)
00132       XSetICFocus(root_xic);
00133   }
00134   return;
00135 }
00136 
00137 XIM
00138 XIMPublic::getXIM() {
00139   if (!xim) OpenIM();
00140   return xim;
00141 }
00142 
00143 void
00144 XIMPublic::CloseIM() {
00145   if (root_xic) XDestroyIC(root_xic);
00146   if (xim) XCloseIM(xim);
00147 
00148   return;
00149 }
00150 
00151 const CompoundString&
00152 XIMPublic::getIfName() const {
00153   return ifname;
00154 }
00155 
00156 XIMPublic::
00157 XIMPublic(IMArg *args, int n) : IMProtocol(args, n) {
00158 
00159   input_context_list.disable_reordering();
00160 
00161   xim = 0;
00162   root_xic = 0;
00163 }
00164 
00165 XIMPublic::
00166 ~XIMPublic() {
00167   delete start_keys.keylist;
00168   delete stop_keys.keylist;
00169 
00170   return;
00171 }
00172 
00173 int
00174 XIMPublic::setSelectionOwner(Window im_window,
00175                           char *name, Atom *selection) {
00176   Window owner;
00177   *selection = XInternAtom(display, name, False);
00178 
00179   if ((owner = XGetSelectionOwner(display, *selection)) != im_window) {
00180     if (owner == None) {
00181       XSetSelectionOwner(display, *selection, im_window, CurrentTime);
00182       return True;
00183     } else {
00184       return False;
00185     }
00186   }
00187   return True;
00188 }
00189 
00190 int
00191 XIMPublic::set_values(IMArg *args, int n) {
00192   if (n == 0) return 0;
00193   for (IMArg *argp = args; argp < &args[n]; argp++) {
00194     switch (argp->id) {
00195     case DisplayConnection:
00196       display = (Display*)argp->value; // extension 
00197       break;
00198     case IFName:
00199       ifname = (char*)argp->value; // extension 
00200       break;
00201     case AppName:
00202       application_name = (char*)argp->value; // extension 
00203       break;
00204     case DisableStatusArea:
00205       disable_status_area = (Bool)(long)argp->value; // extension
00206       break;
00207     case DefaultFontName:
00208       default_font_name = (char*)argp->value; // extension
00209       break;
00210     default:
00211       (void)IMProtocol::set_values(argp, 1);
00212       break;
00213     }
00214   }
00215   return 0;
00216 }
00217 
00218 Bool
00219 XIMPublic::isConversionKey(unsigned int kcode, unsigned int kstate,
00220                           int convOn) {
00221   int i;
00222   KeySym ksym = XKeycodeToKeysym(display, kcode, 0);
00223   XIMTriggerKey *ximp_keyp;
00224 
00225   if (convOn)
00226     ximp_keyp = stop_keys.keylist;
00227   else
00228     ximp_keyp = start_keys.keylist;
00229 
00230   for (i = 0; i < start_keys.count_keys; i++, ximp_keyp++) {
00231     if ((ximp_keyp->keysym == ksym) &&
00232        ((kstate & ximp_keyp->modifier_mask) == ximp_keyp->modifier)) {
00233       return True;
00234     }
00235   }
00236   return False;
00237 }
00238 
00239 void
00240 XIMPublic::select_destroy_emask(Window win) {
00241   XWindowAttributes win_attr;
00242   XGetWindowAttributes(display, win, &win_attr);
00243   XSelectInput(display, win,
00244               (win_attr.your_event_mask | StructureNotifyMask));
00245   return;
00246 }
00247 void
00248 XIMPublic::select_keypress_emask(Window win) {
00249   XWindowAttributes win_attr;
00250   XGetWindowAttributes(display, win, &win_attr);
00251   XSelectInput(display, win, (win_attr.your_event_mask | KeyPressMask));
00252   return;
00253 }
00254 void
00255 XIMPublic::select_keyrelease_emask(Window win) {
00256   XWindowAttributes win_attr;
00257   XGetWindowAttributes(display, win, &win_attr);
00258   XSelectInput(display, win, (win_attr.your_event_mask | KeyReleaseMask));
00259   return;
00260 }
00261 void
00262 XIMPublic::unselect_destroy_emask(Window win) {
00263   XWindowAttributes win_attr;
00264   XGetWindowAttributes(display, win, &win_attr);
00265   XSelectInput(display, win,
00266               (win_attr.your_event_mask & ~StructureNotifyMask));
00267   return;
00268 }
00269 void
00270 XIMPublic::unselect_keypress_emask(Window win) {
00271   XWindowAttributes win_attr;
00272   XGetWindowAttributes(display, win, &win_attr);
00273   XSelectInput(display, win,
00274               (win_attr.your_event_mask & ~KeyPressMask));
00275   return;
00276 }
00277 void
00278 XIMPublic::unselect_keyrelease_emask(Window win) {
00279   XWindowAttributes win_attr;
00280   XGetWindowAttributes(display, win, &win_attr);
00281   XSelectInput(display, win,
00282               (win_attr.your_event_mask & ~KeyReleaseMask));
00283   return;
00284 }