Programatically enumerating available XIM (X Input Method) servers

आशीष शुक्ल ा "\"Wah Java !!\"" <[email protected]> Tue, 14 Mar 2006 15:03:22 +0530
Newsgroups gmane.user-groups.linux.delhi.devel
Message-ID <1142328802.6309.2.camel@megahardlabs>
--===============1866148480==
Content-Type: multipart/signed; micalg=pgp-sha1;
	protocol="application/pgp-signature";
	boundary="=-CjJBj0nRPv20MxsxXdXY"


--=-CjJBj0nRPv20MxsxXdXY
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi mailing list,

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,=20
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 <X11/Xlib.h>
#include <X11/Xatom.h>

#include <stdio.h>
#include <stdlib.h>

#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 =3D None;

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

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

	xa_XIM_SERVERS =3D FetchAtom(display, XIM_SERVERS);

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

#ifdef DEBUG
	p =3D 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
=09
	pAtom =3D (Atom*)buffer;

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

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

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

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

		XConvertSelection(display, pAtom[i], xa_LOCALES, None, w_prog,=20
CurrentTime);
		XIfEvent(display, &event, &ResponseHandler,
(XPointer)SelectionNotify);
		if(!event.xselection.send_event)
		  printf(" is dead");
		if(event.xselection.property !=3D None)
		{
			p =3D 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 =3D XInternAtom(display, atom_name, True);
	if(atom =3D=3D None)
	{
		fprintf(stderr, "X Atom \"%s\" doesn't exists.\n", atom_name);
		if(w_prog !=3D None)
		{
			XDestroyWindow(display, w_prog);
			w_prog =3D None;
		}
		XCloseDisplay(display);
		exit(-1);
	}
	return atom;
}

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

I've compiled it using:
-- output begins here --
[wahjava@megahardlabs Xlib]$ cc -o list_im list_im.c -L/usr/X11R6/lib64
-lX11
list_im.c: In function =E2=80=98ResponseHandler=E2=80=99:
list_im.c:139: warning: cast from pointer to integer of different size
-- ouput ends here --

The warning is due to size of 'int' in 64bit code. 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),=20
output of my program is:

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

As above output clearly indicates that it has detected that XIM server=20
named "htt" and "iiimx" are running (I mean they're active not just=20
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 there might be bugs in
my code. Please help me out.

Thanx in advance,
Ashish Shukla "Wah Java !!"
--
Ashish Shukla "Wah Java !!"
=E0=A4=86=E0=A4=B6=E0=A5=80=E0=A4=B7 =E0=A4=B6=E0=A5=81=E0=A4=95=E0=A5=8D=
=E0=A4=B2=E0=A4=BE

  ,=3D ,-_-. =3D.
 ((_/)o o(\_))
  `-'(. .)`-'
      \_/

My blah, blah, blah at http://wahjava.blogspot.com/
My webpages at http://www.geocities.com/wah_java_dotnet/

My GPG Fingerprint: BBA9 AD7D BA71 61EB BE46 8CF5 E44A C663 A03F 4261

My GPG key at
http://keyserv.nic-se.se:11371/pks/lookup?op=3Dget&search=3D0xA03F4261
--
I've never been drunk, but often I've been overserved.
-- George Gobel

--
Ashish Shukla "Wah Java !!"
=E0=A4=86=E0=A4=B6=E0=A5=80=E0=A4=B7 =E0=A4=B6=E0=A5=81=E0=A4=95=E0=A5=8D=
=E0=A4=B2=E0=A4=BE

  ,=3D ,-_-. =3D.
 ((_/)o o(\_))
  `-'(. .)`-'
      \_/

My blah, blah, blah at http://wahjava.blogspot.com/
My webpages at http://www.geocities.com/wah_java_dotnet/

My GPG Fingerprint: BBA9 AD7D BA71 61EB BE46 8CF5 E44A C663 A03F 4261

My GPG key at
http://keyserv.nic-se.se:11371/pks/lookup?op=3Dget&search=3D0xA03F4261
--
Most people feel that everyone is entitled to their opinion.

--
Ashish Shukla "Wah Java !!"
=E0=A4=86=E0=A4=B6=E0=A5=80=E0=A4=B7 =E0=A4=B6=E0=A5=81=E0=A4=95=E0=A5=8D=
=E0=A4=B2=E0=A4=BE

  ,=3D ,-_-. =3D.
 ((_/)o o(\_))
  `-'(. .)`-'
      \_/

My blah, blah, blah at http://wahjava.blogspot.com/
My webpages at http://www.geocities.com/wah_java_dotnet/

My GPG Fingerprint: BBA9 AD7D BA71 61EB BE46 8CF5 E44A C663 A03F 4261

My GPG key at
http://keyserv.nic-se.se:11371/pks/lookup?op=3Dget&search=3D0xA03F4261
--
'It must have been Fate that brought you here,' said Twoflower.
'Yes, it's the sort of thing he likes to do,' said Rincewind.
(Interesting Times)

--
Ashish Shukla "Wah Java !!"
=E0=A4=86=E0=A4=B6=E0=A5=80=E0=A4=B7 =E0=A4=B6=E0=A5=81=E0=A4=95=E0=A5=8D=
=E0=A4=B2=E0=A4=BE

  ,=3D ,-_-. =3D.
 ((_/)o o(\_))
  `-'(. .)`-'
      \_/

My blah, blah, blah at http://wahjava.blogspot.com/
My webpages at http://www.geocities.com/wah_java_dotnet/

My GPG Fingerprint: BBA9 AD7D BA71 61EB BE46 8CF5 E44A C663 A03F 4261

My GPG key at
http://keyserv.nic-se.se:11371/pks/lookup?op=3Dget&search=3D0xA03F4261
--
        What the guy was doing was having a bad case of optical rectitus.
That would be typical of a "reseller" (AKA Salesman).  Most would not
even have a CLUE that the cards were based on the tulip chipset / driver.

- Michael Warf on linux-kernel


--=-CjJBj0nRPv20MxsxXdXY
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

iD8DBQBEFo3i5ErGY6A/QmERAuovAKCke8QsT+PqahKhQAXF437yp4NGsgCcCVkB
OkufwHlHprJtqSoxzWA9erQ=
=xx0n
-----END PGP SIGNATURE-----

--=-CjJBj0nRPv20MxsxXdXY--




--===============1866148480==
Content-Type: text/plain; charset="iso-8859-1"
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline