Back to index

im-sdk  12.3.91
Classes | Typedefs | Enumerations | Functions
letools.cpp File Reference
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "lexmlconf.h"
#include "SunIM.h"
#include "IMArg.h"
#include "keysyms.h"

Go to the source code of this file.

Classes

struct  _LangList
struct  _Action

Typedefs

typedef struct _LangList LangList
typedef enum _ActionType ActionType
typedef struct _Action

Enumerations

enum  _ActionType {
  ACT_NONE = 0, ACT_ARG, ACT_INSTALL, ACT_REMOVE,
  ACT_DEFAULT, ACT_LANG, ACT_HOTKEY, ACT_ADDKEY,
  ACT_DELKEY, ACT_APPENDMOD = 100, ACT_PREPENDMOD, ACT_REMOVEMOD,
  ACT_MODLIST, ACT_APPENDKEY, ACT_REMOVEKEY
}

Functions

static LangListlang_list_new (const char *lang)
static LangListlang_list_add (LangList *list, const char *lang)
static void lang_list_free (LangList *list)
static void read_supported_lang (Action *act, const char *modname)
void usage (const char *name)
static char * strndup (const char *s, size_t n)
static HotKeyStruct * parse_hotkey (char *keys)
static Action * parse_arg (int argc, char **argv)
int main (int argc, char **argv)

Class Documentation

struct _LangList

Definition at line 19 of file letools.cpp.

Collaboration diagram for _LangList:
Class Members
char * language
struct _LangList * next
struct _Action

Definition at line 42 of file letools.cpp.

Collaboration diagram for _Action:
Class Members
HotKeyList * addhotkey
int clearhotkey
char * filename
int globalmode
LangList * langlist
HotKeyList * removehotkey
ActionType type
int verbose

Typedef Documentation

typedef struct _Action

Definition at line 53 of file letools.cpp.

typedef enum _ActionType ActionType
typedef struct _LangList LangList

Enumeration Type Documentation

Enumerator:
ACT_NONE 
ACT_ARG 
ACT_INSTALL 
ACT_REMOVE 
ACT_DEFAULT 
ACT_LANG 
ACT_HOTKEY 
ACT_ADDKEY 
ACT_DELKEY 
ACT_APPENDMOD 
ACT_PREPENDMOD 
ACT_REMOVEMOD 
ACT_MODLIST 
ACT_APPENDKEY 
ACT_REMOVEKEY 

Definition at line 24 of file letools.cpp.


Function Documentation

static LangList* lang_list_add ( LangList list,
const char *  lang 
) [static]

Definition at line 68 of file letools.cpp.

{
    LangList *l, *ll;

    l = lang_list_new(lang);
    if (list != NULL) {
       for (ll = list; ll->next != NULL; ll = ll->next);
       ll->next = l;
       ll = list;
    } else {
       ll = l;
    }

    return ll;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void lang_list_free ( LangList list) [static]

Definition at line 85 of file letools.cpp.

{
    LangList *last;

    while (list) {
       last = list;
       list = list->next;
       if (last->language)
           free(last->language);
       free(last);
    }
}

Here is the caller graph for this function:

static LangList* lang_list_new ( const char *  lang) [static]

Definition at line 56 of file letools.cpp.

{
    LangList *l;

    l = (LangList *)malloc(sizeof (LangList) * 1);
    l->language = strdup(lang);
    l->next = NULL;

    return l;
}

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 385 of file letools.cpp.

{
    char *conffile = NULL;
    Action *act;
    IIIMLEXMLConf *conf = NULL;
    struct stat s;
    int notfoundconf = 0, i, need_store = 0;
    LangList *ll;
    IIIMLEInfoList *modlist, *m;
    IIIMLELanguageList *langlist, *lelang;
    HotKeyList *hlist;

    if (argc < 2) {
       usage(argv[0]);
       exit(1);
    }
    act = parse_arg(argc, argv);
    if (act->globalmode) {
       conffile = strdup(XMLCONFDIR "/le.xml.conf");
    } else {
       struct passwd *pass;
       size_t len;
       uid_t uid;

       uid = getuid();
       pass = getpwuid(uid);
       len = strlen(pass->pw_dir);
       conffile = (char *)malloc(sizeof (char) * (len + 19));
       sprintf(conffile, "%s/.iiim/le.xml.conf", pass->pw_dir);
       endpwent();
    }
    conf = iiim_le_xmlconf_new(conffile);
    if (act->verbose) {
       iiim_log_debug_mode();
    }
    if (stat(conffile, &s) >= 0) {
       /* if conffile exists, parse it */
       if (act->verbose)
           fprintf(stderr, "Loading %s...", conffile);
       iiim_le_xmlconf_load_file(conf);
    } else {
       notfoundconf = 1;
    }
    switch (act->type) {
       case ACT_MODLIST:
           langlist = iiim_le_xmlconf_get_lang_list(conf);
           for (lelang = langlist; lelang != NULL; lelang = lelang->next) {
              printf("Language: %s\n", lelang->language);
              modlist = iiim_le_xmlconf_get_le_info_list(conf, lelang->language);
              for (m = modlist, i = 1; m != NULL; m = m->next, i++) {
                  IIIMLEInfo *info = m->data;

                  printf(" %d. %s\n", i, info->lename);
              }
           }
           break;
       case ACT_APPENDMOD:
           need_store = 1;
           read_supported_lang(act, act->filename);
           for (ll = act->langlist; ll != NULL; ll = ll->next) {
              if (act->clearhotkey)
                  iiim_le_xmlconf_clear_hotkey(conf, ll->language);
              iiim_le_xmlconf_append_module(conf, act->filename, ll->language);
              for (hlist = act->removehotkey; hlist != NULL; hlist = hlist->next) {
                  iiim_le_xmlconf_remove_hotkey(conf, hlist->hotkey, ll->language);
              }
              for (hlist = act->addhotkey; hlist != NULL; hlist = hlist->next) {
                  iiim_le_xmlconf_append_hotkey(conf, hlist->hotkey, ll->language);
              }
           }
           break;
       case ACT_PREPENDMOD:
           need_store = 1;
           read_supported_lang(act, act->filename);
           for (ll = act->langlist; ll != NULL; ll = ll->next) {
              if (act->clearhotkey)
                  iiim_le_xmlconf_clear_hotkey(conf, ll->language);
              iiim_le_xmlconf_prepend_module(conf, act->filename, ll->language);
              for (hlist = act->removehotkey; hlist != NULL; hlist = hlist->next) {
                  iiim_le_xmlconf_remove_hotkey(conf, hlist->hotkey, ll->language);
              }
              for (hlist = act->addhotkey; hlist != NULL; hlist = hlist->next) {
                  iiim_le_xmlconf_append_hotkey(conf, hlist->hotkey, ll->language);
              }
           }
           break;
       case ACT_REMOVEMOD:
           need_store = 1;
           read_supported_lang(act, act->filename);
           for (ll = act->langlist; ll != NULL; ll = ll->next) {
              iiim_le_xmlconf_remove_module(conf, act->filename, ll->language);
              if (iiim_le_xmlconf_get_le_info_list(conf, ll->language) == NULL)
                  iiim_le_xmlconf_clear_hotkey(conf, ll->language);
           }
           break;
       default:
           if (act->langlist != NULL &&
              (act->addhotkey != NULL || act->removehotkey != NULL)) {
              /* Add/Remove the hotkey only */
              need_store = 1;
              for (ll = act->langlist; ll != NULL; ll = ll->next) {
                  for (hlist = act->removehotkey; hlist != NULL; hlist = hlist->next) {
                     iiim_le_xmlconf_remove_hotkey(conf, hlist->hotkey, ll->language);
                  }
                  for (hlist = act->addhotkey; hlist != NULL; hlist = hlist->next) {
                     iiim_le_xmlconf_append_hotkey(conf, hlist->hotkey, ll->language);
                  }
              }
           } else if (act->langlist != NULL && act->clearhotkey) {
              need_store = 1;
              for (ll = act->langlist; ll != NULL; ll = ll->next) {
                  /* clean up the hotkey only */
                  iiim_le_xmlconf_clear_hotkey(conf, ll->language);
              }
           } else {
              fprintf(stderr, "unkown action: %d\n", act->type);
              exit(1);
           }
    }
    if (need_store) {
       if (iiim_le_xmlconf_is_empty_module(conf) &&
           iiim_le_xmlconf_is_empty_hotkey(conf)) {
           if (!notfoundconf) {
              /* remove empty conf file. */
              if (unlink(conffile) == -1) {
                  fprintf(stderr, "Cannot remove `%s' :%s\n", conffile, strerror(errno));
                  exit(1);
              }
           }
       } else {
           if (act->verbose)
              fprintf(stderr, "Storing %s...", conffile);
           iiim_le_xmlconf_save_file(conf);
           if (act->verbose)
              fprintf(stderr, "done\n");
       }
    }
    if (conffile)
       free(conffile);
    if (act->filename)
       free(act->filename);
    if (act->langlist)
       lang_list_free(act->langlist);
    if (act->removehotkey)
       iiim_le_hotkey_list_free(act->removehotkey);
    if (act)
       free(act);
    if (conf)
       iiim_le_xmlconf_free(conf);

    return 0;
}

Here is the call graph for this function:

static Action* parse_arg ( int  argc,
char **  argv 
) [static]

Definition at line 283 of file letools.cpp.

{
    Action *act = (Action *)malloc(sizeof (Action) * 1);
    ActionType cur = ACT_NONE, next = ACT_NONE;
    int defaultflag = 0;
    int i;
    HotKeyStruct *hstruct;

    act->type = ACT_NONE;
    act->filename = NULL;
    act->verbose = 0;
    act->globalmode = 0;
    act->langlist = NULL;
    act->clearhotkey = 0;
    act->addhotkey = NULL;
    act->removehotkey = NULL;
    for (i = 1; i < argc; i++) {
       if (next == ACT_ARG && strncmp(argv[i], "-", 1) == 0) {
           fprintf(stderr, "missing argument\n");
           exit(1);
       }
       if (strcmp(argv[i], "--install") == 0) {
           cur = ACT_INSTALL;
           next = ACT_ARG;
       } else if (strcmp(argv[i], "--remove") == 0) {
           cur = ACT_REMOVE;
           next = ACT_ARG;
       } else if (strcmp(argv[i], "--lang") == 0) {
           cur = ACT_LANG;
           next = ACT_ARG;
       } else if (strcmp(argv[i], "--default") == 0) {
           cur = ACT_DEFAULT;
           next = ACT_NONE;
           defaultflag = 1;
           if (act->type == ACT_APPENDMOD)
              act->type = ACT_PREPENDMOD;
       } else if (strcmp(argv[i], "--clear-hotkey") == 0) {
           act->clearhotkey = 1;
           next = ACT_NONE;
       } else if (strcmp(argv[i], "--list") == 0) {
           act->type = ACT_MODLIST;
           next = ACT_NONE;
       } else if (strcmp(argv[i], "--add-hotkey") == 0) {
           cur = ACT_ADDKEY;
           next = ACT_ARG;
       } else if (strcmp(argv[i], "--remove-hotkey") == 0) {
           cur = ACT_DELKEY;
           next = ACT_ARG;
       } else if (strcmp(argv[i], "--help") == 0) {
           usage(argv[0]);
           exit(1);
       } else if (strcmp(argv[i], "-v") == 0) {
           act->verbose = 1;
           next = ACT_NONE;
       } else if (strcmp(argv[i], "-g") == 0) {
           act->globalmode = 1;
           next = ACT_NONE;
       } else if (strncmp(argv[i], "-", 1) == 0) {
           fprintf(stderr, "unknown option `%s'\n", argv[i]);
           exit(1);
       } else {
           switch (cur) {
              case ACT_INSTALL:
                  if (defaultflag)
                     act->type = ACT_PREPENDMOD;
                  else
                     act->type = ACT_APPENDMOD;
                  if (act->filename)
                     free(act->filename);
                  act->filename = strdup(argv[i]);
                  break;
              case ACT_REMOVE:
                  act->type = ACT_REMOVEMOD;
                  if (act->filename)
                     free(act->filename);
                  act->filename = strdup(argv[i]);
                  break;
              case ACT_LANG:
                  act->langlist = lang_list_add(act->langlist, argv[i]);
                  break;
              case ACT_ADDKEY:
                  hstruct = parse_hotkey(argv[i]);
                  if (hstruct != NULL)
                     act->addhotkey = iiim_le_hotkey_list_add(act->addhotkey, hstruct);
                  break;
              case ACT_DELKEY:
                  hstruct = parse_hotkey(argv[i]);
                  if (hstruct != NULL)
                     act->removehotkey = iiim_le_hotkey_list_add(act->removehotkey, hstruct);
                  break;
              default:
                  fprintf(stderr, "unknown parameter `%s'\n", argv[i]);
                  exit(1);
           }
           next = ACT_NONE;
       }
    }

    return act;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static HotKeyStruct* parse_hotkey ( char *  keys) [static]

Definition at line 179 of file letools.cpp.

{
    HotKeyStruct *hstruct = NULL;
    size_t len = strlen(keys);
    long i, j, l, mask = 0;
    char *mod, *key = NULL, *tmp;
    const char *p;
    static struct {
       const char *symbol;
       int mask;
    } modifiers[] = {
       {"shift", 1},
       {"control", 2},
       {"meta", 4},
       {"alt", 8},
       {"altgr", 16},
       {NULL, 0},
    };

    for (i = 0; i < len; i++) {
       if (keys[i] == '<') {
           tmp = strchr(&keys[i+1], '>');
           if (tmp != NULL) {
              p = &keys[i+1];
              l = tmp - p;
              mod = strndup(p, l);
              for (j = 0; modifiers[j].symbol != NULL; j++) {
                  if (!strcasecmp(modifiers[j].symbol, mod)) {
                     mask |= modifiers[j].mask;
                     p = NULL;
                     i += (l + 1);
                     break;
                  }
              }
              if (p != NULL)
                  fprintf(stderr, "Unknown modifier symbol: %s\n", mod);
              if (mod)
                  free(mod);
           }
       } else {
           if (key != NULL) {
              fprintf(stderr, "Specified a key twice. ignoring previous key %s...\n", key);
              free(key);
           }
           tmp = strchr(&keys[i], '<');
           if (tmp != NULL) {
              p = &keys[i];
              key = strndup(p, tmp - p);
              i += (tmp - p - 1);
           } else {
              key = strdup(&keys[i]);
              i = len;
           }
       }
    }
    if (key != NULL) {
       char buffer[1024];
       size_t n = 1024, pos = 0;
       int i, found = 0;

       for (i = 0; keysymtable[i].keyname != NULL; i++) {
           if (!strcasecmp(key, keysymtable[i].keyname)) {
              found = 1;
              break;
           }
       }
       if (found == 0) {
           fprintf(stderr, "Unknown key: %s\n", key);
           free(key);

           return NULL;
       }
       buffer[0] = 0;
       for (i = 0; mask != 0; i++) {
           if ((mask & modifiers[i].mask) != 0) {
              size_t len = strlen(modifiers[i].symbol);

              n -= len;
              if (n > 0) {
                  if (pos > 0)
                     strcat(buffer, " ");
                  strcat(buffer, modifiers[i].symbol);
                  pos += len;
              } else {
                  fprintf(stderr, "Buffer overflow.\n");
                  free(key);

                  return NULL;
              }
              mask ^= modifiers[i].mask;
           }
       }
       hstruct = iiim_le_hotkey_struct_new(key, buffer);
       free(key);
    } else {
       fprintf(stderr, "No key specified.");

       return NULL;
    }

    return hstruct;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void read_supported_lang ( Action *  act,
const char *  modname 
) [static]

Definition at line 99 of file letools.cpp.

{
    if (act->langlist == NULL) {
       /* need to get lang info from module */
       void *h = NULL;
       void (*f)(IMArgList, int);
       IMArgList a;
       IMLocale *l;

       if ((h = dlopen(act->filename, RTLD_LAZY)) == NULL) {
           fprintf(stderr, "Cannot open `%s'\n", act->filename);
           exit(1);
       }
       if ((f = (void (*) (IMArgList, int)) dlsym(h, "if_GetIfInfo")) == NULL) {
           fprintf(stderr, "`%s' is not valid module.\n", act->filename);
           exit(1);
       }
       a = (IMArg *)malloc(sizeof (IMArg) * 2);
       a->id = 4;
       f(a, 1);
       for (l = (IMLocale *)a->value; l->id != NULL; l++) {
           act->langlist = lang_list_add(act->langlist, l->id);
       }
       free(a);
       dlclose(h);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* strndup ( const char *  s,
size_t  n 
) [static]

Definition at line 155 of file letools.cpp.

{
    size_t slen;
    char *dst;
    size_t copied = 0;

    if (s != NULL) {
       slen = strlen(s);
       if (slen >= n)
           copied = n;
       else
           copied = slen;
    }

    dst = (char*)malloc (copied + 1);
    if (dst == NULL)
       return NULL;

    dst[copied] = '\0';
    return (char *) memcpy (dst, s, copied);
}

Here is the caller graph for this function:

void usage ( const char *  name)

Definition at line 129 of file letools.cpp.

{
    fprintf(stderr,
           "Usage: %s [-v][-g][--default][--lang LANG][--add-hotkey KEY][--remove-hotkey KEY]<--install MODULE|--remove MODULE>\n"
           "Options:\n"
           "  -v                   display more information\n"
           "  -g                   work for the global configuration\n"
           "  --default            register MODULE as default.\n"
           "                must use --install together\n"
           "  --lang LANG          specify LANG for the action.\n"
           "  --add-hotkey KEY     add the hotkey for LANG\n"
           "                e.g. --add-hotkey '<Shift>space'\n"
           "  --remove-hotkey KEY  remove the hotkey for LANG\n"
           "  --clear-hotkey       clean up the hotkey configuration\n"
           "                must use --install or --lang together\n"
           "\n"
           "Actions:\n"
           "  --install MODULE     install MODULE to the configuration file\n"
           "  --remove MODULE      remove MODULE from the configuration file\n"
           "  --list        shows the available LEs\n"
           "                must use --lang together.\n"
           , name);
}

Here is the caller graph for this function: