Hi,

I've written following program in C (using Xlib) to list XIMs
available.
I've read the XIM specification (that ships with xorg-x11-doc package,
BTW I'm on Fedora Core 4 AMD64).

/* list_im.c -- begins here */
/* This program retrieves list of input method services exposed by the
X
* server, with their transport details and locale details
*/

#include
#include

#include
#include

#define XIM_SERVERS "XIM_SERVERS"
#define TRANSPORT "TRANSPORT"
#define LOCALES "LOCALES"

#define STR_ACTIVE "active"
#define STR_INACTIVE "inactive"

#define SIZE 256

static Atom FetchAtom(Display*, const char*)
#if __GNUC__
/* BTW, how to check for x86 architecture ? */
__attribute__((regparm(3)))
#endif
;
static Bool ResponseHandler(Display*, XEvent*, XPointer);
static Window w_prog = None;

int main()
{
Display* display = NULL;
Window w_root, w_im;
Atom xa_XIM_SERVERS;
Atom xa_TRANSPORT;
Atom xa_LOCALES;
unsigned char* buffer = NULL;
Atom propType;
int propFmt;
unsigned long nItems, nBytesRemaining;
char* p = NULL;
int i;
Atom* pAtom = NULL;
XEvent event;

display = XOpenDisplay(NULL);
if(!display)
{
fputs("XOpenDisplay() failed.\n", stderr);
return -1;
}

xa_XIM_SERVERS = FetchAtom(display, XIM_SERVERS);

w_root = XDefaultRootWindow(display);
XGetWindowProperty(display, w_root, xa_XIM_SERVERS, 0, SIZE,
False, XA_ATOM, &propType, &propFmt, &nItems,
&nBytesRemaining, &buffer);

#ifdef DEBUG
p = XGetAtomName(display, propType);
printf("Property Type: %s\n", p);
printf("Number of items: %d\n", nItems);
printf("Bytes remaining: %d\n", nBytesRemaining);
XFree(p);
#endif

pAtom = (Atom*)buffer;

xa_TRANSPORT = FetchAtom(display, TRANSPORT);
xa_LOCALES = FetchAtom(display, LOCALES);

w_prog = XCreateWindow(display, w_root, 0, 0, 1, 1, 0, 0,
InputOnly,
XDefaultVisual(display,
XDefaultScreen(display)),
0, NULL);

puts("Registered input methods:");
for(i = 0; i < nItems; i++)
{
p = XGetAtomName(display, pAtom[i]);
w_im = XGetSelectionOwner(display, pAtom[i]);

XConvertSelection(display, pAtom[i], xa_TRANSPORT, None,
w_prog,
CurrentTime);
XIfEvent(display, &event, &ResponseHandler,
(XPointer)SelectionNotify);
printf("\"%s\" is %s", p, ((w_im == BadWindow) ?
STR_INACTIVE:STR_ACTIVE));
XFree(p);
if(!event.xselection.send_event)
printf(" is dead");
if(event.xselection.property != None)
{
p = XGetAtomName(display, event.xselection.property);
printf(" at \"%s\"", p);
XFree(p);
}

XConvertSelection(display, pAtom[i], xa_LOCALES, None, w_prog,
CurrentTime);
XIfEvent(display, &event, &ResponseHandler,
(XPointer)SelectionNotify);
if(!event.xselection.send_event)
printf(" is dead");
if(event.xselection.property != None)
{
p = XGetAtomName(display, event.xselection.property);
printf(" at \"%s\"", p);
XFree(p);
}
putchar('\n');
}
XDestroyWindow(display, w_prog);
XFree(buffer);

XCloseDisplay(display);
}

static Atom FetchAtom(Display* display, const char* atom_name)
{
Atom atom = XInternAtom(display, atom_name, True);
if(atom == None)
{
fprintf(stderr, "X Atom \"%s\" doesn't exists.\n", atom_name);
if(w_prog != None)
{
XDestroyWindow(display, w_prog);
w_prog = None;
}
XCloseDisplay(display);
exit(-1);
}
return atom;
}

static Bool ResponseHandler(Display* display, XEvent* event, XPointer
pointer)
{
return (event->type == (int)pointer);
}
/* list_im.c - ends here */

On my machine I don't think I've any XIM server (except iiimx, and that
too usually is not running), so output of my program in that case is:

-- output begins here --
[wahjava@megahardlabs pc]$ ./list_im
X Atom "XIM_SERVERS" doesn't exists.
-- output ends here --

After running XIM server (in my case it is iiimx, in separate
terminal),
output of my program is:

-- output begins here --
[wahjava@pc Xlib]$ ./list_im
Registered input methods:
"@server=htt" is active
"@server=iiimx" is active
-- output ends here --

As above output clearly indicates that it has detected that XIM server
named "htt" and "iiimx" are running (I mean they're active not just
orphan atoms) but it is not giving the details of transport and
locales.

I'm a newbie in Xlib (but eager to learn it), so is there any bug in my
code ?

Thanx in advance,
Ashish Shukla alias Wah Java !!
--
http://wahjava.blogspot.com/