Back to index

im-sdk  12.3.91
guiIM.c
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 #include "guiIM.h"
00044 #include "XimpIm.h"
00045 #include "iiimpDL.h"
00046 #include <X11/Xatom.h>
00047 
00048 typedef enum {
00049   ON_DESKTOP_PANEL,
00050   ATTACH_TO_APP_FRAME
00051 } IMStatusPlacement;
00052 
00053 typedef enum {
00054   IM_OFF = 0,
00055   IM_ON
00056 } IMEnabled;
00057 
00058 typedef struct {
00059   IMEnabled im_enabled;
00060   IMEnabled status_enabled;
00061   IMEnabled lookup_enabled;
00062   IMStatusPlacement status_placement;
00063 } IMSettings;
00064 
00065 static IMSettings current_setting;
00066 static Bool current_setting_enabled;
00067 static Atom im_settings_atom = None;
00068 static const char *_IM_SETTINGS = "_IM_SETTINGS";
00069 
00070 static Bool GetIMSettingsPropertyFilter (Display *display,
00071                                     Window window,
00072                                     XEvent *event,
00073                                     XPointer client_data);
00074 
00075 static void ChangeStatus(XIC, StatusAttr, XPointer);
00076 static void ChangePreedit(XIC, PreeditAttr, XPointer);
00077 
00078 static Bool
00079 SetInputStyle(XicCommon ic, XIMArg *values) {
00080   XIMArg *p;
00081   XimCommon im = (XimCommon)ic->core.im;
00082   Bool status = False;
00083 
00084   for (p = values; p->name != NULL; p++) {
00085     if (strcmp(p->name, XNInputStyle) == 0) {
00086       ic->core.input_style = (XIMStyle)p->value;
00087       ic->ximp_icpart->value_mask |= XIMP_INPUT_STYLE;
00088 
00089       if (ic->core.input_style & XIMStatusArea)
00090        XIC_GUI(ic, change_status) = ChangeStatusArea;
00091       else if (ic->core.input_style & XIMStatusNothing)
00092        XIC_GUI(ic, change_status) = ChangeStatusNothing;
00093 
00094       if (ic->core.input_style & XIMPreeditArea)
00095        XIC_GUI(ic, change_preedit) = ChangePreeditArea;
00096       else if (ic->core.input_style & XIMPreeditPosition)
00097        XIC_GUI(ic, change_preedit) = ChangePreeditPosition;
00098       else if (ic->core.input_style & XIMPreeditNothing)
00099        XIC_GUI(ic, change_preedit) = ChangePreeditNothing;
00100       status = True;
00101       break;
00102     }
00103   }
00104   /* Set fallback lookup method */
00105   XIC_GUI(ic, change_lookup) = ChangeLookup;
00106 
00107   if (im->dl_impart) {
00108     XIMStyles *styles = im->dl_impart->styles;
00109     int i;
00110     if (styles && styles->count_styles != 0) {
00111       for (i = 0; i < styles->count_styles; i++) {
00112        if (ic->core.input_style == styles->supported_styles[i]) {
00113          if (im->dl_impart->change_status)
00114            XIC_GUI(ic, change_status) = im->dl_impart->change_status;
00115          if (im->dl_impart->change_preedit)
00116            XIC_GUI(ic, change_preedit) = im->dl_impart->change_preedit;
00117          if (im->dl_impart->change_lookup)
00118            XIC_GUI(ic, change_lookup) = im->dl_impart->change_lookup;
00119          break;
00120        }
00121       }
00122     }
00123   }
00124 
00125   return status;
00126 }
00127 
00128 extern XICGUI
00129 CreateGUI(XicCommon ic, XIMArg *arg) {
00130   XICGUIRec* gui_icpart = 0;
00131   XimCommon im = (XimCommon)ic->core.im;
00132   Display *display = im->core.display;
00133 
00134   gui_icpart = (XICGUIRec*)Xmalloc(sizeof(XICGUIRec));
00135   if (!gui_icpart) return 0;
00136 
00137   memset(gui_icpart, 0, sizeof(XICGUIRec));
00138   ic->gui_icpart = gui_icpart;
00139 
00140   XIC_GUI(ic, change_status) = ChangeStatus; /* default */
00141   XIC_GUI(ic, change_preedit) = ChangePreedit; /* default */
00142 
00143   SetScreenNumber(ic);
00144 
00145   if (im_settings_atom == None)
00146     im_settings_atom = XInternAtom (display, _IM_SETTINGS, False);
00147 
00148   _XRegisterFilterByType (display,
00149                        RootWindow(display, XIC_GUI(ic, screen_number)),
00150                        PropertyNotify, PropertyNotify,
00151                        GetIMSettingsPropertyFilter, (XPointer)ic);
00152 
00153   /* register a handler for dl_impart to return key events */
00154   if (im->dl_impart &&
00155       im->dl_impart->register_forwardevent)
00156     im->dl_impart->register_forwardevent((XIC)ic, IMForwardEvent);
00157 
00158   /* Need to set inputstyle to the ic first */
00159   if (!SetInputStyle(ic, arg)) {
00160     Xfree(gui_icpart);
00161     return 0;
00162   }
00163   ic->gui_icpart = gui_icpart;
00164   return gui_icpart;
00165 }
00166 
00167 static void
00168 ChangeStatus(XIC xic, StatusAttr reason, XPointer call_data) {
00169   /* do nothing  */
00170   return;
00171 }
00172 
00173 static void
00174 ChangePreedit(XIC xic, PreeditAttr reason, XPointer call_data) {
00175   /* do nothing  */
00176   return;
00177 }
00178 
00179 extern void
00180 DestroyGUI(XicCommon ic) {
00181   if (ic->gui_icpart) Xfree(ic->gui_icpart);
00182   ic->gui_icpart = 0;
00183 }
00184 
00185 void
00186 SetScreenNumber(XicCommon ic) {
00187   XWindowAttributes attr;
00188   if (None != ic->core.focus_window) {
00189     if (XGetWindowAttributes(ic->core.im->core.display,
00190                           ic->core.focus_window, &attr)) {
00191       XIC_GUI(ic, screen_number) = XScreenNumberOfScreen(attr.screen);
00192     } else {
00193       XIC_GUI(ic, screen_number) = DefaultScreen(ic->core.im->core.display);
00194     }
00195   } else {
00196     XIC_GUI(ic, screen_number) = DefaultScreen(ic->core.im->core.display);
00197   }
00198 }
00199 
00200 Bool
00201 GetIMSettings (XicCommon ic)
00202 {
00203   Atom type;
00204   unsigned char *data = NULL;
00205   int format;
00206   unsigned long length = 0, bytes_after;
00207   Display *display = ic->core.im->core.display;
00208 
00209   if (XGetWindowProperty (display,
00210                        RootWindow(display, XIC_GUI(ic, screen_number)),
00211                        im_settings_atom, 0L, 1000000L,
00212                        False, AnyPropertyType, &type, &format, &length,
00213                        &bytes_after, (unsigned char **)&data ) == Success &&
00214       data != NULL)
00215     {
00216       memmove (&current_setting, data, sizeof (IMSettings));
00217       Xfree (data);
00218       current_setting_enabled = True;
00219       return True;
00220     }
00221   else
00222     current_setting_enabled = False;
00223   return False;
00224 }
00225 
00226 static Bool
00227 GetIMSettingsPropertyFilter (Display *display,
00228                           Window window,
00229                           XEvent *event,
00230                           XPointer client_data)
00231 {
00232   if (event->xproperty.atom != im_settings_atom)
00233     return False;
00234 
00235   return GetIMSettings ((XicCommon)client_data);
00236 }
00237 
00238 Bool IsIMEnabled ()
00239 {
00240   return ((current_setting_enabled &&
00241           current_setting.im_enabled == IM_ON) ||
00242          !current_setting_enabled);
00243 }
00244 
00245 Bool IsIMStatusEnabled ()
00246 {
00247   return ((current_setting_enabled &&
00248           current_setting.im_enabled == IM_ON &&
00249           current_setting.status_enabled == IM_ON) ||
00250          !current_setting_enabled);
00251 }
00252 
00253 Bool IsIMStatusAttached ()
00254 {
00255   return ((current_setting_enabled &&
00256           current_setting.im_enabled == IM_ON &&
00257           current_setting.status_placement == ATTACH_TO_APP_FRAME) ||
00258          !current_setting_enabled);
00259 }
00260 
00261 Bool IsIMLookupEnabled ()
00262 {
00263   return ((current_setting_enabled &&
00264           current_setting.im_enabled == IM_ON &&
00265           current_setting.lookup_enabled == IM_ON) ||
00266          !current_setting_enabled);
00267 }