Defines | Functions | Variables

iliad_app.c File Reference

Implementation of application-level functions. More...

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <X11/Xlib.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <liberdm/display.h>
#include <liberipc/eripc.h>
#include <liberipc/eripcviewer.h>
#include <liberipc/eripctoolbar.h>
#include <liberipc/eripcpagebar.h>
#include "iliad_api.h"
#include "iliad_app.h"

Defines

#define EVQ_SIZE   1024
#define IPC_BUF_SIZE   1024

Functions

void * gtk_main_func (void *arg)
int evq_init ()
gboolean evq_gtk (GtkWidget *widget, GdkEvent *event, gpointer ptr)
void * evq_ipc (void *arg)
int evq_enqueue (const iliad_event *ev)
int evq_exit ()
int app_init (char *prgname)
 Initialise GTK and X and create main window.
void app_exit ()
 Clean up before application terminates.
GtkWidget * app_window ()
 Returns the GTK handle of the application window.
Display * app_xdisplay ()
 Returns the X display.
Window app_xwindow ()
 Returns the X handle of the application window.
int app_events_pending ()
 Returns number of events in the event queue.
void app_wait_event (iliad_event *ev)
 Return next event from the event queue.
int sync_bars (int mask)
 Synchronise with toolbar and/or pagebar.
FILE * app_debug ()
 Debug output file handle.

Variables

static GtkWidget * window = NULL
static Display * display = NULL
static Window xwindow
static pthread_t gtk_main_thread
static pthread_t evq_ipc_thread
struct {
   iliad_event   q [EVQ_SIZE]
   iliad_event *   write
   iliad_event *   read
   pthread_mutex_t   ex
   pthread_cond_t   not_empty
ev_q
 Event queue.
static int sync_events
 Flags indicating receipt of synchronisation events from toolbar and pagebar.

Detailed Description

Implementation of application-level functions.

This file implements the initialisation and event queue functions declared in iliad_app.h. Two functions are run as separate threads for running the GTK event loop and receiving inter-process communication (IPC) from the toolbar and pagebar.


Function Documentation

FILE* app_debug (  ) 

Debug output file handle.

This function returns a writable file handle to one of the following, in order of declining priority: the terminal on which a current SSH session is running (/dev/pts/0), the file /tmp/iliad_api.debug (opened to append new messages), or stderr. The files are opened on demand, and opening the first two is retried every time this function is called.

Returns:
File handle
int app_events_pending (  ) 

Returns number of events in the event queue.

If the return value is not 0, a subsequent app_wait_event() will not block.

Returns:
number of available events
void app_exit (  ) 

Clean up before application terminates.

The GTK and IPC event handling threads are terminated. This function must be called outside any gdk_threads_enter()...gdk_threads_leave() region since it calls these functions itself (and the GTK lock is not re-entrant).

int app_init ( char *  prgname  ) 

Initialise GTK and X and create main window.

This function creates an application main window of the correct size and obtains the GTK and X window handle and the X display. Besides, the event mask is set, the GTK event handlers installed, the common event queue is set up and the GTK and IPC event loop threads are created.

Parameters:
prgname Name or path of the command as which this application was started. If this is not correct, the application will fail to receive most GTK events for unknown reasons. Pass argv[0] here.
Returns:
0 OK, != 0 error. In the latter case, the application should terminate.
void app_wait_event ( iliad_event ev  ) 

Return next event from the event queue.

If no event is available, this function blocks until there is.

Parameters:
ev pointer to write event struct to
GtkWidget* app_window (  ) 

Returns the GTK handle of the application window.

app_init() must have been called successfully before this function can be used.

Display* app_xdisplay (  ) 

Returns the X display.

app_init() must have been called successfully before this function can be used.

Window app_xwindow (  ) 

Returns the X handle of the application window.

app_init() must have been called successfully before this function can be used.

int evq_enqueue ( const iliad_event ev  ) 

This function adds an event to the common (GTK + IPC) event queue after obtaining access by locking the mutex. If the queue is already full, the event is discarded.

Parameters:
ev event to queue
Returns:
0 on success, 1 on overflow.
int evq_exit (  ) 

Clean up event queue prior to application exit by destroying mutex and condition variable for event queue access control.

Returns:
0 OK, !=0 error from pthread_cond_destroy() or pthread_mutex_destroy()
gboolean evq_gtk ( GtkWidget *  widget,
GdkEvent *  event,
gpointer  ptr 
)

GTK event handler function. Receives GTK events and converts them to corresponding iliad_event type events to be written to the queue. Button press events are held back until the corresponding button release event to form a combined pen drag event. Key press events are translated to the mnemonic constants in iliad_app.h.

Parameters:
widget ignored
event GTK event
ptr ignored
Returns:
always TRUE
int evq_init (  ) 

Initialise event FIFO read and write pointers and mutex and condition variable.

Returns:
0 OK, !=0 error from pthread_mutex_init() or pthread_cond_init().
void * evq_ipc ( void *  arg  ) 

IPC event queue thread. Iliad IPC messages are received from the toolbar and the pagebar and are converted to iliad_event type events to be queued.

Parameters:
arg ignored
Returns:
This function never returns, but is terminated by evq_exit().
void * gtk_main_func ( void *  arg  ) 

Separate thread which runs the GTK event loop by calling gtk_main(). The argument is ignored, and NULL is always returned.

int sync_bars ( int  mask  ) 

Synchronise with toolbar and/or pagebar.

Send synchronise messages to toolbar and/or pagebar and wait for receipt of synchronise events from them. Times out after approximately one second. This works only via the reporting of sync events by evq_ipc() and therefore requires app_init() to have been called before.

Synchronising with the tool/pagebar seems to cause their latest event to be resent. It is apparently not necessary for ensuring their region of the display is updated.

Parameters:
mask Bit mask; generate from SYNC_TOOLBAR and SYNC_PAGEBAR
Returns:
SYNC_ERROR if a synchronise message could not be sent, otherwise SYNC_OK or SYNC_TIMEOUT.

Variable Documentation

struct { ... } ev_q [static]

Event queue.

Common event queue for relevant GTK events and IPC events. Contains a FIFO of iliad_event structs, a mutex and a condition variable for access control between threads.