Back to index

im-sdk  12.3.91
Functions | Variables
xaux_object_common.c File Reference
#include <stdio.h>
#include <limits.h>
#include <unistd.h>
#include <wait.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include "xaux_object.h"

Go to the source code of this file.

Functions

static Bool xaux_object_event_filter (Display *display, Window window, XEvent *event, XPointer pointer)
static Bool xaux_object_get_extwin (xaux_class_t *xc, Display *display)
static Bool xaux_object_launch_ext (xaux_class_t *xc, Display *display)
static Bool xaux_object_init_class (Display *display, Window window, xaux_class_t *xc)
void xaux_object_print (xaux_object_t *xaux_object)
xaux_object_txaux_object_new ()
Bool xaux_object_init (xaux_object_t *xaux_object, aux_t *aux, char *classname, xaux_class_t *xaux_classes)
void xaux_object_destroy (xaux_object_t *xaux_object)
char * xaux_object_get_classname_from_utfname (CARD16 *utf_name, int utf_name_len)
static xaux_class_txaux_object_get_class_from_name (xaux_object_t *xaux_object, char *classname)
static void xaux_object_signal_child_handler (int sig, siginfo_t *info, void *ucontext)
static void xaux_object_register_signal_child_handler ()
static char * xaux_object_compose_aux_data (aux_t *aux, xaux_class_t *xc, aux_data_t *aux_data, int type, int *string_len)
aux_data_txaux_object_decompose_from_string (xaux_class_t *xc, unsigned char *string_buf)
Bool xaux_object_send_message (aux_t *aux, xaux_class_t *xc, int im_id, int ic_id, aux_data_type_t type, Atom atom_client, Atom atom_data)
Bool xaux_object_send_property (aux_t *aux, xaux_class_t *xc, const unsigned char *p, int len, Atom atom_client)
Bool xaux_object_draw_aux_module (xaux_object_t *xaux_object, aux_t *aux, char *classname, aux_data_t *aux_data, int type)
static Bool xaux_object_process_property_update (Display *display, Window window, Atom atom, xaux_class_t *xc)
static Bool xaux_object_process_client_message (Display *display, Window window, XClientMessageEvent *event)

Variables

static void(* aux_setvalue )(aux_t *, const unsigned char *, int)
static unsigned char *(* compose )(const aux_data_t *, int *)
static aux_t aux_tmp
xaux_class_t xaux_classes []

Function Documentation

static char* xaux_object_compose_aux_data ( aux_t aux,
xaux_class_t xc,
aux_data_t aux_data,
int  type,
int *  string_len 
) [static]

Definition at line 314 of file xaux_object_common.c.

{
       XPoint        point;
       char *        string_buf;
       size_t        i;
       int           *ip;
       char          *sp;
       size_t        total;
       size_t        len;

       /* estimate enough size for string_buf */

       /* size for header */
       total = SX_SIZE_PROP_HEADER_DRAW;

       /* add size for integer_values */
       total += (sizeof (CARD32) * aux_data->integer_count);

       /* add size for string_values */
       if (aux_data->string_count > 0) {
              for (i = 0; i < aux_data->string_count; i++) {
                     /* number of bytes */
                     len = aux_data->string_list[i].length;

                     /* consider padding */
                     total +=
                     ((sizeof (CARD16) + len + 3) / 4) * 4;
              }
       }

       if ((string_buf = (char *)calloc(total, sizeof(char))) == NULL) {
              return NULL;
       }

       SX_PROP_ATOM_AUX_NAME(string_buf) = xc->atom_classname;
       SX_PROP_TYPE(string_buf) = type;
       SX_PROP_INDEX(string_buf) = xc->index;
       SX_PROP_IMID(string_buf) = aux_data->im;
       SX_PROP_ICID(string_buf) = aux_data->ic;
       SX_PROP_SOWIN(string_buf) = xc->sowin;

       SX_PROP_CLIENTWIN(string_buf) = aux->service->client_window(aux);

       aux->service->point(aux, &point);
       SX_PROP_POSX(string_buf) = point.x;
       SX_PROP_POSY(string_buf) = point.y;

       SX_PROP_FOCUSWIN(string_buf) = aux->service->window(aux);

       SX_PROP_INT_COUNT(string_buf) = aux_data->integer_count;
       SX_PROP_STR_COUNT(string_buf) = aux_data->string_count;

       ip = (int *)SX_PROP_INT_LIST(string_buf);

       if (aux_data->integer_count > 0) {
              for (i = 0; i < aux_data->integer_count; i++) {
                     *ip++ = aux_data->integer_list[i];
              }
       }

       sp = (char *)SX_PROP_STR_LIST(string_buf);

       if (aux_data->string_count > 0) {
              char *        ob;
              size_t        obl;

              ob = sp;

              for (i = 0; i < aux_data->string_count; i++) {
                     int           pn;
                     unsigned char *p;
                     size_t        j;

                     len = aux_data->string_list[i].length;
                     p = aux_data->string_list[i].ptr;

                     *(CARD16 *)ob = len;
                     ob += sizeof (CARD16);

                     for (j = 0; j < len; j++) {
                            *ob++ = *p++;
                     }
                            
                     pn = padding[(sizeof (CARD16) + len) % 4];

                     /* padding */
                     for (j = 0; j < pn; j++) {
                            *ob++ = 0U;
                     }
                     sp = ob;
              }
       }

       *string_len = sp - &(string_buf[0]);
       return (string_buf);
}

Here is the caller graph for this function:

aux_data_t* xaux_object_decompose_from_string ( xaux_class_t xc,
unsigned char *  string_buf 
)

Definition at line 411 of file xaux_object_common.c.

{
       aux_data_t *  aux_data;
       int           i;

       aux_data = (aux_data_t *)calloc(1, sizeof(aux_data_t));
       if (aux_data == NULL)
              return (NULL);

       /* header */
       aux_data->type = AUX_DATA_SETVALUE;
       aux_data->im = XS_PROP_IMID(string_buf);
       aux_data->ic = XS_PROP_ICID(string_buf);
       aux_data->aux_index = xc->index;
       aux_data->aux_name = (unsigned char *)xc->utfname;
       aux_data->aux_name_length = strlen(xc->classname)*sizeof(CARD16);

       /* int values */
       aux_data->integer_count = XS_PROP_INT_COUNT(string_buf);

       if (aux_data->integer_count > 0) {
              aux_data->integer_list = (int *)XS_PROP_INT_LIST(string_buf);
       } else {
              aux_data->integer_list = NULL;
       }

       /* string values */
       aux_data->string_count = XS_PROP_STR_COUNT(string_buf);
       if (aux_data->string_count > 0) {
              unsigned char * prop_str = XS_PROP_STR_LIST(string_buf);

              if ((aux_data->string_list = (aux_string_t *)calloc(aux_data->string_count, 
                                          sizeof (aux_string_t))) == NULL) {
                     free ((char *)aux_data);
                     return NULL;
              }

              for (i = 0; i < aux_data->string_count; i++) {
                     int    j;
                     int    pn;
                     size_t len;

                     len = *((CARD16 *)(prop_str));
                     prop_str += sizeof (CARD16);
                     aux_data->string_list[i].ptr = prop_str;
                     aux_data->string_list[i].length = len;
                     prop_str += len;
                     pn = padding[(sizeof(CARD16) + len) % 4];
                     for (j = 0; j < pn; j++) {
                            *prop_str++ = 0U;
                     }
              }
       } else {
              aux_data->string_list = NULL;
       }

       aux_data->string_ptr = NULL;

       return aux_data;
}

Here is the caller graph for this function:

void xaux_object_destroy ( xaux_object_t xaux_object)

Definition at line 95 of file xaux_object_common.c.

{
       if (xaux_object == NULL ||
           xaux_object->display ||
           xaux_object->window == None)
              return;

       XDestroyWindow(xaux_object->display, xaux_object->window);

       return;
}

Here is the caller graph for this function:

Bool xaux_object_draw_aux_module ( xaux_object_t xaux_object,
aux_t aux,
char *  classname,
aux_data_t aux_data,
int  type 
)

Definition at line 551 of file xaux_object_common.c.

{
       char *        string_buf;
       int           string_len;
       Bool          rv = True;
       Display *     display;
       Atom          atom_client;

       xaux_class_t *       xc;

       DEBUG_printf("aux_tmp: %p, aux_setvalue: %p, compose: %p\n", &aux_tmp, aux_setvalue, compose);

       display = aux->service->display(aux);

       /* make the aux_object as the current focused aux object */
       XSetSelectionOwner(display,
              xaux_object->atom_classname, xaux_object->window, CurrentTime);

       xc = xaux_object_get_class_from_name(xaux_object, classname);
       DEBUG_printf("xaux_object_get_class_from_name, return: xc: %p\n", xc);
       if (xc == NULL)
              return False;

       if (xaux_object_get_extwin(xc, display) == False)
              return False;

       /* workaround for "stored reference to aux_t is corrupred" problem */
       aux_tmp.ic = aux->ic;

       atom_client = XInternAtom(display, classname, True);

       if (type == AUX_DATA_START || type == AUX_DATA_DONE) {
              rv = xaux_object_send_message(aux, xc, aux_data->im, aux_data->ic, type, atom_client, (Atom)None);
       } else if (type == AUX_DATA_DRAW) {
              string_buf = (char *)xaux_object_compose_aux_data(aux, xc, aux_data, type, &string_len);

              DEBUG_printf("so_Draw[%s] im:0x%x ic:0x%x in=%d sn=%d\n",
                     xc->classname, aux_data->im, aux_data->ic,
                     aux_data->integer_count, aux_data->string_count);
              DEBUG_printf("total = %d\n", string_len);

              if (string_buf != NULL) {
                     rv = xaux_object_send_property(aux, xc,
                            (unsigned char *)string_buf, string_len, atom_client);
                     free(string_buf);
              }
       }

       return (rv);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Bool xaux_object_event_filter ( Display *  display,
Window  window,
XEvent *  event,
XPointer  pointer 
) [static]

Definition at line 694 of file xaux_object_common.c.

{
       switch (event->type) {
       case ClientMessage:
              return (xaux_object_process_client_message(display, window,
                     (XClientMessageEvent *)event));
       }
       return False;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static xaux_class_t* xaux_object_get_class_from_name ( xaux_object_t xaux_object,
char *  classname 
) [static]

Definition at line 209 of file xaux_object_common.c.

{
       xaux_class_t *aux_class;
       Display *display;
       Window owner;

       Atom atom_classname = (Atom)None;

       if (xaux_object == NULL || classname == NULL)
              return (NULL);

       display = xaux_object->display;
       atom_classname = XInternAtom(display, classname, True);

       /* check whether the classname is registered by the owner */
       DEBUG_printf("classname: %s, atom_classname: %p\n", classname, atom_classname);
       if (atom_classname == (Atom)None)
              return (NULL);

       /* check whether the classname is for the binary aux module */
       for (aux_class = xaux_object->xaux_classes; aux_class->classname; aux_class++) {
              if (!strcasecmp(classname, aux_class->classname))
                     return (aux_class);
       }

       /* check whether the classname is launched by an aux manager */
       owner = XGetSelectionOwner(display, atom_classname);
       if (owner == (Window)None)
              return (NULL);

       for (aux_class = xaux_object->xaux_classes; aux_class->classname; aux_class++) {
              if (aux_class->extwin == owner)
                     return (aux_class);
       }

       return (NULL);
}

Here is the caller graph for this function:

char* xaux_object_get_classname_from_utfname ( CARD16 utf_name,
int  utf_name_len 
)

Definition at line 191 of file xaux_object_common.c.

{
       int i;
       char *classname = NULL;

       if (!utf_name || !*utf_name)
              return (NULL);

       classname = (char *)calloc(utf_name_len + 1, sizeof(char));
       if (classname == NULL) return (NULL);

       for (i = 0; i < utf_name_len; i++) {
              classname[i] = utf_name[i] & 0xff;
       }

       return (classname);
}

Here is the caller graph for this function:

static Bool xaux_object_get_extwin ( xaux_class_t xc,
Display *  display 
) [static]

Definition at line 247 of file xaux_object_common.c.

{
       if (xc->atom_extwin == (Atom)None)
              return False;

       xc->extwin = XGetSelectionOwner(display, xc->atom_extwin);
       if (xc->extwin == None) {
              return False;
       }
       return True;
}

Here is the caller graph for this function:

Bool xaux_object_init ( xaux_object_t xaux_object,
aux_t aux,
char *  classname,
xaux_class_t xaux_classes 
)

Definition at line 40 of file xaux_object_common.c.

{
       Display *display;
       xaux_class_t *p;

       if (!aux)
              return False;

       if (!classname || !*classname)
              return False;

       if (!xaux_classes)
              return False;

       /* workaround for "stored reference to aux_t is corrupred" problem */
       aux_tmp.ic = aux->ic;
       aux_setvalue = aux->service->aux_setvalue;
       compose = aux->service->compose;

       display = aux->service->display(aux);

       xaux_object->display = display;

       xaux_object->classname = classname;
       xaux_object->atom_classname = XInternAtom(display, classname, False);

       xaux_object->window = XCreateSimpleWindow(display, RootWindow(display, 0),
                   0, 0, 1, 1, 0, 0, 0);

       if (xaux_object->window == None) {
              DEBUG_printf("xaux_object_new: creating window failed.\n");
              return False;
       }

       XSetSelectionOwner(display,
              xaux_object->atom_classname, xaux_object->window, CurrentTime);

        XSelectInput(display, xaux_object->window, PropertyChangeMask);

        aux->service->register_X_filter(display, xaux_object->window,
              ClientMessage, ClientMessage,
              xaux_object_event_filter, NULL);

       xaux_object->xaux_classes = xaux_classes;
       p = xaux_classes;
       while(p->classname != NULL) {
              xaux_object_init_class(display, xaux_object->window, p);
              p++;
       }

       xaux_object_print(xaux_object);

       return (True);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Bool xaux_object_init_class ( Display *  display,
Window  window,
xaux_class_t xc 
) [static]

Definition at line 133 of file xaux_object_common.c.

{
       char          buf[XAUX_MAXCLASSNAMELEN + XAUX_MAXSUFFIXLEN + 1];
       int           i;
       int           len;

       if (xc == NULL)
              return False;

       DEBUG_printf("xaux_object_init_class ===\n");
       if (access(xc->extexec, X_OK) != 0) {
              DEBUG_printf("executable \"%s\" not found\n", xc->extexec);
              return False;
       }

       if (xc->classname == NULL) {
              return False;
       }

       xc->atom_classname = XInternAtom(display, xc->classname, False);

       len = XAUX_MAXCLASSNAMELEN + XAUX_MAXSUFFIXLEN + 1;
       snprintf(buf, len, "%s%s", xc->classname, XAUX_SOWIN_SUFFIX);
       xc->atom_sowin = XInternAtom(display, buf, False);

       snprintf(buf, len, "%s%s", xc->classname, XAUX_EXTWIN_SUFFIX);
       xc->atom_extwin = XInternAtom(display, buf, False);

       for (i = 0; i < XAUX_SX_NATOMS; i++) {
              snprintf(buf, len, "%s%s_%d",
                     xc->classname, XAUX_SX_SUFFIX, i);
              xc->atom_sx[i] = XInternAtom(display, buf, False);
       }
       xc->atom_sx_idx = 1;

       for (i = 0; i < XAUX_XS_NATOMS; i++) {
              snprintf(buf, len, "%s%s_%d",
                     xc->classname, XAUX_XS_SUFFIX, i);
              xc->atom_xs[i] = XInternAtom(display, buf, False);
       }
       xc->atom_xs_idx = 1;

       xc->extwin = (Window)0;

       if (xaux_object_launch_ext(xc, display) == False)
              return (False);

       i = 0;
       while (xaux_object_get_extwin(xc, display) == False) {
              DEBUG_printf("classname: %s, retry number: %d, sleep: %d um\n", xc->classname, i, XAUX_RETRYINT_EXTWIN);
              if (i++ > XAUX_MAXRETRY_EXTWIN)
                     break;
              usleep(XAUX_RETRYINT_EXTWIN);
       }

       return True;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Bool xaux_object_launch_ext ( xaux_class_t xc,
Display *  display 
) [static]

Definition at line 281 of file xaux_object_common.c.

{
       pid_t         pid;

       if (xc->atom_extwin == (Atom)None)
              return False;

       if (xaux_object_get_extwin(xc, display) == True) {
              return True;
       }

       xaux_object_register_signal_child_handler();

#ifdef sun
       pid = fork1();
#else
       pid = fork();
#endif

       if (pid == (pid_t)(-1)) { /* fork failed */
              return False;
       } else if (0 == pid) { /* child */
#ifdef DEBUG_XAUX
              chdir("/tmp");
#endif
              execl(xc->extexec, xc->classname, NULL);
              _exit(1);
       }
       
       /* parent */
       return True;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 29 of file xaux_object_common.c.

{
       xaux_object_t *xaux_object;

       xaux_object = (xaux_object_t *)calloc(1, sizeof(xaux_object_t));
       if (xaux_object == NULL)
              return NULL;

       return xaux_object;
}

Here is the caller graph for this function:

void xaux_object_print ( xaux_object_t xaux_object)

Definition at line 107 of file xaux_object_common.c.

{
#ifdef DEBUG
       xaux_class_t *p;

       if (xaux_object == NULL ||
           xaux_object->display ||
           xaux_object->window == None)
              return;

       printf("xaux_object: %p\n", xaux_object);
       printf("  classname: %s\n", xaux_object->classname);
       printf("  window: %d\n", xaux_object->window);

       p = xaux_object->xaux_classes;
       while(p->classname != NULL) {
              printf(" class: %s\n", p->classname);
              p++;
       }
#endif
       return;
}

Here is the caller graph for this function:

static Bool xaux_object_process_client_message ( Display *  display,
Window  window,
XClientMessageEvent *  event 
) [static]

Definition at line 670 of file xaux_object_common.c.

{
       aux_data_t    aux_data_;
       aux_data_t    *aux_data = &(aux_data_);
       aux_data_type_t      type;
       xaux_class_t  *xc;

       xc = &xaux_classes[0];

       aux_data->im = ((CARD32)(event->data.l[1])) >> 16;
       aux_data->ic = ((CARD32)(event->data.l[1])) & 0xffff;
       aux_data->aux_index = (CARD32)(event->data.l[2]);

       type = (CARD32)(event->data.l[3]);

       switch (type) {
       case AUX_DATA_SETVALUE:
              return xaux_object_process_property_update(display, window,
                            (Atom)(event->data.l[4]), xc);
       default:
              return False;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Bool xaux_object_process_property_update ( Display *  display,
Window  window,
Atom  atom,
xaux_class_t xc 
) [static]

Definition at line 607 of file xaux_object_common.c.

{
       Atom          actual_type_return;
       int           actual_format_return;
       unsigned long nitem_return;
       unsigned long bytes_after_return;
       unsigned char *prop_return;
       int           r;
       char          *atom_name;
       aux_data_t    *aux_data;
       int           size;
       unsigned char   *p;

       atom_name = XGetAtomName (display, atom);
       DEBUG_printf("xaux_object_process_property_update: atom_name: %s\n", atom_name);
       DEBUG_printf("aux_tmp: %p, aux_setvalue: %p, compose: %p\n", &aux_tmp, aux_setvalue, compose);

       r = XGetWindowProperty(display, window,
                            atom, 0, INT_MAX, False,
                            AnyPropertyType, &actual_type_return,
                            &actual_format_return, &nitem_return,
                            &bytes_after_return, &prop_return);

       if (r != Success) {
              return False;
       }

       aux_data = xaux_object_decompose_from_string(xc, prop_return);
       if (aux_data == NULL) {
              XFree(prop_return);
              return False;
       }

       /* compose and send message to engine */

       /* workaround for "stored reference to aux_t is corrupred" problem */
       if ((p = /*ic->aux->service->*/compose(aux_data, &size)) == NULL) {
              free(aux_data->string_list);
              free(aux_data);
              XFree(prop_return);
              return False;
       }

       DEBUG_printf("so_SetValue[%s] im:0x%x ic:0x%x in=%d sn=%d\n",
                     xc->classname, aux_data->im, aux_data->ic,
                     aux_data->integer_count, aux_data->string_count);

       /* workaround for "stored reference to aux_t is corrupred" problem */
       /*ic->aux->service->*/aux_setvalue(/*ic->aux*/&aux_tmp, p, size);

       free(p);
       free(aux_data->string_list);
       free(aux_data);

       XFree(prop_return);

       return True;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 269 of file xaux_object_common.c.

{
    struct sigaction act;

    act.sa_handler = NULL;
    act.sa_sigaction = xaux_object_signal_child_handler;
    sigfillset(&act.sa_mask);
    act.sa_flags = SA_SIGINFO;

    sigaction(SIGCHLD, &act, NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Bool xaux_object_send_message ( aux_t aux,
xaux_class_t xc,
int  im_id,
int  ic_id,
aux_data_type_t  type,
Atom  atom_client,
Atom  atom_data 
)

Definition at line 475 of file xaux_object_common.c.

{
       Display *            display;
       XClientMessageEvent  event;

       display = aux->service->display(aux);

       if (xaux_object_get_extwin(xc, display) == False)
              return False;

       event.type = ClientMessage;
       event.serial = 0;
       event.send_event = True;
       event.display = display;
       event.window = xc->extwin;
       event.message_type = atom_client;
       event.format = 32;

       event.data.l[0] = xc->atom_classname;
       event.data.l[1] = ((CARD32)im_id << 16) | ((CARD32)ic_id & 0xffff);
       event.data.l[2] = xc->index;
       event.data.l[3] = type; /* CREATE, DONE, ... */
       event.data.l[4] = atom_data;

       XSendEvent(display, xc->extwin, True, 0, (XEvent *)(&event));

       /* needed in en_US.UTF-8 */
        XFlush(display);

       return True;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Bool xaux_object_send_property ( aux_t aux,
xaux_class_t xc,
const unsigned char *  p,
int  len,
Atom  atom_client 
)

Definition at line 514 of file xaux_object_common.c.

{
       Display *     display;
       int           i = 1;
       Bool          rv;
       Window        win;

       display = aux->service->display(aux);

       if (xaux_object_get_extwin(xc, display) == False)
              return False;

       win = xc->extwin;

       XChangeProperty(display, win,
              xc->atom_sx[xc->atom_sx_idx], XA_STRING,
              8, PropModeReplace, (unsigned char *)p, len);

       if (xaux_object_send_message(aux, xc,
              aux->service->im_id(aux), aux->service->ic_id(aux),
              AUX_DATA_DRAW, atom_client, xc->atom_sx[xc->atom_sx_idx]) == False) {
                     return False;
       }

       /* XFlush() has been called in xaux_object_send_message() */
       
       if (++xc->atom_sx_idx == XAUX_SX_NATOMS)
              xc->atom_sx_idx = 1;
       
       return True;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void xaux_object_signal_child_handler ( int  sig,
siginfo_t *  info,
void *  ucontext 
) [static]

Definition at line 259 of file xaux_object_common.c.

{
    pid_t   pid;
    int     status;

    while ((pid = waitpid(info->si_pid, &status, WNOHANG|WUNTRACED)) > 0) {
        printf("pid %d: die\n", pid);
    }
}

Here is the caller graph for this function:


Variable Documentation

void(* aux_setvalue)(aux_t *, const unsigned char *, int) [static]

Definition at line 16 of file xaux_object_common.c.

aux_t aux_tmp [static]

Definition at line 18 of file xaux_object_common.c.

unsigned char*(* compose)(const aux_data_t *, int *) [static]

Definition at line 17 of file xaux_object_common.c.

Definition at line 91 of file aux_so.c.