Back to index

im-sdk  12.3.91
Functions
guiIMSts.c File Reference
#include "xiiimp.h"
#include "iiimpIM.h"
#include "iiimpColor.h"
#include "guiIMSts.h"
#include "XimpIm.h"
#include "xfactory.h"
#include <X11/Xatom.h>

Go to the source code of this file.

Functions

static void UpdateStatus (XicCommon ic, Bool)
char * MergeStatus (XicCommon ic)
static Bool MapStatusWindow (XicCommon ic, Window win)
static void DrawStatusString (XicCommon ic, Display *display, Window win, XFontSet fontset, GC gc, int x, int y, char *str, int str_len, IMFeedbackList *feedback_list, int feedback_length)
static Bool RepaintStatus (Display *d, Window w, XEvent *ev, XPointer client_data)
Bool SetupStatusExt (XicCommon ic)
static void CreateGC (XicCommon ic)
Bool SetupStatusWindow (XicCommon ic, Window parent)
void SetStatusForeground (XicCommon ic, XPointer call_data)
void SetStatusBackground (XicCommon ic, XPointer call_data)
void SetStatusFont (XicCommon ic, XPointer call_data)
void StatusStart (XicCommon ic, XPointer call_data)
void StatusDrawText (XicCommon ic, XPointer call_data)
void StatusDone (XicCommon ic, XPointer call_data)
void DestroyStatus (XicCommon ic, XPointer call_data)

Function Documentation

static void CreateGC ( XicCommon  ic) [static]

Definition at line 182 of file guiIMSts.c.

                       {
  StatusWin status = (StatusWin)(ic->gui_icpart->status);
  unsigned long fg, bg;
  XWindowAttributes attr;
  unsigned long val_mask;
  XGCValues gcval;
  Display *display = ic->core.im->core.display;

  if (!XIMP_CHK_STSBGMASK(ic) || !XIMP_CHK_STSFGMASK(ic)) 
    XGetWindowAttributes(display, 
                      ic->core.client_window,
                      &attr);

  if (XIMP_CHK_STSBGMASK(ic)) 
    bg = ic->core.status_attr.background;
  else if (XIMP_CHK_PREBGMASK(ic))
    bg = ic->core.preedit_attr.background;
  else
    bg = WhitePixel(display, XScreenNumberOfScreen(attr.screen));

  if (XIMP_CHK_STSFGMASK(ic))
    fg = ic->core.status_attr.foreground;
  else if (XIMP_CHK_PREFGMASK(ic))
    /* Motif does not set ic value for white status foreground color,
       so this is workaround. (#4290814)
    */
    fg = ic->core.preedit_attr.foreground;
  else
    fg = BlackPixel(display, XScreenNumberOfScreen(attr.screen));

  val_mask = GCForeground | GCBackground;
  gcval.foreground = fg;
  gcval.background = bg;
  status->gc = XCreateGC(display, status->window, val_mask, &gcval);
#ifdef USE_STATUS_FEEDBACK
  gcval.foreground = bg;
  gcval.background = fg;
  status->rgc = XCreateGC(display, win, val_mask, &gcval);
#endif
  return;
}

Here is the caller graph for this function:

void DestroyStatus ( XicCommon  ic,
XPointer  call_data 
)

Definition at line 600 of file guiIMSts.c.

                                                {
  StatusWin status = (StatusWin)(ic->gui_icpart->status);

  if (!status) return;

  if (status->fontset && status->need_free_fontset) {
    XFactoryFreeDefaultFontSet (ic->core.im->core.display);
    status->need_free_fontset = False;
  }
  _XUnregisterFilter(ic->core.im->core.display, status->window,
                   RepaintStatus, (XPointer)ic);
#if defined(USE_FILTER_KEY_PRESS_IN_STATUS)
  _XUnregisterFilter(ic->core.im->core.display, status->window,
                   FilterKeyPress, (XPointer)ic);
#endif /* USE_FILTER_KEY_PRESS_IN_STATUS */
  if (status->window) {
    if (IMCheckIMWindow(ic, status->window)) {
      XDestroyWindow(ic->core.im->core.display, status->window);
    }
    status->window = 0;
  }

  if (status->gc) XFreeGC(ic->core.im->core.display, status->gc);
#ifdef USE_STATUS_FEEDBACK
  if (status->rgc) XFreeGC(ic->core.im->core.display, status->rgc);
#endif
  if (status->text.string.multi_byte) {
    Xfree(status->text.string.multi_byte);
  }
  FreeFeedbackList(status->feedback, status->text.length);
  status->feedback = NULL;
  
  Xfree(status->status_string);
  Xfree(status);
  ic->gui_icpart->status = (StatusWin)NULL;
  return;
}

Here is the call graph for this function:

static void DrawStatusString ( XicCommon  ic,
Display *  display,
Window  win,
XFontSet  fontset,
GC  gc,
int  x,
int  y,
char *  str,
int  str_len,
IMFeedbackList feedback_list,
int  feedback_length 
) [static]

Definition at line 97 of file guiIMSts.c.

                                                                   {
  if (fontset == NULL) return;
  if (feedback_list) {
    /* coloring */
    int i;
    wchar_t *wcstr = 0, *wcstrp = NULL;
    size_t wc_len = 0;
    IMFeedbackList *pfeedback;
    XimCommon im = (XimCommon)ic->core.im;

    /* need to get wchar string */
    wc_len = str_len;
    if (!(wcstr = Xmalloc(sizeof(wchar_t) * (wc_len + 1)))) return;

    if (IIimpMbstoWcs(im, str, str_len, wcstr, wc_len, NULL) == 0) {
      Xfree(wcstr);
      goto error;
    }
    wcstrp = wcstr;

    pfeedback = feedback_list;
    for (i = 0; i < feedback_length; i++, pfeedback++) {
      /* set colors */
      SetIMColors(ic, display, win, gc, (GC)0, pfeedback, (XIMFeedback)0);
      XwcDrawImageString(display, win, fontset, gc,
                      x, y, wcstrp, 1);
      x += XwcTextEscapement(fontset, wcstrp, 1); wcstrp++;
    }
    Xfree(wcstr);
    return;
  }
 error:
  XmbDrawString(display, win, fontset, gc, x, y, str, str_len);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Bool MapStatusWindow ( XicCommon  ic,
Window  win 
) [static]

Definition at line 54 of file guiIMSts.c.

                                          {
  Display *display = ic->core.im->core.display;
  XWindowAttributes win_att;
  XWindowAttributes cwin_att;

  if (!XGetWindowAttributes(display, 
                         ic->core.client_window,
                         &cwin_att)) {
    /* xemacs causes BadWindow of X_UnmapWindow on TL4.2 */
#ifdef linux
    if(IMCheckIMWindow(ic, win))
#endif
    /* client window is not ready, so unmap status */
    XUnmapWindow(display, win);
    return False;
  } else {

    if (!IsIMStatusAttached ())
      {
       XUnmapWindow(display, win);
       return True;
      }

    if (cwin_att.map_state == IsUnmapped) {
      if (ic->core.input_style & XIMStatusNothing) {
       return False;
      } else {
       XMapWindow(display, win);
       return True;
      }
    }
  }
  if (XGetWindowAttributes(display, win,
                        &win_att) > 0) {
    if (win_att.map_state == IsUnmapped) {
      XMapWindow(display, win);
    }
    return True;    
  }
  return False;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char * MergeStatus ( XicCommon  ic)

Definition at line 639 of file guiIMSts.c.

                          {
  StatusWin status = (StatusWin)(ic->gui_icpart->status);
  int len = 0;
  char *status_string;

  if (!status) return 0;
  len = 0;
  if (NULL != status) {
    if (NULL != status->text.string.multi_byte) {
      len = strlen(status->text.string.multi_byte);
    }
  }
  if (len <= 0) {
    return NULL;
  }

  status_string = (char *)Xmalloc(len + 1);
  if (NULL == status_string) return NULL;
  if (NULL != status->text.string.multi_byte) {
    memcpy(status_string, status->text.string.multi_byte, len);
  }
  *(status_string + len) = '\0';
  return status_string;
}

Here is the caller graph for this function:

static Bool RepaintStatus ( Display *  d,
Window  w,
XEvent *  ev,
XPointer  client_data 
) [static]

Definition at line 151 of file guiIMSts.c.

                                                                      {
  XicCommon ic = (XicCommon)client_data;
  StatusWin status;

  if (!ic->gui_icpart) return True;

  status = (StatusWin)(ic->gui_icpart->status);

  if (!status) return True;

  UpdateStatus(ic, False);

  return True;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void SetStatusBackground ( XicCommon  ic,
XPointer  call_data 
)

Definition at line 442 of file guiIMSts.c.

                                                      { 
  StatusWin status = (StatusWin)(ic->gui_icpart->status);
  CacheRec *status_cache;

  if (!status) return;  /* Let's do it later */

  status_cache = (CacheRec*)&(status->status_cache);

  if (status_cache->background == ic->core.status_attr.background) {
    return;
  }
  if (status->gc) {
    XGCValues val;
    unsigned long mask;
    val.background = ic->core.status_attr.background;
    mask = GCBackground;
    XChangeGC(ic->core.im->core.display,
             status->gc,
             mask,
             &val);
  }
#ifdef USE_STATUS_FEEDBACK
  if (status->rgc) {
    XGCValues val;
    unsigned long mask;
    val.foreground = ic->core.status_attr.background;
    mask = GCForeground;
    XChangeGC(ic->core.im->core.display,
             status->rgc,
             mask,
             &val);
  }
#endif
  status_cache->background = ic->core.status_attr.background;

  if (status->window) {
    XSetWindowBackground(ic->core.im->core.display, status->window,
                      ic->core.status_attr.background);
  }
  return;
}
void SetStatusFont ( XicCommon  ic,
XPointer  call_data 
)

Definition at line 485 of file guiIMSts.c.

                                                {
  StatusWin status = (StatusWin)(ic->gui_icpart->status);

  if (!status) return;  /* Let's do it later */

  if (ic->core.status_attr.fontset) {
    if (status->fontset && status->need_free_fontset) {
      XFactoryFreeDefaultFontSet (ic->core.im->core.display);
      status->need_free_fontset = False;
    }
    /* need to clear status cache */
    status->fontset = ic->core.status_attr.fontset;
    status->len = 0;
    status->status_string = NULL;
  } else if (status->fontset == NULL) {
    status->fontset = XFactoryCreateDefaultFontSet(ic->core.im->core.display,
                                             XIM_IIIMP (ic->core.im, default_font_name));
    status->need_free_fontset = True;
  }
  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void SetStatusForeground ( XicCommon  ic,
XPointer  call_data 
)

Definition at line 404 of file guiIMSts.c.

                                                      {
  StatusWin status = (StatusWin)(ic->gui_icpart->status);
  CacheRec *status_cache;

  if (!status) return;  /* Let's do it later */

  status_cache = (CacheRec*)&(status->status_cache);

  if (status_cache->foreground == ic->core.status_attr.foreground) {
    return;
  }
  if (status->gc) {
    XGCValues val;
    unsigned long mask;
    val.foreground = ic->core.status_attr.foreground;
    mask = GCForeground;
    XChangeGC(ic->core.im->core.display,
             status->gc,
             mask,
             &val);
  }
#ifdef USE_STATUS_FEEDBACK
  if (status->rgc) {
    XGCValues val;
    unsigned long mask;
    val.background = ic->core.status_attr.foreground;
    mask = GCBackground;
    XChangeGC(ic->core.im->core.display,
             status->rgc,
             mask,
             &val);
  }
#endif
  status_cache->foreground = ic->core.status_attr.foreground;
  return;
}

Definition at line 167 of file guiIMSts.c.

                             {
  StatusWin status = (StatusWin)Xmalloc(sizeof(StatusWinRec));

  if (!status) return True;
  memset((char *)status, 0, sizeof(StatusWinRec));

  memset(&status->status_cache, 0, sizeof(CacheRec));

  status->need_free_fontset = False;

  ic->gui_icpart->status = (void *)status;
  return True;
}

Here is the caller graph for this function:

Bool SetupStatusWindow ( XicCommon  ic,
Window  parent 
)

Definition at line 273 of file guiIMSts.c.

                                               {
  Window win;
  StatusWin status = (StatusWin)(ic->gui_icpart->status);
  int x, y;
  unsigned int width, height;
  unsigned long fg, bg;
  XWindowAttributes attr;
  Display *display = ic->core.im->core.display;
  XIMFilterRec filters[4];
  int n;
  unsigned int event_mask;
  extern Bool popup_button_press(Display *d, Window w, XEvent *ev,
                             XPointer client_data);

  if (XIMP_CHK_STSAREAMASK(ic)) {
    x = ic->core.status_attr.area.x;
    y = ic->core.status_attr.area.y;
    width   = ic->core.status_attr.area.width;
    height  = ic->core.status_attr.area.height;
  } else {
    x  = y = 0;
    width = height = 1;
  }
  if (width == 0 || height == 0) return False;

  if (!XIMP_CHK_STSBGMASK(ic) || !XIMP_CHK_STSFGMASK(ic)) 
    XGetWindowAttributes(display, 
                      ic->core.client_window,
                      &attr);

  if (XIMP_CHK_STSBGMASK(ic)) 
    bg = ic->core.status_attr.background;
  else if (XIMP_CHK_PREBGMASK(ic))
    bg = ic->core.preedit_attr.background;
  else
    bg = WhitePixel(display, XScreenNumberOfScreen(attr.screen));

  if (XIMP_CHK_STSFGMASK(ic))
    fg = ic->core.status_attr.foreground;
  else if (XIMP_CHK_PREFGMASK(ic))
    /* Motif does not set ic value for white status foreground color,
       so this is workaround. (#4290814)
    */
    fg = ic->core.preedit_attr.foreground;
  else
    fg = BlackPixel(display, XScreenNumberOfScreen(attr.screen));

  /* A new parent window is the same as the previous, nothing to do. */
  if (parent == 0 || status->parent == parent) return False;

  status->parent = parent;

  event_mask = None;

  n = 0;
#if defined(USE_FILTER_KEY_PRESS_IN_STATUS)
  filters[n].type = KeyPress;
  filters[n].filter = FilterKeyPress;
  filters[n].client_data = (XPointer)ic;
  n++;
  event_mask |= KeyPressMask;
#endif /* USE_FILTER_KEY_PRESS_IN_STATUS */
  filters[n].type = Expose;
  filters[n].filter = RepaintStatus;
  filters[n].client_data = (XPointer)ic;
  n++;
  event_mask |= ExposureMask;

  if (XIM_IS_SWITCH(ic->core.im) || XIM_IS_COMPOSE(ic->core.im)) {
    filters[n].type = ButtonPress;
    filters[n].filter = popup_button_press;
    filters[n].client_data = (XPointer)(ic);
    n++;
    event_mask |= ButtonPressMask;
    filters[n].type = ButtonRelease;
    filters[n].filter = popup_button_press;
    filters[n].client_data = (XPointer)(ic);
    n++;
    event_mask |= ButtonReleaseMask;
    event_mask |= PointerMotionMask;
  }
  if (!status->window) {
    XClassHint class_hint;
    win = XFactoryCreateIMWindow(display, parent, ic->core.client_window,
                             x, y, width, height, bg,
                             event_mask,
                             filters, n);

    if (!win) return False;

    /* remove all of the window decoration */
    XFactoryRemoveAllDecoration(display, win);

    if (ic->core.input_style & XIMStatusArea) {
      /* set override-redirect to true */
      XSetWindowAttributes attributes;
      int cmask = 0;
      cmask |= CWOverrideRedirect;
      attributes.override_redirect = True;
      XChangeWindowAttributes(ic->core.im->core.display, win,
                           cmask, &attributes);
    }

    XStoreName(display, win, "iiimx IM Status");

    class_hint.res_name = "iiimx-im-status";
    class_hint.res_class = "IiimxImStatus";
    XSetClassHint(display, win, &class_hint);

    status->window = win;
  }
#if 0
 {
   unsigned long val_mask;
   XGCValues gcval;
   val_mask = GCForeground | GCBackground;
   gcval.foreground = fg;
   gcval.background = bg;
   status->gc = XCreateGC(display, win, val_mask, &gcval);
 }
#ifdef USE_STATUS_FEEDBACK
  gcval.foreground = bg;
  gcval.background = fg;
  status->rgc = XCreateGC(display, win, val_mask, &gcval);
#endif
#endif

  return True;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void StatusDone ( XicCommon  ic,
XPointer  call_data 
)

Definition at line 594 of file guiIMSts.c.

                                             {
  /* do nothing */
  
}
void StatusDrawText ( XicCommon  ic,
XPointer  call_data 
)

Definition at line 513 of file guiIMSts.c.

                                                 {
  StatusWin status = (StatusWin)(ic->gui_icpart->status);
  XIMDrawTextStruct *status_draw = (XIMDrawTextStruct*)call_data;
  XIMText *text = (XIMText*)status_draw->call_data;
  IMFeedbackList *feedback_list = status_draw->feedback_list;

  if (text == (XIMText*)NULL || text->length == 0 ||
      text->string.multi_byte == NULL) {
    /* unmap the status window if no valid status */
    Display *display = ic->core.im->core.display;

    if (status->window)
      XUnmapWindow(display, status->window);

    return;
  }

  if (!status) {
    XIC_GUI(ic, change_status)((XIC)ic, STATUS_CREATE, NULL);
    status = (StatusWin)(ic->gui_icpart->status);
    if (!status) return;
  }
  if (status->text.string.multi_byte) {
    Xfree(status->text.string.multi_byte);
  }

  if (feedback_list) {
    /* copy feedback_list */
    if (status->feedback) {
      IMFeedbackList *p;
      for (p = status->feedback; p < &status->feedback[status->text.length]; p++) {
       if (p->feedbacks) Xfree(p->feedbacks);
      }
      Xfree(status->feedback);
      status->feedback = 0;
    }
    status->feedback = Xmalloc(sizeof(IMFeedbackList) * text->length);
    if (status->feedback) {
      IMFeedbackList *from, *to;
      for (to = status->feedback, from = feedback_list;
          to < &status->feedback[text->length];
          to++, from++) {
       to->count_feedbacks = from->count_feedbacks;
       to->feedbacks = Xmalloc(sizeof(IMFeedback) * to->count_feedbacks);
       if (to->feedbacks) {
         IMFeedback *p, *q;
         for (p = to->feedbacks, q = from->feedbacks;
              p < &to->feedbacks[to->count_feedbacks];
              p++, q++) {
           p->type = q->type;
           p->value = q->value;
         }
       } else {
         /* error */
         Xfree(status->feedback);
         return;
       }
      }
    } else {
      /* error */
      return;
    }
  } else {
    if (NULL != status->feedback) {
      FreeFeedbackList(status->feedback, status->text.length);
      status->feedback = NULL;
    }
  }
  memmove(&(status->text), text, sizeof(XIMText));
  if (text->string.multi_byte == NULL) {
    status->text.string.multi_byte = NULL;
  } else {
    status->text.string.multi_byte = (char*)strdup(text->string.multi_byte);
  }
  XIC_GUI(ic, change_status)((XIC)ic, STATUS_WIN, NULL);

  UpdateStatus(ic, True);
  return;
}

Here is the call graph for this function:

void StatusStart ( XicCommon  ic,
XPointer  call_data 
)

Definition at line 508 of file guiIMSts.c.

                                              {
  return;
}
void UpdateStatus ( XicCommon  ic,
Bool  doCache 
) [static]

Definition at line 225 of file guiIMSts.c.

                                         {
  StatusWin status = (StatusWin)(ic->gui_icpart->status);
  int len;
  char * status_string;
  status_string = MergeStatus(ic);
  if (NULL == status_string) return;
  len = strlen(status_string);
  if (!status->window) {
    if (!SetupStatusWindow(ic, ic->core.client_window)) return;
  }

  if (!status->fontset)
    SetStatusFont(ic, NULL);
  if (!status->fontset)
    return;
  if (!MapStatusWindow(ic, status->window))
    return;

  if (doCache &&
      len == status->len &&
      !strcmp(status_string, status->status_string)) {
    /* same string as the previous, skipped */
    Xfree(status_string);
    return;
  }

  XClearArea(ic->core.im->core.display, status->window, 0, 0, 0, 0, False);

  if (!status->gc) {
    CreateGC(ic);
    if (!status->gc) return;
  }
  DrawStatusString(ic, ic->core.im->core.display,
                 status->window,
                 status->fontset,
                 status->gc, status->x, status->y,
                 status_string, len,
                 status->feedback, status->text.length);

  /* status cache */
  status->len = len;

  Xfree(status->status_string);
  status->status_string = status_string;
  return;
}

Here is the call graph for this function:

Here is the caller graph for this function: