XChat 1.2: How to help XChat

Next Previous Contents

## 7. How to help XChat

## 7.1 Navigating the Code

The main source of XChat is in the /src directory. In it are all the .c and .h files that make up XChat. If you are looking round the code here's a little map:

- xchat.c - Main program file, contains main()
- xchat.h - Main header file, contains most of the major struct's used in XChat
- editlist.c - Generic code for handling editable lists (like the Userlist Buttons list)
- fkeys.c - Handles function keys
- gtkutil.c - Wrappers round GTK
- outbound.c - Code for handling commands
- inbound.c - Code for handling data from the server
- text.c - Code for text handling and logging
- plugin.c - All the plugin code

Most of the other files are easy to guess.

## 7.2 Writing Scripts

Dagmar d'Surreal has written the documentation for writing scripts, in xchatdox2.html

## 7.3 Writing Plugins

There should be a sample module under the sample directory, this gives a general overview of writing a module.

Firstly you must #define USE_PLUGIN before any #includes. You must also include xchat.h and plugin.h from the xchat main directory. Every module must export a function called module_init, it is passed the version number (an int), a pointer to the module struct for your module and a pointer to the current session. It returns an int

- 0 = success
- 1 = fail

The name and desc parts of the module structure must be filled out with strings.

You must check the version number is what you think it is (currently 2) before referencing anything else, the current version number is defined in plugin.h as MODULE_IFACE_VER.

The basic hook onto XChat, by a plugin, is a signal. At certain places in the code a signal is emitted. A chain of handlers (if any) are then called, each calling the next. If the first handler (and thus the handler that returns to the emitting function) returns TRUE then the emitting function doesn't carry out the default action. In this way a signal handler can over-right XChat's default actions with its own. Any module can hook a signal, using hook_signal and passing a pointer to an xp_signal struct, filling in the "signal", "callback", "naddr" and "mod" parts. They should be filled in like thus:

- signal - one of the XP_* defines in plugin.h
- callback - a pointer to a callback function passed 5 void *'s and a char. Use the XP_CALLBACK() define in plugin.h around it
- naddr - a pointer to a pointer (yes, double indirect) to a callback function (see last item)
- mod - your module handle, passed to you in module_init

At the end of the callback you use XP_CALLNEXT(naddrfunction, a, b, c, d, e, f) to call the next callback, a to f being the arguments you were passed. The plugin code in XChat updates the function pointed to by the "naddr" field to point to the next handler, or NULL if you are the last handler. You don't have to worry about that. If you don't want the default action to take place then use XP_CALLNEXT_ANDSET() not XP_CALLNEXT. Only 1 handler in a chain needs to use XP_CALLNEXT_ANDSET to abort the default action. Be aware that XP_CALLNEXT[_ANDSET] expand to include a return, so these must be at the end of the execution paths of your handler.

The signal handlers are passed 5 void *'s and a char (just seemed about enough), by convention the first void * is a pointer to the session or server struct. To cast as a signal callback use the define XP_CALLBACK like a GTK cast.

Most modules call module_add_cmds at some point. This hooks any commands for you without having to hook and parse all the command signals. You pass it a pointer to a struct module_cmd_set, which should be filled in like this:

- mod - the module handle passed to module_init
- cmds - a pointer to an array of struct commands (see below)

See the sample module for an example of the array of struct commands. Be aware that the struct module_cmd_set must be global as XChat uses and changes it.

When the module is removed the module_cleanup function is called, it is passed the module struct and the current session. You do not have to export a module_cleanup as all commands and hooks are removed by XChat.

Plugins call XChat functions directly and thus are more dependent on the XChat code base than scripts. Some of the common XChat functions that are used are listed below:

- PrintText (struct session *sess, char *text) - Prints "text" to the session "sess"
- handle_command (char *cmd, struct session *sess, int log) - Runs "cmd" as if it had been entered in the input box in session "sess". If log == 1 then the command it put in the history

I have also written a much more complete (and working) example of a plugin, it's called auto and is on the the XChat homepage.

### Signals

There is a list of all the current signals in plugins/SIGNALS. This may be added to in the future. If you think you have a good place for some more signals e-mail me (I'm Adam, see Authors). NOTE: This doesn't include text event signals, look in text.c for those details

Next Previous Contents