Back to index

im-sdk  12.3.91
Functions
guiIMPre.c File Reference
#include "xiiimp.h"
#include "iiimpIM.h"
#include "iiimpColor.h"
#include "guiIMPre.h"
#include "XimpIm.h"
#include "xfactory.h"
#include "trace_message.h"

Go to the source code of this file.

Functions

static void UpdatePreedit (XicCommon, int, int)
static void DrawPreeditString (XicCommon ic, Display *display, Window win, XFontSet fontset, GC gc, GC rgc, int x, int y, XIMFeedback *feedback, IMFeedbackList *feedback_list, wchar_t *wstr, int offset, int len)
Bool FilterConfigureNotify (Display *d, Window w, XEvent *ev, XPointer client_data)
static Bool FilterKeyPress (Display *d, Window w, XEvent *ev, XPointer client_data)
static Bool RepaintPreedit (Display *d, Window w, XEvent *ev, XPointer client_data)
static void UpdatePreeditAll (XicCommon ic)
static void preedit_window_fg_and_bg (XicCommon ic, unsigned long *fg, unsigned long *bg)
static void create_preedit_gc (Display *display, Window win, PreeditWin preedit, unsigned long fg, unsigned long bg)
void UnmapPreeditWindow (XicCommon ic, PreeditArea preedit_area)
Bool SetupPreeditExt (XicCommon ic)
Bool NewPreeditWindow (XicCommon ic)
Bool SetupPreeditWindow (XicCommon ic, Window parent)
void SetPreeditForeground (XicCommon ic, XPointer call_data)
void SetPreeditBackground (XicCommon ic, XPointer call_data)
static void UpdatePreeditWidth (XicCommon ic)
void SetPreeditFont (XicCommon ic, XPointer call_data)
static void PreeditReplaceString (XicCommon ic, PreeditWin preedit, int *change_first, int *change_length, XIMText *text, IMFeedbackList *feedback_list)
static void PreeditCursor (PreeditChars preedit_chars, int caret)
void PreeditStart (XicCommon ic, XPointer call_data)
void PreeditDrawText (XicCommon ic, XPointer p)
void PreeditCaret (XicCommon ic, XPointer call_data)
void PreeditDone (XicCommon ic, XPointer call_data)
void DestroyPreedit (XicCommon ic, XPointer call_data)
void PreeditCaretAdjustLookupPlacement (XicCommon ic, XPoint *point)
void PreeditCaretPlacement (XicCommon ic, XPoint *point)
void PreeditCaretPlacementRelative (XicCommon ic, XPoint *point)

Function Documentation

static void create_preedit_gc ( Display *  display,
Window  win,
PreeditWin  preedit,
unsigned long  fg,
unsigned long  bg 
) [static]

Definition at line 251 of file guiIMPre.c.

                                                    {
  unsigned long val_mask;
  XGCValues gcval;

  val_mask = GCForeground | GCBackground;
  gcval.foreground = fg;
  gcval.background = bg;
  preedit->gc = XCreateGC(display, win, val_mask, &gcval);
  gcval.foreground = bg;
  gcval.background = fg;
  preedit->rgc = XCreateGC(display, win, val_mask, &gcval);
}

Here is the caller graph for this function:

void DestroyPreedit ( XicCommon  ic,
XPointer  call_data 
)

Definition at line 1454 of file guiIMPre.c.

                                                 {
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);
  int i;
  PreeditArea preedit_area;

  if (!preedit) return;

  if (preedit->fontset && preedit->need_free_fontset) {
    XFactoryFreeDefaultFontSet (ic->core.im->core.display);
    preedit->need_free_fontset = False;
  }
#if 0
  PreeditDone(ic, NULL);
#else
  _XUnregisterFilter(ic->core.im->core.display, ic->core.focus_window,
                   FilterConfigureNotify, (XPointer)ic);
#endif

  preedit_area = (PreeditArea)(preedit->preedit_areas);
  for (i = 0; i < preedit->alloc_areas; i++) {
    _XUnregisterFilter(ic->core.im->core.display, 
                     preedit_area[i].window,
                     RepaintPreedit, (XPointer)ic);
    _XUnregisterFilter(ic->core.im->core.display, 
                     preedit_area[i].window,
                     FilterKeyPress, (XPointer)ic);
  }

  if (preedit->gc) XFreeGC(ic->core.im->core.display, preedit->gc);
  if (preedit->rgc) XFreeGC(ic->core.im->core.display, preedit->rgc);

  for (i = 0; i < preedit->alloc_areas; i++) {
    if (ic->core.input_style & XIMPreeditNothing) {
      /* check the window is valid before XDestroyWindow() */
      if(IMCheckIMWindow(ic, preedit_area[i].window)) {
        XDestroyWindow(ic->core.im->core.display, preedit_area[i].window);
      }
    }
  }
  if (preedit->preedit_areas) Xfree(preedit->preedit_areas);
  Xfree(preedit);
  ic->gui_icpart->preedit = (PreeditWin)NULL;
  return;
}

Here is the call graph for this function:

static void DrawPreeditString ( XicCommon  ic,
Display *  display,
Window  win,
XFontSet  fontset,
GC  gc,
GC  rgc,
int  x,
int  y,
XIMFeedback *  feedback,
IMFeedbackList feedback_list,
wchar_t *  wstr,
int  offset,
int  len 
) [static]

Definition at line 53 of file guiIMPre.c.

                                                    {
  if (fontset == NULL) return;

  wstr += offset;
  if (feedback != NULL) {
    XIMFeedback *start = (XIMFeedback*)feedback + offset;
    XIMFeedback *current;
    IMFeedbackList *start_flist = 0;
    IMFeedbackList *current_flist;
    int left = len;
    int nchars;
    wchar_t *wcstr = wstr;
    int under_line = y + 1;
    int pos_x = x;
    int width;

    if (feedback_list) {
      start_flist = &feedback_list[offset];
    }
    while (0 < left) {
      current = start;
      current_flist = start_flist;
      nchars = 0;

      while (*current == *start &&
            SameIMFeedbackList(current_flist, start_flist)) {
       nchars++;
       left--;
       if (left == 0) break;
       current++;
       current_flist++;
      }
      /* set colors */
      SetIMColors(ic, display, win, gc, rgc, start_flist, *start);

      if (*start & XIMReverse) {
       XwcDrawImageString(display, win, fontset, rgc, 
                        pos_x, y, wcstr, nchars);
      } else {
       XwcDrawImageString(display, win, fontset, gc, 
                        pos_x, y, wcstr, nchars);
      }
      width = XwcTextEscapement(fontset, wcstr, nchars);
      if (*start & XIMUnderline) {
       if (*start & XIMReverse)
         XDrawLine(display, win, rgc, 
                  pos_x, under_line, pos_x + width, under_line);
       else
         XDrawLine(display, win, gc, 
                  pos_x, under_line, pos_x + width, under_line);
      }
      wcstr += nchars;
      pos_x += width;
      start = current;
      start_flist = current_flist;
    }
  } else {
    XwcDrawString(display, win, fontset, gc, x, y, wstr, len);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Bool FilterConfigureNotify ( Display *  d,
Window  w,
XEvent *  ev,
XPointer  client_data 
)

Definition at line 119 of file guiIMPre.c.

                                                                              {
  XicCommon ic = (XicCommon)client_data;

  if (!ic->gui_icpart || NULL == XIC_GUI(ic, preedit)) {
    /* perhaps the ic has been destroyed already */
    return False;
  }
  if (NULL != ev) {
    if (ConfigureNotify == ev->type) {
      if (((XConfigureEvent *)ev)->window == ic->core.focus_window) {
       XIC_GUI(ic, preedit)->client_window_width =
              ((XConfigureEvent *)ev)->width;
       XIC_GUI(ic, preedit)->client_window_height =
              ((XConfigureEvent *)ev)->height;
       XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_WIN, NULL);
       UpdatePreedit(ic, 0, 0);
      }
    }
  } else {
    if (w == ic->core.focus_window) {
      XWindowAttributes attr;
      if (XGetWindowAttributes(d, w, &attr)) {
       XIC_GUI(ic, preedit)->client_window_width = attr.width;
       XIC_GUI(ic, preedit)->client_window_height = attr.height;
      }
    }
  }

  return False;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 151 of file guiIMPre.c.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 454 of file guiIMPre.c.

                               {
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);
  Window win;
  int x, y;
  unsigned int width, height;
  unsigned long fg, bg;
  Display *display = ic->core.im->core.display;
  PreeditArea preedit_area = (PreeditArea)NULL;
  int n;
  int nn;
  int mask;
  XIMFilterRec filters[2];
  XClassHint class_hint;

  if (!preedit) return False;

  if (XIMP_CHK_PREAREAMASK(ic)) {
    x = ic->core.preedit_attr.area.x;
    y = ic->core.preedit_attr.area.y;
    width   = ic->core.preedit_attr.area.width;
    height  = ic->core.preedit_attr.area.height;
  } else if (XIMP_CHK_PRESPOTLMASK(ic)) {
    x = ic->core.preedit_attr.spot_location.x;
    y = ic->core.preedit_attr.spot_location.y;
    width = height = 1;
  } else {
    x  = y = 0;
    width = height = 1;
  }

  if (preedit->alloc_areas == 0 || !preedit->preedit_areas) {
    preedit->alloc_areas = 1;
    preedit->active_areas = 1;
    preedit->preedit_areas = (PreeditArea)Xmalloc(sizeof(PreeditAreaRec));
    if (!preedit->preedit_areas) {
      return False;
    }
    memset((char *)preedit->preedit_areas, 0, sizeof(PreeditAreaRec));
  } else {
    preedit->alloc_areas++;
    preedit->active_areas++;
    preedit->preedit_areas = (PreeditArea)
      Xrealloc(preedit->preedit_areas, sizeof(PreeditAreaRec) *
              preedit->alloc_areas);
    if (!preedit->preedit_areas) {
      return False;
    }
  }
  preedit_area = preedit->preedit_areas;
  n = preedit->alloc_areas;

  preedit_window_fg_and_bg(ic, &fg, &bg);

  mask = None;
  nn = 0;
  filters[nn].type = KeyPress;
  filters[nn].filter = FilterKeyPress;
  filters[nn].client_data = (XPointer)ic;
  mask |= KeyPressMask;
  nn++;
  filters[nn].type = Expose;
  filters[nn].filter = RepaintPreedit;
  filters[nn].client_data = (XPointer)ic;
  nn++;
  mask |= ExposureMask;

  width = height = 1;
  win = XFactoryCreateIMWindow(display, preedit->parent,
                            ic->core.client_window,
                            x, y, width, height, bg,
                            mask, filters, nn);
  if (!win) return False;

  if (ic->core.input_style & XIMPreeditArea ||
      ic->core.input_style & XIMPreeditPosition) {
    /* 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 Preedit");

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

  if (!(ic->core.input_style & XIMPreeditNothing)) {
    /* bug fix:
          4295973: preedit text is invisible in XIMPreeditNothing
       We don't know why backing store with XIMPreeditNothing causes
       4295973, but having the codes commented out will fix it.
    */
    XSetWindowAttributes attributes;
    mask = 0;
    attributes.bit_gravity = NorthWestGravity;
    mask |= CWBitGravity;
    attributes.backing_store = WhenMapped;
    mask |= CWBackingStore;
    XChangeWindowAttributes(display, win, mask, &attributes);
  }
#if 0
  if (XIMP_CHK_PREFGMASK(ic) && XIMP_CHK_PREBGMASK(ic)) {
    create_preedit_gc(display, win, preedit,
                    ic->core.preedit_attr.foreground,
                    ic->core.preedit_attr.background);
  }
#endif

  preedit_area[n-1].window = win;
  preedit_area[n-1].char_offset = 0;
  preedit_area[n-1].char_len = 0;
  preedit_area[n-1].char_offset_backup = 0;
  preedit_area[n-1].char_len_backup = 0;
  preedit_area[n-1].active_lines = 0;
  preedit_area[n-1].alloc_lines = 0;
  preedit_area[n-1].mapped = False;
  preedit_area[n-1].win_config.x = x;
  preedit_area[n-1].win_config.y = y;
  preedit_area[n-1].win_config.width = width;
  preedit_area[n-1].win_config.height = height;


  return True;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void preedit_window_fg_and_bg ( XicCommon  ic,
unsigned long *  fg,
unsigned long *  bg 
) [static]

Definition at line 236 of file guiIMPre.c.

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

  if (XIMP_CHK_PREFGMASK(ic) && XIMP_CHK_PREBGMASK(ic)) {
    *fg = ic->core.preedit_attr.foreground;
    *bg = ic->core.preedit_attr.background;
  } else {
    *fg = BlackPixel(display, DefaultScreen(display));
    *bg = WhitePixel(display, DefaultScreen(display));
  }
  return;
}

Here is the caller graph for this function:

void PreeditCaret ( XicCommon  ic,
XPointer  call_data 
)

Definition at line 1414 of file guiIMPre.c.

                                               {
  /* do nothing */
  return;
}
void PreeditCaretAdjustLookupPlacement ( XicCommon  ic,
XPoint *  point 
)

Definition at line 1500 of file guiIMPre.c.

                                                                {
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);
  PreeditArea preedit_area;
  PreeditChars preedit_chars;
  int  escapement = 0; 
  int vertical = 0;
  int i;

  if (NULL == preedit) {
    XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_CREATE, NULL);
    preedit = (PreeditWin)(ic->gui_icpart->preedit);
  }
  if (NULL != preedit) {
    preedit_area = (PreeditArea)(preedit->preedit_areas);
    preedit_chars = (PreeditChars)&(preedit->preedit_chars);
    for (i = 0; i < preedit->alloc_areas; i++) {
      if (preedit_area[i].active_lines == 0) {
       int char_offset = preedit_area[i].char_offset;
       int char_len = preedit_area[i].char_len;
       if ((char_offset <= preedit_chars->caret_pos) &&
           (preedit_chars->caret_pos <= (char_offset + char_len))) {
         if (char_offset != preedit_chars->caret_pos) {
           escapement = XwcTextEscapement(preedit->fontset,
                                      preedit_chars->wchar + 
                                      preedit_chars->caret_pos,
                                      preedit_chars->caret_pos -
                                      char_offset);
         }
         vertical = (ic->core.preedit_attr.area.height * i);
         point->x += escapement;
         point->y += vertical;
         TRACE_MESSAGE('p', ("caret_pos=%d escapement=%d vertical=%d\n",
                           preedit_chars->caret_pos, escapement, vertical));
         return;
       }
      }
    }
    if ((preedit_chars->caret_pos <= 0) ||
       (preedit_chars->wchar_len <= preedit_chars->caret_pos)) {
      return;
    }
    if (0 < preedit_chars->caret_pos) {
      escapement = XwcTextEscapement(preedit->fontset,
                                 preedit_chars->wchar,
                                 preedit_chars->caret_pos);
    }
    TRACE_MESSAGE('p', ("caret_pos=%d escapement=%d len=%d caret=%d\n",
                     preedit_chars->caret_pos, escapement,
                     preedit_chars->wchar_len, preedit_chars->caret_pos));
  }
  return;
}
void PreeditCaretPlacement ( XicCommon  ic,
XPoint *  point 
)

Definition at line 1554 of file guiIMPre.c.

{
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);
  PreeditArea preedit_area;
  PreeditChars preedit_chars;
  int  x = 0; 
  int y = 0;
  int i;

  if (NULL == preedit) {
    XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_CREATE, NULL);
    preedit = (PreeditWin)(ic->gui_icpart->preedit);
  }
  if (NULL != preedit) {
    preedit_area = (PreeditArea)(preedit->preedit_areas);
    preedit_chars = (PreeditChars)&(preedit->preedit_chars);

    if (preedit_area == 0 || preedit_chars == 0 ||
       preedit_chars->wchar == 0) {
      return;
    }
    for (i = 0; i < preedit->alloc_areas; i++) {
      int char_offset = preedit_area[i].char_offset;
      int char_len = preedit_area[i].char_len;

      if (preedit_area[i].active_lines == 0) {
       if ((char_offset <= preedit_chars->caret_pos) &&
           (preedit_chars->caret_pos <= (char_offset + char_len))) {

         XFontSetExtents *fse = 0;
         if (!preedit->fontset) {
           SetPreeditFont(ic, NULL);
         }
         fse = XExtentsOfFontSet(preedit->fontset);

         if (char_offset != preedit_chars->caret_pos) {
           x = XwcTextEscapement(preedit->fontset,
                              preedit_chars->wchar + 
                              char_offset,
                              preedit_chars->caret_pos -
                              char_offset);
         } else {
           x = 0;
         }
         y = (-fse->max_ink_extent.y);
         XFactoryGetLocationOnScreen(ic->core.im->core.display,
                                  preedit_area[i].window,
                                  x, y, point);
         TRACE_MESSAGE('p', ("caret_pos=%d escapement=%d vertical=%d\n",
                           preedit_chars->caret_pos, x, y));
         return;

       }
      } else {
       PreeditLine line = (PreeditLine)preedit_area[i].lines;
       int j;

       for (j = 0; j < preedit_area[i].active_lines; j++) {
         if ((line[j].char_offset <= preedit_chars->caret_pos) &&
             (preedit_chars->caret_pos < (line[j].char_offset + line[j].char_len))) {
           XFontSetExtents *fse = 0;
           if (!preedit->fontset) {
             SetPreeditFont(ic, NULL);
           }
           fse = XExtentsOfFontSet(preedit->fontset);
           if (line[j].char_offset != preedit_chars->caret_pos) {
             x = XwcTextEscapement(preedit->fontset,
                                preedit_chars->wchar + 
                                line[j].char_offset,
                                preedit_chars->caret_pos -
                                line[j].char_offset);
           } else {
             x = 0;
           }
           y = ((fse->max_logical_extent.height * j) +
               (-fse->max_ink_extent.y));
           XFactoryGetLocationOnScreen(ic->core.im->core.display,
                                   preedit_area[i].window,
                                   x, y, point);
           TRACE_MESSAGE('p', ("caret_pos=%d escapement=%d vertical=%d\n",
                            preedit_chars->caret_pos, x, y));
           return;
         }
       }
      }
    }
  }
  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void PreeditCaretPlacementRelative ( XicCommon  ic,
XPoint *  point 
)

Definition at line 1645 of file guiIMPre.c.

{
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);
  PreeditArea preedit_area;
  PreeditChars preedit_chars;
  int  x = 0; 
  int y = 0;
  int i;
  int new_x;
  int new_y;
  Window child;


  if (NULL == preedit) {
    XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_CREATE, NULL);
    preedit = (PreeditWin)(ic->gui_icpart->preedit);
  }
  if (NULL != preedit) {
    preedit_area = (PreeditArea)(preedit->preedit_areas);
    preedit_chars = (PreeditChars)&(preedit->preedit_chars);

    for (i = 0; i < preedit->alloc_areas; i++) {
      int char_offset = preedit_area[i].char_offset;
      int char_len = preedit_area[i].char_len;

      if (preedit_area[i].active_lines == 0) {
       if ((char_offset <= preedit_chars->caret_pos) &&
           (preedit_chars->caret_pos <= (char_offset + char_len))) {
         XFontSetExtents *fse = 0;
         if (0 == preedit_chars->wchar_len) {
           if (XIMP_CHK_PREAREAMASK(ic)) {
             x = ic->core.preedit_attr.area.x;
             y = ic->core.preedit_attr.area.y;
           } else if (XIMP_CHK_PRESPOTLMASK(ic)) {
             x = ic->core.preedit_attr.spot_location.x;
             y = ic->core.preedit_attr.spot_location.y;
           } else {
             x  = y = 0;
           }
           return;
         }
         if (!preedit->fontset) {
           SetPreeditFont(ic, NULL);
         }
         fse = XExtentsOfFontSet(preedit->fontset);

         if (char_offset != preedit_chars->caret_pos) {
           x = XwcTextEscapement(preedit->fontset,
                              preedit_chars->wchar + 
                              char_offset,
                              preedit_chars->caret_pos -
                              char_offset);
         } else {
           x = 0;
         }
         y = fse->max_logical_extent.height;
         y += (fse->max_ink_extent.height + fse->max_ink_extent.y);

         XTranslateCoordinates(ic->core.im->core.display,
                            preedit_area[i].window,
                            ic->core.focus_window,
                            x, y, &new_x, &new_y, &child);
         point->x = new_x;
         point->y = new_y;

         TRACE_MESSAGE('p', ("caret_pos=%d escapement=%d vertical=%d\n",
                           preedit_chars->caret_pos, x, y));
         return;

       }
      } else {
       PreeditLine line = (PreeditLine)preedit_area[i].lines;
       int j;

       for (j = 0; j < preedit_area[i].active_lines; j++) {
         if ((line[j].char_offset <= preedit_chars->caret_pos) &&
             (preedit_chars->caret_pos < (line[j].char_offset + line[j].char_len))) {
           XFontSetExtents *fse = 0;
           if (0 == preedit_chars->wchar_len) {
             if (XIMP_CHK_PREAREAMASK(ic)) {
              x = ic->core.preedit_attr.area.x;
              y = ic->core.preedit_attr.area.y;
             } else if (XIMP_CHK_PRESPOTLMASK(ic)) {
              x = ic->core.preedit_attr.spot_location.x;
              y = ic->core.preedit_attr.spot_location.y;
             } else {
              x  = y = 0;
             }
             return;
           }
           if (!preedit->fontset) {
             SetPreeditFont(ic, NULL);
           }
           fse = XExtentsOfFontSet(preedit->fontset);
           if (line[j].char_offset != preedit_chars->caret_pos) {
             x = XwcTextEscapement(preedit->fontset,
                                preedit_chars->wchar + 
                                line[j].char_offset,
                                preedit_chars->caret_pos -
                                line[j].char_offset);
           } else {
             x = 0;
           }
           y = (fse->max_logical_extent.height * (j + 1));
           y += (fse->max_ink_extent.height + fse->max_ink_extent.y);

           XTranslateCoordinates(ic->core.im->core.display,
                              preedit_area[i].window,
                              ic->core.focus_window,
                              x, y, &new_x, &new_y, &child);
           point->x = new_x;
           point->y = new_y;

           TRACE_MESSAGE('p', ("caret_pos=%d escapement=%d vertical=%d\n",
                            preedit_chars->caret_pos, x, y));
           return;
         }
       }
      }
    }
  }
  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void PreeditCursor ( PreeditChars  preedit_chars,
int  caret 
) [static]

Definition at line 1290 of file guiIMPre.c.

                                                     {
  /* need to implement  */
  if (preedit_chars->caret_pos != caret) {
    preedit_chars->caret_pos = caret;
  }
  return;
}

Here is the caller graph for this function:

void PreeditDone ( XicCommon  ic,
XPointer  call_data 
)

Definition at line 1420 of file guiIMPre.c.

                                              {
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);
  PreeditArea preedit_area;
  PreeditChars preedit_chars;
  int i;

  if (!preedit) return;

  _XUnregisterFilter(ic->core.im->core.display, ic->core.focus_window,
                   FilterConfigureNotify, (XPointer)ic);

  preedit_area = (PreeditArea)(preedit->preedit_areas);
  preedit_chars = (PreeditChars)&(preedit->preedit_chars);

  if (preedit_chars->feedback) Xfree((char*)preedit_chars->feedback);
  if (preedit_chars->wchar) Xfree((char*)preedit_chars->wchar);
  if (preedit_chars->wchar_width)
    Xfree((char*)preedit_chars->wchar_width);
  FreeFeedbackList(preedit_chars->feedback_list, 
                 preedit_chars->alloc_len);
  preedit_chars->feedback_list = NULL;
  preedit_chars->feedback = NULL;
  preedit_chars->wchar = NULL;
  preedit_chars->wchar_width = NULL;
  preedit_chars->wchar_len = 0;
  preedit_chars->alloc_len = 0;

  for (i = 0; i < preedit->alloc_areas; i++) {
    UnmapPreeditWindow(ic, preedit_area + i);
  }
  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void PreeditDrawText ( XicCommon  ic,
XPointer  p 
)

Definition at line 1340 of file guiIMPre.c.

                                          {
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);
  PreeditChars preedit_chars;
  int chg_first;
  int chg_length;
  XIMDrawTextStruct *preedit_draw = (XIMDrawTextStruct*)p;
  XIMPreeditDrawCallbackStruct *call_data =
    (XIMPreeditDrawCallbackStruct*)preedit_draw->call_data;
  XIMText *text = (XIMText*)call_data->text;
  IMFeedbackList *feedback_list = preedit_draw->feedback_list;

  if (!preedit) {
    XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_CREATE, NULL);
    preedit = (PreeditWin)(ic->gui_icpart->preedit);
    if (!preedit) return;
  }

  preedit_chars = (PreeditChars)&(preedit->preedit_chars);
  if (preedit_chars->alloc_len == 0) {
    if (text) {
      /* Start drawing preedit without calling preedit_start */
      PreeditStart(ic, NULL);
    } else {
      return;               /* nothing to do */
    }
  }

#if 0
  if (call_data->chg_first == preedit_chars->wchar_len) {
    /* append from right most position */
    if (text && text->length > 0) change_len = text->length;
  }else if ((call_data->chg_first + call_data->chg_length
            == preedit_chars->wchar_len) && !text) {
    /* delete from right most position */
    change_len = call_data->chg_length;
  } else {
    /* other operations */
    change_len = preedit_chars->wchar_len - call_data->chg_first;
    change_len -= call_data->chg_length;
    if (text && text->length > 0) change_len += text->length;
  }
#endif /* 0 */

  chg_first = call_data->chg_first;
  chg_length = call_data->chg_length;

  TRACE_MESSAGE('p', ("PreeditDrawText: chg_first = %d chg_length = %d, %d %d, caret = %d\n",
                    call_data->chg_first, call_data->chg_length,
                    chg_first, chg_length, call_data->caret));

#if 1
  PreeditReplaceString(ic, preedit,
                     &chg_first, &chg_length, text, feedback_list);

#else /* 0 */
  if (call_data->chg_length) {
    PreeditDelete(preedit_chars,
                call_data->chg_first, call_data->chg_length);
  }
  PreeditInsert(ic, preedit_chars, call_data->chg_first,
              text, feedback_list);
#endif /* 0 */
  PreeditCursor(preedit_chars, call_data->caret);
  XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_WIN, NULL);
#if 1
  UpdatePreedit(ic, chg_first, chg_length);
#else /* 0 */
  UpdatePreedit(ic, call_data->chg_first, change_len);
#endif /* 0 */

  return;
}

Here is the call graph for this function:

static void PreeditReplaceString ( XicCommon  ic,
PreeditWin  preedit,
int *  change_first,
int *  change_length,
XIMText *  text,
IMFeedbackList feedback_list 
) [static]

Definition at line 780 of file guiIMPre.c.

                                                                 {
  int  first_real;
  int  length_real;
  int  first_orig;
  int  length_orig;
  int  i = 0;
  int  j;
  int  m;
  int  text_length;
  PreeditChars preedit_chars;
  PreeditChars preedit_chars_backup;
  wchar_t *cur_char;
  wchar_t *chg_char;
  wchar_t wc_buf[1024];
  wchar_t *wc_p;
  wchar_t *wc_p_free;
  IMFeedbackList *src_fbl;
  IMFeedbackList *dst_fbl;
  IMFeedbackList *cur_fbl;
  IMFeedbackList *chg_fbl;
  XIMFeedback *cur_xfb;
  XIMFeedback *chg_xfb;
  IMFeedback  *cur_fb;
  IMFeedback  *chg_fb;

  preedit_chars = &(preedit->preedit_chars);

  if (preedit_chars->wchar_len < *change_first) {
    first_orig  = preedit_chars->wchar_len;
    length_orig = 0;
  } else if (preedit_chars->wchar_len < (*change_first + *change_length)) {
    first_orig  = *change_first;
    length_orig = (preedit_chars->wchar_len - *change_first);
  } else {
    first_orig  = *change_first;
    length_orig = *change_length;
  }
  first_real = first_orig;
  length_real = length_orig;

  wc_p_free = NULL;

  /*
   * dtermine the real change
   */
  if (NULL == text) {
    wc_p = NULL;
    text_length = 0;
    *change_first = first_real;
    *change_length = length_real;
  } else {
    text_length = text->length;
    if (text->encoding_is_wchar) {
      wc_p = text->string.wide_char;
    } else {
      wc_p = wc_buf;
      if (((sizeof (wc_buf)) / (sizeof (wchar_t))) < text_length) {
       wc_p = Xmalloc((sizeof (wchar_t)) * text_length);
       if (NULL == wc_p) return;
       wc_p_free = wc_p;
      }
      IIimpMbstoWcs((XimCommon)ic->core.im,
                  text->string.multi_byte, strlen(text->string.multi_byte),
                  wc_p, text_length, NULL);
    }

    cur_char = (preedit_chars->wchar + first_real);
    cur_fbl = (preedit_chars->feedback_list + first_real);
    cur_xfb = (preedit_chars->feedback + first_real);
    chg_char = wc_p;
    chg_fbl = feedback_list;
    chg_xfb = text->feedback;

    /*
     * calculate first_real
     */
    for (i = 0; i < length_real; i++) {
      if (*(cur_char + i) != *(chg_char + i)) {
       break;
      }

      cur_fb = cur_fbl[i].feedbacks;
      if (NULL == chg_fbl) {
       for (j = 0; j < cur_fbl[i].count_feedbacks; j++) {
         if ((IM_DECORATION_FEEDBACK != (cur_fb + j)->type) ||
             (0 != (cur_fb + j)->value)) {
           break;
         }
       }
       if (j != cur_fbl[i].count_feedbacks) {
         break;
       }
      } else {
       if (cur_fbl[i].count_feedbacks != chg_fbl[i].count_feedbacks) {
         break;
       }
       chg_fb = chg_fbl[i].feedbacks;
       for (j = 0; j < cur_fbl[i].count_feedbacks; j++) {
         if (((cur_fb + j)->type  != (chg_fb + j)->type) ||
             ((cur_fb + j)->value != (chg_fb + j)->value)) {
           break;
         }
       }
       if (j != cur_fbl[i].count_feedbacks) {
         break;
       }
      }

      if (NULL == chg_xfb) {
       if (*(cur_xfb + i) != 0) {
         break;
       }
      } else {
       if (*(cur_xfb + i) != *(chg_xfb + i)) {
         break;
       }
      }
    }
    first_real += i;

    cur_char = (preedit_chars->wchar + *change_first + *change_length - 1);
    cur_fbl = ((NULL == preedit_chars->feedback_list) ? NULL :
              (preedit_chars->feedback_list +
              *change_first + *change_length - 1));
    cur_xfb = ((NULL == preedit_chars->feedback) ? NULL :
              (preedit_chars->feedback + *change_first + *change_length - 1));
    chg_char = (wc_p + text_length - 1);
    chg_fbl = ((NULL == feedback_list) ? NULL :
              (feedback_list + text_length - 1));
    chg_xfb = ((NULL == text->feedback) ? NULL :
              (text->feedback + text_length - 1));

    /*
     * calculate length_real
     */
    if (0 == *change_length) {
      m = 0;
    } else {
      m = ((text_length < *change_length) ? *change_length : text_length);
    }
    for (i = 0; i < m; i++) {
      if (*(cur_char - i) != *(chg_char - i)) {
       break;
      }

      cur_fb = (cur_fbl->feedbacks - i);
      if (NULL == chg_fbl) {
       for (j = 0; j < cur_fbl->count_feedbacks; j++) {
         if ((IM_DECORATION_FEEDBACK != (cur_fb + j)->type) ||
             (0 != (cur_fb + j)->value)) {
           break;
         }
       }
       if (j != cur_fbl->count_feedbacks) {
         break;
       }
      } else {
       if ((cur_fbl - i)->count_feedbacks != (chg_fbl - i)->count_feedbacks) {
         break;
       }
       chg_fb = (chg_fbl->feedbacks - i);
       for (j = 0; j < cur_fbl->count_feedbacks; j++) {
         if (((cur_fb + j)->type  != (chg_fb + j)->type) ||
             ((cur_fb + j)->value != (chg_fb + j)->value)) {
           break;
         }
       }
       if (j != cur_fbl->count_feedbacks) {
         break;
       }
      }

      if (NULL == chg_xfb) {
       if (*(cur_xfb - i) != 0) {
         break;
       }
      } else {
       if (*(cur_xfb - i) != *(chg_xfb - i)) {
         break;
       }
      }
    }
    length_real -= i;

    *change_first = first_real;
    if (*change_length == text_length) {
      *change_length = length_real;
    } else {
      *change_length = (preedit_chars->wchar_len
                     - first_real - *change_length + text_length);
    }
  }

  /*
   * free preedit_chars_backup
   */
  preedit_chars_backup = &(preedit->preedit_chars_backup);

  Xfree((char*)preedit_chars_backup->feedback);
  Xfree((char*)preedit_chars_backup->wchar);
  Xfree((char*)preedit_chars_backup->wchar_width);
  FreeFeedbackList(preedit_chars_backup->feedback_list, 
                 preedit_chars_backup->alloc_len);

  /*
   * backup current preedit_chars
   */
  preedit_chars_backup->feedback_list = preedit_chars->feedback_list;
  preedit_chars_backup->feedback = preedit_chars->feedback;
  preedit_chars_backup->wchar = preedit_chars->wchar;
  preedit_chars_backup->wchar_width = preedit_chars->wchar_width;
  preedit_chars_backup->wchar_len = preedit_chars->wchar_len;
  preedit_chars_backup->alloc_len = preedit_chars->alloc_len;

  /*
   * allocate new preedit_chars areas
   */
  preedit_chars->wchar_len = (preedit_chars_backup->wchar_len - length_orig
                           + text_length);
  preedit_chars->alloc_len = (preedit_chars->wchar_len + 1);
  preedit_chars->wchar = Xmalloc(preedit_chars->alloc_len * (sizeof (wchar_t)));
  preedit_chars->wchar_width = Xmalloc(preedit_chars->alloc_len *
                                   (sizeof (unsigned short)));
  memset(preedit_chars->wchar_width, 0,
        preedit_chars->alloc_len * (sizeof (unsigned short)));
  preedit_chars->feedback =
         Xmalloc(preedit_chars->alloc_len * (sizeof (XIMFeedback)));
  memset(preedit_chars->feedback, 0,
        preedit_chars->alloc_len * (sizeof (XIMFeedback)));
  preedit_chars->feedback_list =
         Xmalloc(preedit_chars->alloc_len * (sizeof (IMFeedbackList)));
  memset(preedit_chars->feedback_list, 0,
        preedit_chars->alloc_len * (sizeof (IMFeedbackList)));  

  /*
   * update wchar
   */
  if (0 != first_orig) {
    memcpy(preedit_chars->wchar, preedit_chars_backup->wchar,
          (sizeof (wchar_t)) * first_orig);
  }
  if (0 != text_length) {
    memcpy(preedit_chars->wchar + first_orig, wc_p,
          (sizeof (wchar_t)) * text_length);
  }
  if ((first_orig + text_length) < preedit_chars->wchar_len) {
    memcpy(preedit_chars->wchar + first_orig + text_length,
          preedit_chars_backup->wchar + first_orig + length_orig,
          (sizeof (wchar_t)) *
          (preedit_chars->wchar_len - first_orig + text_length));
  }
  *(preedit_chars->wchar + preedit_chars->wchar_len) = L'\0';

  /*
   * update width
   */

  if (0 != first_orig) {
    memcpy(preedit_chars->wchar_width, preedit_chars_backup->wchar_width,
          (sizeof (unsigned short)) * first_orig);
  }
  if (0 != text_length) {
    if (NULL == preedit->fontset) {
      SetPreeditFont(ic, NULL);
    }
    if (NULL == preedit->fontset) {
      *(preedit_chars->wchar_width + i) = 0;
    } else {
      for (i = 0; i < text_length; i++) {
       *(preedit_chars->wchar_width + first_orig + i) =
              XwcTextEscapement(preedit->fontset, wc_p + i, 1);
      }
    }
  }
  if ((first_orig + text_length) < preedit_chars->wchar_len) {
    memcpy(preedit_chars->wchar_width + first_orig + text_length,
          preedit_chars_backup->wchar_width + first_orig + length_orig,
          (sizeof (unsigned short)) *
          (preedit_chars->wchar_len - first_orig + text_length));
  }

  /*
   * update feedback
   */
  if (0 != first_orig) {
    memcpy(preedit_chars->feedback, preedit_chars_backup->feedback,
          (sizeof (XIMFeedback)) * first_orig);
  }
  if (0 != text_length) {
    memcpy(preedit_chars->feedback + first_orig, text->feedback,
          (sizeof (XIMFeedback)) * text_length);
  } else {
    memset(preedit_chars->feedback + first_orig, 0,
          (sizeof (XIMFeedback)) * text_length);
  }
  if ((first_orig + text_length) < preedit_chars->wchar_len) {
    memcpy(preedit_chars->feedback + first_orig + text_length,
          preedit_chars_backup->feedback + first_orig + length_orig,
          (sizeof (XIMFeedback)) * 
          (preedit_chars->wchar_len - first_orig + text_length));
  }
  *(preedit_chars->feedback + preedit_chars->wchar_len) = 0;

  /*
   * update feedback_list
   */
  for (i = 0; i < first_orig; i++) {
    (preedit_chars->feedback_list + i)->count_feedbacks =
           (preedit_chars_backup->feedback_list + i)->count_feedbacks;
    if (0 == (preedit_chars->feedback_list + i)->count_feedbacks) {
      (preedit_chars->feedback_list + i)->feedbacks = NULL;
    } else {
      (preedit_chars->feedback_list + i)->feedbacks =
             Xmalloc((preedit_chars->feedback_list + i)->count_feedbacks *
                    (sizeof (IMFeedback)));
    }
    for (j = 0; j < (preedit_chars->feedback_list + i)->count_feedbacks; j++) {
      ((preedit_chars->feedback_list + i)->feedbacks + j)->type =
             ((preedit_chars_backup->feedback_list + i)->feedbacks + j)->type;
      ((preedit_chars->feedback_list + i)->feedbacks + j)->value =
             ((preedit_chars_backup->feedback_list + i)->feedbacks + j)->value;
    }
  }
  if (NULL != feedback_list) {
    for (i = first_orig; i < (first_orig + text_length); i++) {
      (preedit_chars->feedback_list + i)->count_feedbacks =
             (feedback_list + i)->count_feedbacks;
      if (0 == (preedit_chars->feedback_list + i)->count_feedbacks) {
       (preedit_chars->feedback_list + i)->feedbacks = NULL;
      } else {
       (preedit_chars->feedback_list + i)->feedbacks =
              Xmalloc((preedit_chars->feedback_list + i)->count_feedbacks *
                     (sizeof (IMFeedback)));
      }
      for (j = 0; j < (preedit_chars->feedback_list + i)->count_feedbacks; j++) {
       ((preedit_chars->feedback_list + i)->feedbacks + j)->type =
              ((feedback_list + i)->feedbacks + j)->type;
       ((preedit_chars->feedback_list + i)->feedbacks + j)->value =
              ((feedback_list + i)->feedbacks + j)->value;
      }
    }
  } else {
    for (i = first_orig; i < (first_orig + text_length); i++) {
      (preedit_chars->feedback_list + i)->count_feedbacks = 0;
      (preedit_chars->feedback_list + i)->feedbacks = NULL;
    }
  }
  dst_fbl = (preedit_chars->feedback_list + first_orig + text_length);
  src_fbl = (preedit_chars_backup->feedback_list + first_orig + text_length);
  for (i = first_orig + text_length; i < preedit_chars->wchar_len; i++) {
    dst_fbl->count_feedbacks = src_fbl->count_feedbacks;
    if (0 == dst_fbl->count_feedbacks) {
      dst_fbl->feedbacks = NULL;
    } else {
      dst_fbl->feedbacks =
             Xmalloc(dst_fbl->count_feedbacks * (sizeof (IMFeedback)));
    }
    for (j = 0; j < dst_fbl->count_feedbacks; j++) {
      (dst_fbl->feedbacks + j)->type  = (src_fbl->feedbacks + j)->type;
      (dst_fbl->feedbacks + j)->value = (src_fbl->feedbacks + j)->value;
    }
    src_fbl += 1;
    dst_fbl += 1;
  }
  dst_fbl->count_feedbacks = 0;
  dst_fbl->feedbacks = NULL;


  Xfree(wc_p_free);

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void PreeditStart ( XicCommon  ic,
XPointer  call_data 
)

Definition at line 1299 of file guiIMPre.c.

                                               {
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);
  PreeditChars preedit_chars;

  if (!preedit) {
    XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_CREATE, NULL);
    preedit = (PreeditWin)(ic->gui_icpart->preedit);
    if (!preedit) return;
  }
  preedit_chars = (PreeditChars)&(preedit->preedit_chars);
  preedit_chars->caret_pos = 0;
  preedit_chars->wchar_len = 0;
  preedit_chars->alloc_len = 16;
  preedit_chars->wchar = Xmalloc(sizeof(wchar_t) *
                             preedit_chars->alloc_len);
  preedit_chars->wchar_width = Xmalloc(sizeof(unsigned short) *
                                   preedit_chars->alloc_len);
  preedit_chars->feedback = Xmalloc(sizeof(XIMFeedback) *
                                preedit_chars->alloc_len);
  preedit_chars->feedback_list = Xmalloc(sizeof(IMFeedbackList) *
                                    preedit_chars->alloc_len);
  memset(preedit_chars->wchar, 0,
        sizeof(wchar_t) * preedit_chars->alloc_len);
  memset(preedit_chars->wchar_width, 0,
        sizeof(unsigned short) * preedit_chars->alloc_len);
  memset(preedit_chars->feedback, 0,
        sizeof(XIMFeedback) * preedit_chars->alloc_len);
  memset(preedit_chars->feedback_list, 0,
        sizeof(IMFeedbackList) * preedit_chars->alloc_len);

  FilterConfigureNotify(ic->core.im->core.display,
                     ic->core.focus_window,
                     NULL, (XPointer)ic);
  _XRegisterFilterByType(ic->core.im->core.display, ic->core.focus_window,
                      ConfigureNotify, ConfigureNotify,
                      FilterConfigureNotify, (XPointer)ic);

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 159 of file guiIMPre.c.

                                                                       {
  XicCommon ic = (XicCommon)client_data;
  PreeditWin preedit = NULL;

  if (!ic->gui_icpart) return True;
  preedit = (PreeditWin)ic->gui_icpart->preedit;
  
  if (!preedit) return True;

  if (True == XIC_GUI(ic, preedit)->discard_expose_event) {
    /*
     * when preedit window is created or reconfigured, expose
     * event will be delivered.  xiiimp.so always updates
     * contents of the window before receiving expose event,
     * there is no need to update the contents here.
     */
    XIC_GUI(ic, preedit)->discard_expose_event = False;
    return True;
  }

  /* multiple expose event */
  if (0 != ((XExposeEvent *)ev)->count) return True;

  UpdatePreedit(ic, 0, 0);
  return True;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void SetPreeditBackground ( XicCommon  ic,
XPointer  call_data 
)

Definition at line 683 of file guiIMPre.c.

                                                       {
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);
  CacheRec *preedit_cache;
  int i;

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

  preedit_cache = (CacheRec*)&(preedit->preedit_cache);

  TRACE_MESSAGE('p', ("SetPreeditBackground: %d %d\n",
                    preedit_cache->background,
                    ic->core.preedit_attr.background));

  if (preedit_cache->background == ic->core.preedit_attr.background) {
    return;
  }

  for (i = 0; i < preedit->alloc_areas; i++) {
    if (preedit->preedit_areas[i].window) {
      XSetWindowBackground(ic->core.im->core.display,
                        preedit->preedit_areas[i].window,
                        ic->core.preedit_attr.background);
    }
  }
#if 0
  if (preedit->gc) {
    XGCValues val;
    unsigned long mask;
    val.background = ic->core.preedit_attr.background;
    mask = GCBackground;
    XChangeGC(ic->core.im->core.display,
             preedit->gc,
             mask,
             &val);
  }
  if (preedit->rgc) {
    XGCValues val;
    unsigned long mask;
    val.foreground = ic->core.preedit_attr.background;
    mask = GCForeground;
    XChangeGC(ic->core.im->core.display,
             preedit->rgc,
             mask,
             &val);
  }
#endif
  preedit_cache->background = ic->core.preedit_attr.background;
  return;
}
void SetPreeditFont ( XicCommon  ic,
XPointer  call_data 
)

Definition at line 752 of file guiIMPre.c.

                                                 {
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);

  if (!preedit) {
    XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_CREATE, NULL);
    preedit = (PreeditWin)ic->gui_icpart->preedit;
    if (!preedit) return;
  }
  if (ic->core.preedit_attr.fontset) {
    if (preedit->fontset && preedit->need_free_fontset) {
      XFactoryFreeDefaultFontSet (ic->core.im->core.display);
      preedit->need_free_fontset = False;
    }
    preedit->fontset = ic->core.preedit_attr.fontset;
  } else if (preedit->fontset == NULL) {
    preedit->fontset = XFactoryCreateDefaultFontSet(ic->core.im->core.display,
                                              XIM_IIIMP(ic->core.im, default_font_name));
    preedit->need_free_fontset = True;
  }
  preedit->fse = XExtentsOfFontSet(preedit->fontset);

  XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_WIN, NULL);
  UpdatePreeditWidth(ic);
  XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_MOVE, NULL);
  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void SetPreeditForeground ( XicCommon  ic,
XPointer  call_data 
)

Definition at line 644 of file guiIMPre.c.

                                                       {
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);
  CacheRec *preedit_cache;

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

  preedit_cache = (CacheRec*)&(preedit->preedit_cache);

  if (preedit_cache->foreground == ic->core.preedit_attr.foreground) {
    return;
  }
#if 0
  if (preedit->gc) {
    XGCValues val;
    unsigned long mask;
    val.foreground = ic->core.preedit_attr.foreground;
    mask = GCForeground;
    XChangeGC(ic->core.im->core.display,
             preedit->gc,
             mask,
             &val);
  }

  if (preedit->rgc) {
    XGCValues val;
    unsigned long mask;
    val.background = ic->core.preedit_attr.foreground;
    mask = GCBackground;
    XChangeGC(ic->core.im->core.display,
             preedit->rgc,
             mask,
             &val);
  }
#endif
  preedit_cache->foreground = ic->core.preedit_attr.foreground;
  return;
}

Definition at line 439 of file guiIMPre.c.

                              {
  PreeditWin preedit = (PreeditWin)Xmalloc(sizeof(PreeditWinRec));

  if (!preedit) return False;
  memset((char *)preedit, 0, sizeof(PreeditWinRec));

  preedit->alloc_areas = 0;
  preedit->active_areas = 0;
  preedit->need_free_fontset = False;

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

Here is the caller graph for this function:

Bool SetupPreeditWindow ( XicCommon  ic,
Window  parent 
)

Definition at line 584 of file guiIMPre.c.

                                                {
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);
  int x, y;
  Display *display = ic->core.im->core.display;
  PreeditArea preedit_area = (PreeditArea)NULL;
  XWindowAttributes cwin_att;
  int i;

  if (!preedit) return False;

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

    /* on Linux, sometimes parent window is invalid */
    if (preedit->parent && !IMCheckIMWindow(ic, preedit->parent)) {
      preedit->alloc_areas=0;
    }
  }

  preedit->parent = parent;

  if (XIMP_CHK_PREAREAMASK(ic)) {
    x = ic->core.preedit_attr.area.x;
    y = ic->core.preedit_attr.area.y;
  } else if (XIMP_CHK_PRESPOTLMASK(ic)) {
    x = ic->core.preedit_attr.spot_location.x;
    y = ic->core.preedit_attr.spot_location.y;
  } else {
    x  = y = 0;
  }

  if (preedit->alloc_areas > 0) {
    preedit_area = preedit->preedit_areas;
    for (i = 0; i < preedit->alloc_areas; i++) {
      if (preedit_area[i].window) {
       /* Make sure the window gets unmapped */
        preedit_area[i].mapped = True;
       UnmapPreeditWindow(ic, preedit_area + i);
       XReparentWindow(display, preedit_area[i].window,
                     preedit->parent,
                     x, y);
      }
    }
    XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_MOVE, NULL);
    /* redraw if any text in preedit windows */
    UpdatePreedit(ic, 0, 0);
    return True;
  } else {
    if (XGetWindowAttributes(ic->core.im->core.display, 
              ic->core.client_window, &cwin_att) && 
              (cwin_att.map_state == IsViewable))
      return NewPreeditWindow(ic);
    else 
      return False;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void UnmapPreeditWindow ( XicCommon  ic,
PreeditArea  preedit_area 
)

Definition at line 267 of file guiIMPre.c.

                                                           {
  if (False == preedit_area->mapped) {
    return;
  }

  XUnmapWindow(ic->core.im->core.display, preedit_area->window);
  preedit_area->mapped = False;
  preedit_area->win_config.x = -1;
  preedit_area->win_config.y = -1;
  preedit_area->win_config.height = -1;
  preedit_area->win_config.width = -1;

  return;
}

Here is the caller graph for this function:

static void UpdatePreedit ( XicCommon  ic,
int  start,
int  len 
) [static]

Definition at line 283 of file guiIMPre.c.

                                                {
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);
  PreeditArea preedit_area = preedit->preedit_areas;
  PreeditChars preedit_chars;
  int i;

  if (!preedit) return;

  if (!preedit->preedit_areas) {
    XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_CREATE, NULL);
    if (!preedit->preedit_areas)
      return;
  }
  preedit_area = preedit->preedit_areas;
  preedit_chars = (PreeditChars)&(preedit->preedit_chars);

  if (preedit_chars->wchar_len == 0) {
    for (i = 0; i < preedit->active_areas; i++) {
      UnmapPreeditWindow(ic, preedit_area + i);
    }
    return;
  }
  if (preedit->gc == 0 || preedit->rgc == 0) {
    unsigned long fg, bg;
    preedit_window_fg_and_bg(ic, &fg, &bg);
    create_preedit_gc(ic->core.im->core.display,
                    preedit_area[0].window, preedit,
                    fg, bg);
  }

  if (!preedit->fontset) {
    SetPreeditFont(ic, NULL);
  }
  for (i = 0; i < preedit->active_areas; i++) {
    if (preedit_area[i].char_len == 0) {
      UnmapPreeditWindow(ic, preedit_area + i);
      continue;
    }
    if (False == preedit_area[i].mapped) {
      XMapWindow(ic->core.im->core.display, preedit_area[i].window);
      preedit_area[i].mapped = True;
    }
  }
  for (i = preedit->active_areas; i < preedit->alloc_areas; i++) {
    UnmapPreeditWindow(ic, preedit_area + i);
  }
  if (preedit_chars->wchar_len == 0) {
    for (i = 0; i < preedit->active_areas; i++) {
      XClearArea(ic->core.im->core.display,
               preedit_area[i].window, 0, 0, 0, 0, False);
    }
  }
  if (start == 0 && len == 0) {
    UpdatePreeditAll(ic);
  } else if (ic->core.input_style & XIMPreeditArea &&
            (preedit_area[0].configured == True ||
             preedit_area[0].char_len !=
             preedit_area[0].char_len_backup)) {
    UpdatePreeditAll(ic);
  } else if (len > 0) {
    int x;
    unsigned int width;
    wchar_t *wcstr = preedit_chars->wchar;

    for (i = preedit->active_areas - 1; i >= 0; i--) {
      if (preedit_area[i].active_lines == 0) {
       int char_offset = preedit_area[i].char_offset;
       int char_len = preedit_area[i].char_len;
       int start_clear;
       int end_clear;

       if (True == preedit_area[i].configured) {
         start_clear = char_offset;
         end_clear = start_clear + char_len;
         width = XwcTextEscapement(preedit->fontset,
                                wcstr + start_clear, char_len);
         x = 0;
         preedit_area[i].configured = False;

       } else {
         if (char_offset + char_len < start) continue;
         if (char_offset > start + len) continue;

         start_clear = start > char_offset ? start : char_offset;
         if ((True == XIC_GUI(ic, preedit)->discard_expose_event) &&
             ((start + len) <= (char_offset + char_len))) {
           end_clear = (char_offset + char_len);
         } else {
           end_clear = (((start + len) < (char_offset + char_len)) ?
                      (start + len) : (char_offset + char_len));
         }

         if ((start + len) < (char_offset + char_len)) {
           width = XwcTextEscapement(preedit->fontset, wcstr + start_clear,
                                  end_clear - start_clear);
         } else {
           width = 0;
         }
         if (0 < (start_clear - char_offset)) {
           x = XwcTextEscapement(preedit->fontset, wcstr + char_offset,
                              start_clear - char_offset);
         } else {
           x = 0;
         }
       }

       TRACE_MESSAGE('p', ("UpdatePreedit: "
                         "len=%d start=%d end=%d "
                         "char_offset=%d char_len=%d x=%d width=%d "
                         "area[%d].x=%d, area[%d].y=%d "
                         "\n",
                         len, start_clear, end_clear,
                         char_offset, char_len, x, width,
                         i, preedit_area[i].x, i, preedit_area[i].y));
       if ((preedit_chars->wchar[0]) && (0 < (end_clear - start_clear))) {
         XClearArea(ic->core.im->core.display,
                   preedit_area[i].window,
                   preedit_area[i].x + x, preedit_area[i].y,
                   width, 0, False);
         DrawPreeditString(ic,
                         ic->core.im->core.display,
                         preedit_area[i].window,
                         preedit->fontset,
                         preedit->gc, preedit->rgc,
                         preedit_area[i].x + x, preedit_area[i].y,
                         preedit_chars->feedback,
                         preedit_chars->feedback_list,
                         preedit_chars->wchar,
                         start_clear, end_clear - start_clear);
       }
      } else {
       PreeditLine line = (PreeditLine)preedit_area[i].lines;
       int j;
       XClearArea(ic->core.im->core.display,
                 preedit_area[i].window, 0, 0, 0, 0, False);
       for (j = 0; j < preedit_area[i].active_lines; j++) {    
         DrawPreeditString(ic,
                         ic->core.im->core.display,
                         preedit_area[i].window,
                         preedit->fontset,
                         preedit->gc, preedit->rgc,
                         line[j].x,
                         line[j].y,
                         preedit_chars->feedback,
                         preedit_chars->feedback_list,
                         preedit_chars->wchar,
                         line[j].char_offset,
                         line[j].char_len);
       }
      }
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void UpdatePreeditAll ( XicCommon  ic) [static]

Definition at line 187 of file guiIMPre.c.

                               {
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);
  PreeditArea preedit_area = preedit->preedit_areas;
  PreeditChars preedit_chars = (PreeditChars)&(preedit->preedit_chars);
  int i;

  if (preedit_chars->wchar == 0) return;

  /* Draw All Preedit Text */
  for (i = 0; i < preedit->active_areas; i++) {
    if (ic->core.input_style & XIMPreeditArea) {
      XClearArea(ic->core.im->core.display,
               preedit_area[i].window, 0, 0, 0, 0, False);
    }
    if (preedit_area[i].active_lines == 0) {
      DrawPreeditString(ic,
                     ic->core.im->core.display,
                     preedit_area[i].window,
                     preedit->fontset,
                     preedit->gc, preedit->rgc,
                     preedit_area[i].x,
                     preedit_area[i].y,
                     preedit_chars->feedback,
                     preedit_chars->feedback_list,
                     preedit_chars->wchar,
                     preedit_area[i].char_offset,
                     preedit_area[i].char_len);
    } else {
      int j;
      PreeditLine line = (PreeditLine)preedit_area[i].lines;
      for (j = 0; j < preedit_area[i].active_lines; j++) {
       DrawPreeditString(ic,
                       ic->core.im->core.display,
                       preedit_area[i].window,
                       preedit->fontset,
                       preedit->gc, preedit->rgc,
                       line[j].x,
                       line[j].y,
                       preedit_chars->feedback,
                       preedit_chars->feedback_list,
                       preedit_chars->wchar,
                       line[j].char_offset,
                       line[j].char_len);
      }
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void UpdatePreeditWidth ( XicCommon  ic) [static]

Definition at line 734 of file guiIMPre.c.

                                 {
  PreeditWin preedit = (PreeditWin)(ic->gui_icpart->preedit);
  PreeditChars preedit_chars;
  int i;
  int text_length;
  wchar_t *wc_p;

  preedit_chars = &(preedit->preedit_chars);
  text_length = preedit_chars->wchar_len;

  for (wc_p = preedit_chars->wchar, i = 0; i < text_length; i++) {
    *(preedit_chars->wchar_width + i) =
      XwcTextEscapement(preedit->fontset, wc_p + i, 1);
  }
  UpdatePreedit(ic, 0, text_length);
}

Here is the call graph for this function:

Here is the caller graph for this function: