Xlib tutorial part 10 -- Encapsulation

by Alan at Sun 15th Mar 2009 1:00AM EST

Hello, welcome to part 10 of the Xlib tutorial.

Before we start, I would like to mention something. At the end of each section, I make sure that my code works. If it doesn't work on your unix system let me know and we'll see if we can work it out. Each week I'm want to give you something that works so that you can play with it. Play is an important part of learning. Run the examples, but also try changing them and running them again to see what else you can do with your knowledge. If you break it and can't get back to a working piece of code, you can always start again from my code. In a few weeks, I'll be describing some possible ways of debugging X lib code.

This part of the tutorial, we're going continue encapsulating code. First, we've moved all the button related functions to their own file. That way they're out of the way. Also, the two XChar2b functions, and the resource functions each get their own file. We've also moved all the Xrm database initialization code into its own function in the resources file.


XrmDatabase setupDB(Display *dpy,
			XrmOptionDescRec *xrmTable, int nCommandLineResources,
			const char *progname, int *argc, char **argv){
	XrmDatabase db;
	char filename[256];

	db = XrmGetDatabase(dpy);
	XrmParseCommand(&db, xrmTable, nCommandLineResources, progname, argc, argv);
	sprintf(filename, "%.240s.resources", progname);
	if(XrmCombineFileDatabase(filename, &db, False)){
		printf("read %s
", filename);
	} else  {
		printf("didn't read %s
", filename);
	return db;


And while we were at it we added a new function to get string resources.


char *getResource(Display *dpy, XrmDatabase db, char *name, char *cl, char *def){
	XrmValue v;
	char * type;
	if(XrmGetResource(db, name, cl, &type, &v))
		return strdup(v.addr);
	return strdup(def);

getFont() and getColour() , of course, remain the same.

In C, with encapsulation, comes the need for .h header files. such as common.h


#define DefGC(dpy) DefaultGC(dpy, DefaultScreen(dpy))

XrmDatabase setupDB(Display *dpy,
			XrmOptionDescRec *xrmTable, int nCommandLineResources,
			const char *progname, int *argc, char **argv);
char *getResource(Display *dpy, XrmDatabase db, char *name, char *cl, char *def);
unsigned long getColour(Display *dpy,  XrmDatabase db, char *name,
			char *cl, char *def);
XFontStruct *getFont(Display *dpy, XrmDatabase db, char *name,
		char *cl, char *def);
int XChar2bLen(XChar2b *string);
int utf8toXChar2b(XChar2b *output_r, int outsize, const char *input, int inlen);

and button.h

typedef void (*Callback)(void *cbdata);

typedef struct Button Button;
struct Button {
	XChar2b * text;
	int text_width;
	int font_ascent;
	int width, height;
	unsigned long border, background, foreground;
	void *cbdata;
	Callback buttonRelease;

void createButton(Display *dpy, Window parent, char *text, XFontStruct *font,
		int x, int y, int width, int height,
		unsigned long foreground, unsigned long background, unsigned long border,
		XContext ctxt, Callback callback, void *cbdata);
void buttonExpose(Button *button, XEvent *ev);
void buttonConfigure(Button *button, XEvent *ev);
void buttonEnter(Button *button, XEvent *ev);
void buttonLeave(Button *button, XEvent *ev);
void buttonExpose(Button *button, XEvent *ev);

I'm going to stop there this week. Last week's section was long and next week we'll see how we can turn this into menus and menubars, which is going to be even longer.

You can get the new source code from /xtut10.tgz Type 'make' in the directory and it should compile on any unix/linux/bsd system. You may have to tweak the Makefile, if you can't figure it out, ask.

Things to try:

Comments are closed.