This file describes the API between userui_core and a userui plugin (eg, userui_text). It does not cover the kernel API, which is detailed in the file KERNEL_API. You want to read this file if you plan to write your own user interface. Function API ------------ Each userui module should define a struct userui_ops describing its operations, and also define a pointer to it called "userui_ops". See userui_skeleton.c for an example. The userui_ops struct defined for your module must contain the following elements : char *name; void (*prepare) (); void (*cleanup) (); void (*message) (unsigned long type, unsigned long level, int normally_logged, char *text); void (*update_progress) (unsigned long value, unsigned long maximum, char *text); void (*log_level_change) (); void (*redraw) (); void (*keypress) (int key); And some optional ones: unsigned long (*memory_required) (); char *optstring; struct option *longopts; int (*option_handler) (char c); char *(*cmdline_options) (); Each element in turn is described below: char *name; This is a short string identifying your module. void prepare() This function is the first to be called in your module. It is run pretty soon after the suspend cycle has started. This is where you do all your setup - this entails opening and reading all the files you will need, allocating all the memory you will need and anything else to avoid touching the filesystem once suspending has started. Hibernating will not proceed until this function exits. If you really need to abort the suspend process because something failed (not really recommended), you can send a USERUI_MSG_ABORT. This is described in Communicating with TuxOnIce. void cleanup() This is called after the suspend has completed (either through resuming or aborting). It is expected to clean up things like the console and undo any effects of prepare() that would otherwise persist. void message(type, level, normally_logged, text) This function is called by TuxOnIce when it wishes to update the message on the screen. FIXME ... fill in details of parameters! void update_progress(value, maximum, text) This function is called by TuxOnIce to update progress of suspending or resuming. The text parameter specifies the text to display in the middle of the progress bar. void log_level_change() Notifies the UI module that the kernel loglevel (given in console_loglevel) has changed - it may wish to update the display to give more or less verbosity as required. void redraw() Upon resuming, immediately after copying the original kernel back, video memory is normally filled with old boot messages that need to be cleared. This function is called to clear and redraw the screen from scratch. void keypress(int key) If the user presses a key whilst suspending, this function is called with the appropriate keycode. The following functions are optional: unsigned long memory_required() If the process will require a given amount of memory for suspending, that has not yet been allocated, it can specify an amount here (in bytes). char *optstring If the userui module wishes to accept extra command-line options, it can specify a string of characters here (getopt-style). Module authors should verify that it does not clash with existing options in handle_params() in userui_core.c. struct option *longopts If the userui module wishes to accept long-style command-line options, it can specify a pointer to an empty-terminated array of struct option's. int option_handler(char c) If not NULL, this function is called when command-line options are found that the userui_core could not handle. If the module handles the given option, then it should return 1. If not, it should return 0. char *cmdline_options() This function should returns a string containing the usage text for the extra options provided by this module. Communicating with TuxOnIce --------------------------- Most of the messages are handled by userui_core, but there may arise occasions where you wish to manipulate TuxOnIce directly. This can be achieved by using the send_message function: int send_message(int type, void* buf, int len); This function returns 1 on success (the message was successfully sent to the kernel) or 0 on failure. Some messages of interest are: type = USERUI_MSG_ABORT (no parameters) Aborts the current suspend cycle (eg because the user pressed Escape). type = USERUI_MSG_SET_STATE, buf = &suspend_action, len = sizeof(int) Sets the suspend_action variable to the given value. This allows you to change the following flags: SUSPEND_REBOOT, SUSPEND_PAUSE, SUSPEND_SLOW, SUSPEND_LOGALL, SUSPEND_SINGLESTEP, SUSPEND_PAUSE_NEAR_PAGESET_END. type = USERUI_MSG_GET_STATE (no parameters) This will tell the kernel to reply with the current suspend_action value. You should call this after a call to USERUI_MSG_SET_STATE to ensure the kernel and userspace are in sync. type = USERUI_MSG_SET_LOGLEVEL, buf = &new_loglevel, len = sizeof(int) Sets the console loglevel to the given value. type = USERUI_MSG_GET_LOGLEVEL, buf = &new_loglevel, len = sizeof(int) Gets the current console loglevel, and calls the log_level_change function to report it. Restrictions on your userui module ---------------------------------- Memory Allocation and Usage - it shouldn't use too much. All memory of the userui is mlock()'d so it is not swapped out to disk. It shouldn't try to allocate huge amounts of memory outside of your prepare() function as this will starve TuxOnIce of memory for IO. A resource limit is enforced while suspending so excessive allocations should hopefully return with ENOMEM, but you should avoid this in the first place. Disk access - Big no no. Do *NOT* try to access the disk whilst suspending as this will most likely corrupt the suspend image. Resource limits should cause file opening attempts to fail. If you want to opening a /proc entry or something not linked to a disk, do it in prepare(). Forking or threading - Don't fork mid-suspend. Resource limits will probably ensure that it fails. You can create forks or threads in prepare(). It should be safe so long as all threads follow these same rules. Exiting - Exiting before the suspend/resume cycle has finished may corrupt the image. Don't try it. Signal handlers are installed to catch most common signals and simply sleep the process for a while. Certain syscalls - It has been noted that calling select() or poll() to wait for data on a socket can be detrimental to suspending (causing things like several-second hangs whilst "Eating memory"). Minimalism is good - the process shouldn't do too much other than play with its own memory, respond to events and dump stuff to display.