+#ifdef XIM_XLIB /* starting XIM specific codes */
+
+/* Callbacks for IM are supported from X11R6 or later. */
+#ifdef HAVE_XREGISTERIMINSTANTIATECALLBACK
+
+static Boolean xim_initted = False;
+
+/* Called from when XIM is destroying.
+ Clear all the XIC when the XIM was destroying... */
+static void
+IMDestroyCallback (XIM im, XPointer client_data, XPointer call_data)
+{
+ struct device *d = (struct device *)client_data;
+ Lisp_Object tail;
+
+ DEVICE_FRAME_LOOP (tail, d)
+ {
+ struct frame *target_frame = XFRAME (XCAR (tail));
+ if (FRAME_X_P (target_frame) && FRAME_X_XIC (target_frame))
+ {
+ /* XDestroyIC (FRAME_X_XIC (target_frame)); */
+ FRAME_X_XIC (target_frame) = NULL;
+ }
+ }
+
+ DEVICE_X_XIM (d) = NULL;
+ xim_initted = False;
+ return;
+}
+
+/* This is registered in XIM_init_device (when DEVICE is initializing).
+ This activates XIM when XIM becomes available. */
+static void
+IMInstantiateCallback (Display *dpy, XPointer client_data, XPointer call_data)
+{
+ struct device *d = (struct device *)client_data;
+ XIM xim;
+ char *name, *class;
+ XIMCallback ximcallback;
+ Lisp_Object tail;
+
+ /* if no xim is presented, initialize xim ... */
+ if ( xim_initted == False )
+ {
+ xim_initted = True;
+ XtGetApplicationNameAndClass (dpy, &name, &class);
+ DEVICE_X_XIM (d) = xim = XOpenIM (dpy, XtDatabase (dpy), name, class);
+
+ /* destroy callback for im */
+ ximcallback.callback = (XIMProc) IMDestroyCallback;
+ ximcallback.client_data = (XPointer) d;
+ XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL);
+ }
+
+ /* activate XIC on all the X frames... */
+ DEVICE_FRAME_LOOP (tail, d)
+ {
+ struct frame *target_frame = XFRAME (XCAR (tail));
+ if (FRAME_X_P (target_frame) && !FRAME_X_XIC (target_frame))
+ {
+ XIM_init_frame (target_frame);
+ }
+ }
+ return;
+}
+#endif /* HAVE_XREGISTERIMINSTANTIATECALLBACK */
+
+/* Initialize XIM for X device.
+ Register the use of XIM using XRegisterIMInstantiateCallback. */