/* * $Id: display.c,v 1.2 2001/06/14 18:16:14 ura Exp $ */ /* * FreeWnn is a network-extensible Kana-to-Kanji conversion system. * This file is part of FreeWnn. * * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999 * Copyright 1991, 1992 by Massachusetts Institute of Technology * * Author: OMRON SOFTWARE Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Emacs; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Commentary: * * Change log: * * Last modified date: 8,Feb.1999 * * Code: * */ /* Version 4.0 */ #include #include "commonhd.h" #include "sdefine.h" #include "xim.h" #include "sheader.h" #include "ext.h" extern wchar_t dol_wchar_t; wchar cursor_wchar = 0x20202020; GC currentGC; static void JWwindow_move (xl) register XIMLangRec *xl; { if ((check_mb (xl->buf, xl->vst)) == 2) { xl->vst++; } XMoveWindow (dpy, xl->w[0], -(xl->vst * FontWidth (xl)), 0); if (IsPreeditPosition (cur_x)) { XMoveWindow (dpy, xl->w[1], -((cur_x->c0 + xl->vst - xl->linefeed[1]) * FontWidth (xl)), 0); XMoveWindow (dpy, xl->w[2], -((c01 (cur_x) + xl->vst - xl->linefeed[2]) * FontWidth (xl)), 0); } XFlush (dpy); } static void JWM_note (which) int which; { register XIMLangRec *xl; register XIMClientRec *xc = cur_p; int x, y; xl = cur_p->cur_xl; if (xl->note[which]) return; if (IsPreeditNothing (cur_x) || IsPreeditArea (cur_x)) { XClearWindow (dpy, xl->wn[which]); XMapWindow (dpy, xl->wn[which]); XRaiseWindow (dpy, xl->wn[which]); XwcDrawString (dpy, xl->wn[which], xl->pe_fs, xc->pe.gc, 0, FontAscent (xl), &dol_wchar_t, 1); } else if (IsPreeditPosition (cur_x)) { if (which == 1) { if (xc->c2) { x = PreeditX (xc) + (xc->c2 * FontWidth (xl)); y = PreeditSpotY (xc) + (FontHeight (xl) + xc->pe.line_space) * 2; if ((int) (y + FontHeight (xl)) > (int) (PreeditY (xc) + PreeditHeight (xc))) { if ((int) (y - xc->pe.line_space) > (int) (PreeditY (xc) + PreeditHeight (xc))) { y = PreeditY (xc) + FontHeight (xl) + xc->pe.line_space; } else { y = PreeditY (xc); } } } else if (xc->c1) { x = PreeditX (xc) + (xc->c1 * FontWidth (xl)); y = PreeditSpotY (xc) + FontHeight (xl) + xc->pe.line_space; if ((int) (y + FontHeight (xl)) > (int) (PreeditY (xc) + PreeditHeight (xc))) { y = PreeditY (xc); } } else { x = PreeditSpotX (xc) + xc->c0 * FontWidth (xl); y = PreeditSpotY (xc); } } else { x = PreeditSpotX (xc) - FontWidth (xl); y = PreeditSpotY (xc); } XMoveWindow (dpy, xl->wn[which], x, y); XClearWindow (dpy, xl->wn[which]); XMapWindow (dpy, xl->wn[which]); XRaiseWindow (dpy, xl->wn[which]); XwcDrawString (dpy, xl->wn[which], xl->pe_fs, xc->pe.gc, 0, FontAscent (xl), &dol_wchar_t, 1); } XFlush (dpy); } static void JWM_note_null () { register XIMLangRec *xl; register XIMClientRec *xc = cur_p; int x, y; xl = cur_p->cur_xl; if (xl->visible_line > 2) { x = PreeditX (xc) + ((xc->c2 - 1) * FontWidth (xl)); y = PreeditSpotY (xc) + (FontHeight (xl) + xc->pe.line_space) * 2; if ((int) (y + FontHeight (xl)) > (int) (PreeditY (xc) + PreeditHeight (xc))) if ((int) (y - xc->pe.line_space) > (int) (PreeditY (xc) + PreeditHeight (xc))) { y = PreeditY (xc) + FontHeight (xl) + xc->pe.line_space; } else { y = PreeditY (xc); } } else if (xl->visible_line > 1) { x = PreeditX (xc) + ((xc->c1 - 1) * FontWidth (xl)); y = PreeditSpotY (xc) + FontHeight (xl) + xc->pe.line_space; if ((int) (y + FontHeight (xl)) > (int) (PreeditY (xc) + PreeditHeight (xc))) y = PreeditY (xc); } else { x = PreeditSpotX (xc) + (xc->c0 - 1) * FontWidth (xl); y = PreeditSpotY (xc); } XMoveWindow (dpy, xl->wn[2], x, y); XMapWindow (dpy, xl->wn[2]); XRaiseWindow (dpy, xl->wn[2]); XFlush (dpy); } static void invisual_note (which) int which; { register XIMLangRec *xl; xl = cur_p->cur_xl; if (xl->note[which]) { XUnmapWindow (dpy, xl->wn[which]); XFlush (dpy); } } static void visible_line2 () { register XIMLangRec *xl; register XIMClientRec *xc = cur_p; int x, y, width; xl = cur_p->cur_xl; if ((xc->c1 == 0) || !IsPreeditPosition (cur_x)) return; x = PreeditX (xc); y = PreeditSpotY (xc) + FontHeight (xl) + xc->pe.line_space; if ((int) (y + FontHeight (xl)) > (int) (PreeditY (xc) + PreeditHeight (xc))) y = PreeditY (xc); if (xl->max_cur > (xc->c0 + xc->c1)) { width = xc->c1 * FontWidth (xl); } else { width = (xl->max_cur - xc->c0 + xl->linefeed[1]) * FontWidth (xl); } if (width == 0) width = 1; XMoveResizeWindow (dpy, xl->wp[1], x, y, width, FontHeight (xl)); XMoveWindow (dpy, xl->w[1], -((xc->c0 + xl->vst - xl->linefeed[1]) * FontWidth (xl)), 0); XMapWindow (dpy, xl->wp[1]); XRaiseWindow (dpy, xl->wp[1]); XFlush (dpy); } static void visible_line3 () { register XIMLangRec *xl; register XIMClientRec *xc = cur_p; int x, y, width; xl = cur_p->cur_xl; if ((xc->c2 == 0) || !IsPreeditPosition (cur_x)) return; x = PreeditX (xc); y = PreeditSpotY (xc) + (FontHeight (xl) + xc->pe.line_space) * 2; if ((int) (y + FontHeight (xl)) > (int) (PreeditY (xc) + PreeditHeight (xc))) { if ((int) (y - xc->pe.line_space) > (int) (PreeditY (xc) + PreeditHeight (xc))) { y = PreeditY (xc) + FontHeight (xl) + xc->pe.line_space; } else { y = PreeditY (xc); } } if (xl->max_cur > c012 (xc)) { width = xc->c2 * FontWidth (xl); } else { width = (xl->max_cur - c01 (xc) + xl->linefeed[2]) * FontWidth (xl); } if (width == 0) width = 1; XMoveResizeWindow (dpy, xl->wp[2], x, y, width, FontHeight (xl)); XMoveWindow (dpy, xl->w[2], -((c01 (xc) + xl->vst - xl->linefeed[2]) * FontWidth (xl)), 0); XMapWindow (dpy, xl->wp[2]); XRaiseWindow (dpy, xl->wp[2]); XFlush (dpy); } static void check_move1 (xc, xl, mb) register XIMClientRec *xc; register XIMLangRec *xl; int mb; { register int currentcol_tmp; int max_pos_tmp; currentcol_tmp = xl->currentcol + xl->linefeed[(xl->visible_line ? (xl->visible_line - 1) : 0)]; if ((currentcol_tmp - xl->vst + mb) >= xc->max_columns) { do { xl->vst = currentcol_tmp - xc->max_columns + mb + 1; if ((check_mb (xl->buf, xl->vst)) == 2) { xl->vst++; } currentcol_tmp = xl->currentcol; if (xl->visible_line > 1 && xc->c1) { if ((check_mb (xl->buf, (xc->c0 + xl->vst - 1))) == 1) { xl->linefeed[1] = 1; } else { xl->linefeed[1] = 0; } currentcol_tmp = xl->currentcol + xl->linefeed[1]; } if (xl->visible_line > 2 && xc->c2) { if ((check_mb (xl->buf, (c01 (xc) + xl->vst - xl->linefeed[1] - 1))) == 1) { xl->linefeed[2] = xl->linefeed[1] + 1; } else { xl->linefeed[2] = xl->linefeed[1]; } currentcol_tmp = xl->currentcol + xl->linefeed[2]; } } while ((currentcol_tmp - xl->vst + mb) >= xc->max_columns); JWwindow_move (xl); } else if (xl->currentcol < xl->vst) { xl->vst = xl->currentcol; if (xc->c1 && ((xl->visible_line > 1) || (xl->vst + xc->c0 < xl->max_pos))) { if ((check_mb (xl->buf, (xc->c0 + xl->vst - 1))) == 1) { xl->linefeed[1] = 1; } else { xl->linefeed[1] = 0; } if (xl->visible_line < 2 && (xl->vst + xc->c0 < xl->max_pos)) { visible_line2 (); xl->visible_line = 2; } } if (xc->c2 && ((xl->visible_line > 2) || ((c01 (xc) + xl->vst - xl->linefeed[1]) < xl->max_pos))) { if ((check_mb (xl->buf, (c01 (xc) + xl->vst - xl->linefeed[1] - 1))) == 1) { xl->linefeed[2] = xl->linefeed[1] + 1; } else { xl->linefeed[2] = xl->linefeed[1]; } if (xl->visible_line < 3 && (c01 (xc) + xl->vst - xl->linefeed[1] < xl->max_pos)) { visible_line3 (); xl->visible_line = 3; } } JWwindow_move (xl); } if (xl->vst) { if (!xl->note[0]) { JWM_note (0); xl->note[0] = 1; } } else { if (xl->note[0]) { invisual_note (0); xl->note[0] = 0; } } max_pos_tmp = xl->vst + xc->max_columns - xl->linefeed[(xl->visible_line ? (xl->visible_line - 1) : 0)]; if (xl->max_pos > max_pos_tmp) { if (!xl->note[1]) { JWM_note (1); xl->note[1] = 1; } if ((check_mb (xl->buf, (max_pos_tmp - 1))) == 1) { JWM_note_null (); } else { XUnmapWindow (dpy, xl->wn[2]); } } else { if (xl->note[1]) { invisual_note (1); xl->note[1] = 0; } XUnmapWindow (dpy, xl->wn[2]); } } static void check_move (xc, xl, mb) register XIMClientRec *xc; register XIMLangRec *xl; int mb; { if (IsPreeditPosition (cur_x)) { check_move1 (xc, xl, mb); } else { if ((xl->currentcol - xl->vst + mb) >= xc->max_columns) { xl->vst = xl->currentcol - xc->max_columns + mb + 1; JWwindow_move (xl); } else if (xl->currentcol < xl->vst) { xl->vst = xl->currentcol; JWwindow_move (xl); } if (xl->vst) { JWM_note (0); xl->note[0] = 1; } else { invisual_note (0); xl->note[0] = 0; } if (xl->max_pos > (xl->vst + xc->max_columns)) { JWM_note (1); xl->note[1] = 1; if ((check_mb (xl->buf, (xl->vst + xc->max_columns - 1))) == 1) { XMapWindow (dpy, xl->wn[2]); } else { XUnmapWindow (dpy, xl->wn[2]); } } else { invisual_note (1); xl->note[1] = 0; XUnmapWindow (dpy, xl->wn[2]); } } } static void Resize_jw () { register XIMLangRec *xl; Window window; int width = 0; char ok = '\0'; xl = cur_p->cur_xl; if (!IsPreeditPosition (cur_x) || !xl->m_cur_flag) return; if (cur_p->c2) { if (xl->max_cur <= (c012 (cur_p) - xl->linefeed[2])) { width = (xl->max_cur - c01 (cur_p) + xl->linefeed[2]); xl->max_l3 = 0; ok = 1; } else if (!xl->max_l3) { width = cur_p->c2; xl->max_l3 = 1; ok = 1; } if (ok) { window = xl->wp[2]; XResizeWindow (dpy, window, (width * FontWidth (xl)), FontHeight (xl)); } } if (cur_p->c1) { ok = '\0'; if (xl->max_cur <= (c01 (cur_p) - xl->linefeed[1])) { width = (xl->max_cur - cur_p->c0 + xl->linefeed[1]); xl->max_l2 = 0; ok = 1; } else if (!xl->max_l2) { width = cur_p->c1; xl->max_l2 = 1; ok = 1; } if (ok) { window = xl->wp[1]; XResizeWindow (dpy, window, (width * FontWidth (xl)), FontHeight (xl)); } } if (cur_p->c0) { ok = '\0'; if (xl->max_cur <= cur_p->c0) { width = xl->max_cur; xl->max_l1 = 0; ok = 1; } else if (!xl->max_l1) { width = cur_p->c0; xl->max_l1 = 1; ok = 1; } if (ok) { window = xl->wp[0]; XResizeWindow (dpy, window, (width * FontWidth (xl)), FontHeight (xl)); } } XFlush (dpy); xl->m_cur_flag = 0; } void JWmark_cursor (on) int on; { register XIMLangRec *xl; register XIMClientRec *xc = cur_p; wchar *JW_buf; unsigned char *JW_att; Window currentW = 0; int mb_len; unsigned char flg; XCharStruct cs; xl = cur_p->cur_xl; if (xl->cursor_flag != 1 || xl->mark_flag == on) return; xl->mark_flag = on; JW_buf = xl->buf + xl->currentcol; JW_att = xl->att + xl->currentcol; cs.width = FontWidth (xl); cs.ascent = FontAscent (xl); cs.descent = FontDescent (xl); if ((*JW_att & REV_FLAG) != 0) return; if (*JW_buf) { if ((mb_len = get_columns_wchar (JW_buf)) > 0) { JW_buf += (mb_len - 1); JW_att += (mb_len - 1); } flg = *JW_att; } else { JW_buf = &cursor_wchar; JW_att = '\0'; mb_len = 1; flg = 0; } if (on) { if (mb_len > 1) { check_move (xc, xl, 1); } else { check_move (xc, xl, 0); } currentGC = xc->pe.reversegc; flg |= REV_FLAG; } else { currentGC = xc->pe.gc; } if (IsPreeditNothing (cur_x) || IsPreeditArea (cur_x)) { currentW = xl->w[0]; } else if (IsPreeditPosition (cur_x)) { if ((xl->currentcol + mb_len - xl->vst) <= xc->c0) { currentW = xl->w[0]; } else if ((xl->currentcol + xl->linefeed[1] + mb_len - xl->vst) <= c01 (xc)) { currentW = xl->w[1]; } else { currentW = xl->w[2]; } if ((*(xl->buf + xl->currentcol) == 0) && on) { if (xc->c1 && ((xl->currentcol - xl->vst) == xc->c0)) { xl->linefeed[1] = 0; visible_line2 (); if (xl->visible_line < 2) { xl->visible_line = 2; } } if (xc->c2 && ((xl->currentcol + xl->linefeed[1] - xl->vst) == c01 (xc))) { xl->linefeed[2] = xl->linefeed[1]; visible_line3 (); if (xl->visible_line < 3) { xl->visible_line = 3; } } if ((xl->currentcol - xl->vst) >= xl->max_cur) { xl->max_cur += 1; xl->m_cur_flag = 1; Resize_jw (); } } if (on) { if ((xl->max_pos - xl->vst) > xl->max_cur && !xl->m_cur_flag) { xl->max_cur = xl->max_pos - xl->vst; xl->m_cur_flag = 1; Resize_jw (); } } } JWOutput (currentW, xl->pe_fs, currentGC, xl->currentcol, mb_len, flg, 0, 0, &cs, JW_buf, 1); XFlush (dpy); } void redraw_window3 (x, width) int x, width; { register XIMLangRec *xl; wchar *JW_buf, *wc; unsigned char *JW_att; unsigned char old_JW_att; int currentcol_tmp = 0; int start, end, startcol; int wc_len, mb_len; int col; XCharStruct cs; Bool error = False; if (IsPreeditNothing (cur_x)) { xl = cur_x->root_pointer->ximclient->cur_xl; } else if (IsPreeditArea (cur_x)) { xl = cur_p->cur_xl; } else { return; } currentcol_tmp = xl->currentcol; start = x / FontWidth (xl); end = start + width / FontWidth (xl) + ((width % FontWidth (xl)) ? 1 : 0); if (end > xl->max_pos) end = xl->max_pos; if (check_mb (xl->buf, (start)) == 2) start--; if (check_mb (xl->buf, (end - 1)) == 1) end++; JW_buf = xl->buf + start; JW_att = xl->att + start; old_JW_att = *JW_att; while (wc_buf_max < (end - start)) { if (realloc_wc_buf () < 0) return; } wc = wc_buf; skip_pending_wchar (wc, JW_buf); wc_len = 0; col = 0; startcol = start; cs.width = FontWidth (xl); cs.ascent = FontAscent (xl); cs.descent = FontDescent (xl); for (xl->currentcol = start; xl->currentcol < end;) { JW_buf = xl->buf + xl->currentcol; JW_att = xl->att + xl->currentcol; if ((mb_len = get_columns_wchar (JW_buf)) > 0) { JW_buf += (mb_len - 1); JW_att += (mb_len - 1); } else { error = True; } if (((error == True) || (*JW_att != old_JW_att)) && (wc_len > 0)) { if (old_JW_att & REV_FLAG) { currentGC = cur_p->pe.reversegc; } else { currentGC = cur_p->pe.gc; } JWOutput (xl->w[0], xl->pe_fs, currentGC, startcol, col, old_JW_att, 0, 0, &cs, wc, wc_len); old_JW_att = *JW_att; wc += wc_len; wc_len = 0; col = 0; startcol = xl->currentcol; } if (error == True) { wc_len = 0; col += 1; xl->currentcol += 1; error = False; } else { wc_len++; col += mb_len; xl->currentcol += mb_len; } } if (wc_len > 0) { if (old_JW_att & REV_FLAG) { currentGC = cur_p->pe.reversegc; } else { currentGC = cur_p->pe.gc; } JWOutput (xl->w[0], xl->pe_fs, currentGC, startcol, col, old_JW_att, 0, 0, &cs, wc, wc_len); } xl->currentcol = currentcol_tmp; JW_buf = xl->buf + xl->currentcol; JW_att = xl->att + xl->currentcol; if (*JW_att & REV_FLAG) { for (; *JW_buf && (*JW_att & REV_FLAG); JW_buf++, JW_att++, xl->currentcol++); if (get_columns_wchar (JW_buf)) { check_move (cur_p, xl, 1); } else { check_move (cur_p, xl, 0); } } xl->currentcol = currentcol_tmp; if (xl->cursor_flag == 1 && xl->mark_flag == 1) { xl->mark_flag = 0; JWmark_cursor (1); } } void redraw_lines (x, width, line) int x, width, line; { register XIMLangRec *xl; register XIMClientRec *xc = cur_p; register wchar *JW_buf, *wc; unsigned char *JW_att; unsigned char old_JW_att; int currentcol_tmp = 0; int start, end, startcol; int tmp_col = 0; int wc_len, mb_len; int col; XCharStruct cs; Bool error = False; xl = cur_p->cur_xl; currentcol_tmp = xl->currentcol; if (line == 1) { tmp_col = xc->c0; } else if (line == 2) { tmp_col = c01 (xc) - xl->linefeed[1]; } start = x / FontWidth (xl); end = start + width / FontWidth (xl) + ((width % FontWidth (xl)) ? 1 : 0); if (end > xl->max_pos) end = xl->max_pos; if (check_mb (xl->buf, (start)) == 2 && start > 0) start--; if (check_mb (xl->buf, (end - 1)) == 1) end++; JW_buf = xl->buf + start; JW_att = xl->att + start; old_JW_att = *JW_att; while (wc_buf_max < (end - start)) { if (realloc_wc_buf () < 0) return; } wc = wc_buf; wc_len = 0; skip_pending_wchar (wc, JW_buf); col = 0; startcol = start; cs.width = FontWidth (xl); cs.ascent = FontAscent (xl); cs.descent = FontDescent (xl); for (xl->currentcol = start; xl->currentcol < end;) { JW_buf = xl->buf + xl->currentcol; JW_att = xl->att + xl->currentcol; if ((mb_len = get_columns_wchar (JW_buf)) > 0) { JW_buf += (mb_len - 1); JW_att += (mb_len - 1); } else { error = True; } if (((error == True) || (*JW_att != old_JW_att)) && (wc_len > 0)) { if (old_JW_att & REV_FLAG) { currentGC = cur_p->pe.reversegc; } else { currentGC = cur_p->pe.gc; } JWOutput (xl->w[line - 1], xl->pe_fs, currentGC, startcol, col, old_JW_att, 0, 0, &cs, wc, wc_len); old_JW_att = *JW_att; wc += wc_len; wc_len = 0; col = 0; startcol = xl->currentcol; } if (error == True) { wc_len = 0; col += 1; xl->currentcol += 1; } else { wc_len++; col += mb_len; xl->currentcol += mb_len; } if (*JW_att & REV_FLAG) { if (mb_len) { check_move (cur_p, xl, 1); } else { check_move (cur_p, xl, 0); } } if (line != 3) { if (mb_len > 1) { if (xl->currentcol > (tmp_col + xl->vst - 2)) { if ((line == 1 && xc->c1) || (line == 2 && xc->c2)) { if (check_mb (xl->buf, (tmp_col + xl->vst - 1)) == 1) { xl->linefeed[line] = xl->linefeed[line - 1] + 1; } else { xl->linefeed[line] = xl->linefeed[line - 1]; } } break; } } else { if (xl->currentcol > (tmp_col + xl->vst - 1)) { if ((line == 1 && xc->c1) || (line == 2 && xc->c2)) { xl->linefeed[line] = xl->linefeed[line - 1]; } break; } } } } if (wc_len > 0) { if (old_JW_att & REV_FLAG) { currentGC = cur_p->pe.reversegc; } else { currentGC = cur_p->pe.gc; } JWOutput (xl->w[line - 1], xl->pe_fs, currentGC, startcol, col, old_JW_att, 0, 0, &cs, wc, wc_len); } xl->currentcol = currentcol_tmp; if (line == 1) { if (xl->linefeed[line]) { XClearArea (dpy, xl->w[line - 1], (xc->c0 + xl->vst - 1) * FontWidth (xl), 0, 0, 0, False); } if (xl->cursor_flag && xl->mark_flag && (xl->currentcol < (xc->c0 + xl->vst))) { xl->mark_flag = 0; JWmark_cursor (1); } } else if (line == 2) { if (xl->linefeed[line]) { XClearArea (dpy, xl->w[line - 1], ((c01 (xc) + xl->vst + xl->linefeed[1] - 1) * FontWidth (xl)), 0, 0, 0, False); } if (xl->cursor_flag && xl->mark_flag && (xl->currentcol < (tmp_col + xl->vst)) && (xl->currentcol >= (xc->c0 + xl->vst - xl->linefeed[1]))) { xl->mark_flag = 0; JWmark_cursor (1); } } else { if (xl->cursor_flag && xl->mark_flag && (xl->currentcol >= (tmp_col + xl->vst))) { xl->mark_flag = 0; JWmark_cursor (1); } } } void redraw_note (which) int which; { XIMLangRec *xl = cur_p->cur_xl; XClearWindow (dpy, xl->wn[which]); XwcDrawString (dpy, xl->wn[which], xl->pe_fs, cur_p->pe.gc, 0, FontAscent (xl), &dol_wchar_t, 1); XFlush (dpy); } void redraw_window0 () { register XIMLangRec *xl; wchar *JW_buf, *wc; int wc_len; int col = 0; int mb_len; unsigned char flg; XCharStruct cs; xl = cur_p->cur_xl; JW_buf = xl->buf0; flg = xl->att0[0]; cs.width = StatusFontWidth (xl); cs.ascent = StatusFontAscent (xl); cs.descent = StatusFontDescent (xl); for (; *JW_buf; JW_buf++) { mb_len = get_columns_wchar (JW_buf); JW_buf += (mb_len - 1); col += mb_len; } while (wc_buf_max < col) { if (realloc_wc_buf () < 0) return; } wc = wc_buf; wc_len = skip_pending_wchar (wc, xl->buf0); if (wc_len <= 0) return; JWOutput (xl->ws, xl->st_fs, ((flg & REV_FLAG) ? cur_p->st.reversegc : cur_p->st.gc), 0, col, flg, 0, 0, &cs, wc, wc_len); } void redraw_xj_all () { register XIMLangRec *xl; xl = cur_p->cur_xl; redraw_window0 (); if (IsPreeditNothing (cur_x) || IsPreeditArea (cur_x)) { redraw_window3 (0, xl->max_pos * FontWidth (xl)); } else if (IsPreeditPosition (cur_x)) { redraw_lines (xl->vst * FontWidth (xl), xl->max_pos * FontWidth (xl), 1); redraw_lines ((xl->vst + cur_p->c0 - xl->linefeed[1]) * FontWidth (xl), xl->max_pos * FontWidth (xl), 2); redraw_lines ((xl->vst + c01 (cur_p) - xl->linefeed[2]) * FontWidth (xl), xl->max_pos * FontWidth (xl), 3); } if (xl->note[0] != 0) JWM_note (0); if (xl->note[1] != 0) JWM_note (1); } static void visual_window3 () { register XIMLangRec *xl; xl = cur_p->cur_xl; XMapWindow (dpy, xl->wp[0]); XMapWindow (dpy, xl->w[0]); /* Need not this, because window3 is redraw by exposure callback. if (xl->max_pos) { redraw_window3(0, xl->max_pos * FontWidth(xl)); } */ if (IsPreeditNothing (cur_x)) { xl->visible = 3; } else { xl->visible = 1; xl->visible_line = 1; } if (xl->vst) { JWM_note (0); xl->note[0] = 1; } if (xl->max_pos > (xl->vst + cur_p->max_columns)) { JWM_note (1); xl->note[1] = 1; if ((check_mb (xl->buf, (xl->vst + cur_p->max_columns - 1))) == 1) { XMapWindow (dpy, xl->wn[2]); } else { XUnmapWindow (dpy, xl->wn[2]); } } } void visual_window1 () { int width; register int w_width; register XIMLangRec *xl; int max_pos_tmp; register XIMClientRec *xc = cur_p; xl = cur_p->cur_xl; if (xl->visible) return; if (IsPreeditPosition (cur_x)) { w_width = (int) PreeditWidth (xc) / (int) FontWidth (xl); xc->max_columns = ((int) PreeditWidth (xc) / (int) FontWidth (xl)); if (xc->max_columns <= 0) xc->max_columns = 1; xc->c0 = (int) (PreeditWidth (xc) + PreeditX (xc) - PreeditSpotX (xc)) / (int) FontWidth (xl); if (xc->c0 < 0) xc->c0 = 0; if (xc->c0 >= xc->max_columns) { xc->c0 = xc->max_columns; xc->c1 = xc->c2 = 0; } else if ((xc->c1 = xc->max_columns - xc->c0) > w_width) { xc->c1 = w_width; xc->c2 = xc->max_columns - xc->c0 - xc->c1; } else { xc->c2 = 0; } xl->max_cur = xl->max_pos - xl->vst; if (xl->max_cur > xc->c0) { width = xc->c0 * FontWidth (xl); } else { width = xl->max_cur * FontWidth (xl); } if (width == 0) width = 1; XMoveResizeWindow (dpy, xl->wp[0], PreeditSpotX (xc), PreeditSpotY (xc), width, FontHeight (xl)); XMoveWindow (dpy, xl->w[0], -(xl->vst * FontWidth (xl)), 0); XFlush (dpy); } if (xl->visible_line == 0) xl->visible_line = 1; XMapWindow (dpy, xl->wp[0]); XRaiseWindow (dpy, xl->wp[0]); XFlush (dpy); if (xc->c1 && (xl->max_pos >= xc->c0) && (xl->buf[xc->c0] != 0)) { if (check_mb (xl->buf, (xc->c0 - 1)) == 1) { xl->linefeed[1] = 1; } else { xl->linefeed[1] = 0; } visible_line2 (); if (xl->visible_line < 2) xl->visible_line = 2; } if (xc->c2 && (xl->max_pos > (c01 (xc) - 1 - xl->linefeed[1]))) { if (check_mb (xl->buf, (c01 (xc) - 1 - xl->linefeed[1])) == 1) { xl->linefeed[2] = xl->linefeed[1] + 1; } else { xl->linefeed[2] = xl->linefeed[1]; } visible_line3 (); if (xl->visible_line < 3) xl->visible_line = 3; } if (xl->vst) { if (!xl->note[0]) { JWM_note (0); xl->note[0] = 1; } } else { if (!xl->note[1]) { invisual_note (0); xl->note[0] = 0; } } max_pos_tmp = xl->vst + xc->max_columns - xl->linefeed[(xl->visible_line ? (xl->visible_line - 1) : 0)]; if (xl->max_pos > max_pos_tmp) { if (!xl->note[1]) { JWM_note (1); xl->note[1] = 1; } if ((check_mb (xl->buf, (max_pos_tmp - 1))) == 1) { JWM_note_null (); } else { XUnmapWindow (dpy, xl->wn[2]); } } else { if (xl->note[1]) { invisual_note (1); xl->note[1] = 0; } XUnmapWindow (dpy, xl->wn[2]); } xl->visible = 1; } #ifdef CALLBACKS static void visual_window_cb () { register XIMLangRec *xl; xl = cur_p->cur_xl; if (xl->visible == 0) { CBPreeditStart (); if (xl->max_pos) { CBPreeditRedraw (xl); } xl->visible = 1; } } #endif /* CALLBACKS */ void visual_window () { if (cur_p->cur_xl->visible) return; if (IsPreeditNothing (cur_x) || IsPreeditArea (cur_x)) { visual_window3 (); } else if (IsPreeditPosition (cur_x)) { visual_window1 (); #ifdef CALLBACKS } else if (IsPreeditCallbacks (cur_x)) { visual_window_cb (); #endif /* CALLBACKS */ } XFlush (dpy); } static void invisual_line2 () { XUnmapWindow (dpy, cur_p->cur_xl->wp[1]); XFlush (dpy); } static void invisual_line3 () { XUnmapWindow (dpy, cur_p->cur_xl->wp[2]); XFlush (dpy); } static void invisual_window3 () { register XIMLangRec *xl; xl = cur_p->cur_xl; if (xl->note[0]) { XUnmapWindow (dpy, xl->wn[0]); xl->note[0] = 0; } if (xl->note[1]) { XUnmapWindow (dpy, xl->wn[1]); xl->note[1] = 0; } if (IsPreeditNothing (cur_x)) { xl->visible = 0; } else { xl->visible_line = 0; } xl->vst = 0; XClearWindow (dpy, xl->w[0]); XUnmapWindow (dpy, xl->wp[0]); JWwindow_move (xl); } void invisual_window1 () { register XIMLangRec *xl; xl = cur_p->cur_xl; XUnmapWindow (dpy, xl->wp[0]); invisual_line2 (); invisual_line3 (); xl->visible = 0; xl->visible_line = 0; xl->linefeed[0] = xl->linefeed[1] = xl->linefeed[2] = 0; if (xl->note[0]) { XUnmapWindow (dpy, xl->wn[0]); xl->note[0] = 0; } if (xl->note[1]) { XUnmapWindow (dpy, xl->wn[1]); xl->note[1] = 0; } XUnmapWindow (dpy, xl->wn[2]); } void invisual_window () { if (!cur_p->cur_xl->visible) return; if (IsPreeditNothing (cur_x) || IsPreeditArea (cur_x)) { invisual_window3 (); } else if (IsPreeditPosition (cur_x)) { invisual_window1 (); #ifdef CALLBACKS } else if (IsPreeditCallbacks (cur_x)) { CBPreeditDone (); #endif /* CALLBACKS */ } cur_p->cur_xl->visible = 0; XFlush (dpy); } static void JW0Mputwc (wc, wc_len, status) register wchar *wc; int wc_len; char status; /* 0: Preedit Window, 1: Status Window */ { register int cnt = wc_len; register XIMLangRec *xl; register XIMClientRec *xc = cur_p; register wchar *JW_buf, *p = wc; unsigned char *JW_att; int mb_len; short *cur_col, start_col = 0, end_col = 0; register unsigned char flg = 0; XCharStruct cs; if (cnt <= 0) return; xl = xc->cur_xl; if (status) { JW_buf = xl->buf0 + xl->currentcol0; JW_att = xl->att0 + xl->currentcol0; cs.width = StatusFontWidth (xl); cs.ascent = StatusFontAscent (xl); cs.descent = StatusFontDescent (xl); start_col = xl->currentcol0; cur_col = &xl->currentcol0; } else { visual_window (); if (xl->currentcol >= xc->maxcolumns) return; JW_buf = xl->buf + xl->currentcol; JW_att = xl->att + xl->currentcol; cs.width = FontWidth (xl); cs.ascent = FontAscent (xl); cs.descent = FontDescent (xl); start_col = xl->currentcol; cur_col = &xl->currentcol; } if (xl->r_flag) flg |= REV_FLAG; if (xl->b_flag) flg |= BOLD_FLAG; if (xl->u_line_flag) flg |= UNDER_FLAG; for (; cnt > 0; cnt--) { mb_len = put_pending_wchar_and_flg (*p++, JW_buf, JW_att, flg); JW_buf += mb_len; JW_att += mb_len; end_col += mb_len; if (flg & REV_FLAG) { if (mb_len) { check_move (xc, xl, 1); } else { check_move (xc, xl, 0); } } *cur_col += mb_len; } if (status) { JWOutput (xl->ws, xl->st_fs, ((flg & REV_FLAG) ? xc->st.reversegc : xc->st.gc), start_col, end_col, flg, 0, 0, &cs, wc, wc_len); } else { JWOutput (xl->w[0], xl->pe_fs, ((flg & REV_FLAG) ? xc->pe.reversegc : xc->pe.gc), start_col, end_col, flg, 0, 0, &cs, wc, wc_len); } } static void JWMputwc (wc, wc_len) register wchar *wc; int wc_len; { register int cnt = wc_len; register XIMLangRec *xl; register XIMClientRec *xc = cur_p; register wchar *JW_buf, *p = wc; unsigned char *JW_att; Window currentW = 0; int mb_len; short col = 0; register unsigned char flg = 0; XCharStruct cs; if (cnt <= 0) return; xl = xc->cur_xl; if (xl->currentcol >= xc->maxcolumns) return; if (xl->currentcol == 0 && xl->visible == 0) visual_window1 (); if (xl->r_flag) flg |= REV_FLAG; if (xl->b_flag) flg |= BOLD_FLAG; if (xl->u_line_flag) flg |= UNDER_FLAG; JW_buf = xl->buf + xl->currentcol; JW_att = xl->att + xl->currentcol; cs.width = FontWidth (xl); cs.ascent = FontAscent (xl); cs.descent = FontDescent (xl); for (; cnt > 0; cnt--) { mb_len = put_pending_wchar_and_flg (*p++, JW_buf, JW_att, flg); JW_buf += mb_len; JW_att += mb_len; col += mb_len; if (mb_len > 1) { if (((xl->currentcol + mb_len - xl->vst) > xc->c0) && ((xl->currentcol - xl->vst) <= xc->c0) && (xc->c1)) { xl->linefeed[1] = xc->c0 + xl->vst - xl->currentcol; if (xl->linefeed[1] == 1) XClearArea (dpy, xl->w[0], (xc->c0 + xl->vst - 1) * FontWidth (xl), 0, 0, 0, False); visible_line2 (); if (xl->visible_line < 2) xl->visible_line = 2; if (((xl->currentcol + mb_len + xl->linefeed[1] - xl->vst) > (xc->c0 + xc->c1)) && ((xl->currentcol + xl->linefeed[1] - xl->vst) <= (xc->c0 + xc->c1)) && (xc->c2)) { xl->linefeed[2] = xc->c0 + xc->c1 + xl->vst - xl->currentcol; if ((xl->linefeed[2] - xl->linefeed[1]) == 1) XClearArea (dpy, xl->w[1], ((xc->c0 + xc->c1 + xl->vst - xl->linefeed[2]) * FontWidth (xl)), 0, 0, 0, False); visible_line3 (); if (xl->visible_line < 3) xl->visible_line = 3; } } if (flg & REV_FLAG) { check_move (xc, xl, 1); } if ((xl->currentcol - xl->vst) <= (xc->c0 - 2)) { currentW = xl->w[0]; } else if ((xl->currentcol - xl->vst) <= (xc->c0 + xc->c1 - 2 - xl->linefeed[1])) { currentW = xl->w[1]; } else { currentW = xl->w[2]; } } else { if (((xl->currentcol - xl->vst) == xc->c0) && (xc->c1)) { xl->linefeed[1] = 0; visible_line2 (); if (xl->visible_line < 2) xl->visible_line = 2; if (((xl->currentcol + xl->linefeed[1] - xl->vst) == (xc->c0 + xc->c1)) && (xc->c2)) { xl->linefeed[2] = xl->linefeed[1]; visible_line3 (); if (xl->visible_line < 3) xl->visible_line = 3; } } if (flg & REV_FLAG) check_move (xc, xl, 0); if ((xl->currentcol - xl->vst) <= (xc->c0 - 1)) { currentW = xl->w[0]; } else if ((xl->currentcol - xl->vst) <= (xc->c0 + xc->c1 - 1 - xl->linefeed[1])) { currentW = xl->w[1]; } else { currentW = xl->w[2]; } } JWOutput (currentW, xl->pe_fs, ((flg & REV_FLAG) ? xc->pe.reversegc : xc->pe.gc), xl->currentcol, col, flg, 0, 0, &cs, wc, 1); if ((xl->currentcol + col - xl->vst) > xl->max_cur) { xl->max_cur = xl->currentcol + col - xl->vst; xl->m_cur_flag = 1; Resize_jw (); } xl->currentcol += col; col = 0; wc++; } return; } void JWMflushw_buf (w_buf, len) w_char *w_buf; int len; { XIMLangRec *xl = cur_p->cur_xl; int wc_len; if (len <= 0) return; while (1) { wc_len = w_char_to_wchar (xl->xlc, w_buf, wc_buf, len, wc_buf_max); if (wc_len < -1) { return; } else if (wc_len == -1) { if (realloc_wc_buf () < 0) return; } else { break; } } if (IsPreeditNothing (cur_x) || IsPreeditArea (cur_x)) { (void) JW0Mputwc (wc_buf, wc_len, 0); } else if (IsPreeditPosition (cur_x)) { (void) JWMputwc (wc_buf, wc_len); #ifdef CALLBACKS } else if (IsPreeditCallbacks (cur_x)) { (void) CBPreeditDraw (wc_buf, wc_len); #endif /* CALLBACKS */ } if (xl->currentcol > xl->max_pos) { xl->max_pos = xl->currentcol; } XFlush (dpy); } void jw_disp_mode (c) unsigned char *c; { XIMLangRec *xl = cur_p->cur_xl; int c_len; int wc_len; c_len = strlen ((char *) c); while (1) { wc_len = char_to_wchar (xl->xlc, c, wc_buf, c_len, wc_buf_max); if (wc_len < -1) { return; } else if (wc_len == -1) { if (realloc_wc_buf () < 0) return; } else { break; } } xl->currentcol0 = 0; if (IsStatusNothing (cur_x) || IsStatusArea (cur_x)) { JW0Mputwc (wc_buf, wc_len, 1); #ifdef CALLBACKS } else if (IsStatusCallbacks (cur_x)) { CBStatusDraw (wc_buf, wc_len); #endif /* CALLBACKS */ } if (xl->currentcol0 > xl->max_pos0) { xl->max_pos0 = xl->currentcol0; } return; } void JWMline_clear (x) register int x; { register XIMLangRec *xl; register int cnt; register wchar *JW_buf; unsigned char *JW_att; xl = cur_p->cur_xl; JW_buf = xl->buf + x; JW_att = xl->att + x; if (IsPreeditArea (cur_x) || IsPreeditNothing (cur_x)) { XClearArea (dpy, xl->w[0], x * FontWidth (xl), 0, (xl->max_pos - x) * FontWidth (xl) + 1, 0, False); if (x <= (xl->vst + cur_x->max_columns)) { invisual_note (1); xl->note[1] = 0; XUnmapWindow (dpy, xl->wn[2]); } if (x <= 0) { invisual_window (); } #ifdef CALLBACKS } else if (IsPreeditCallbacks (cur_x)) { if (x <= 0) { invisual_window (); } else { CBPreeditClear (x, xl->max_pos); } #endif /* CALLBACKS */ } else if (IsPreeditPosition (cur_x)) { xl->del_x = x; } for (cnt = x; cnt < xl->max_pos; cnt++) { *JW_buf++ = 0; *JW_att++ = 0; } xl->currentcol = x; xl->max_pos = x; XFlush (dpy); } void JWMline_clear1 () { register XIMLangRec *xl; register XIMClientRec *xc = cur_p; register int xx; xl = xc->cur_xl; xx = xl->del_x; if (xl->currentcol == xl->max_pos) xx++; if (xc->c2 && (((xx - xl->vst) <= (c01 (xc) - xl->linefeed[1])) || (xl->visible_line < 3))) { XUnmapWindow (dpy, xl->wp[2]); xl->visible_line = 2; } if (xc->c1 && (((xx - xl->vst) <= cur_p->c0) || (xl->visible_line < 2))) { XUnmapWindow (dpy, xl->wp[1]); xl->visible_line = 1; } xl->m_cur_flag = 1; if (xl->del_x <= 0) { invisual_window (); xl->visible_line = 0; xl->max_l1 = 0; xl->max_cur = 0; xl->m_cur_flag = 1; } xl->del_x = -1; xl->max_cur = xx - xl->vst; Resize_jw (); XFlush (dpy); } void visual_status () { register XIMLangRec *xl; xl = cur_p->cur_xl; #ifdef CALLBACKS if (IsStatusCallbacks (cur_x)) { CBStatusStart (); if (henkan_off_flag == 0) { disp_mode (); } else { display_henkan_off_mode (); } } else { #endif /* CALLBACKS */ XMapWindow (dpy, xl->ws); XRaiseWindow (dpy, xl->ws); #ifdef CALLBACKS } #endif /* CALLBACKS */ } void invisual_status () { register XIMLangRec *xl; xl = cur_p->cur_xl; #ifdef CALLBACKS if (IsStatusCallbacks (cur_x)) { CBStatusDone (); } else { #endif /* CALLBACKS */ XUnmapWindow (dpy, xl->ws); #ifdef CALLBACKS } #endif /* CALLBACKS */ } void JWcursor_visible () { cur_p->cur_xl->cursor_flag = 1; #ifdef CALLBACKS if (IsPreeditCallbacks (cur_x)) { CBCursorMark (1); } else { #endif /* CALLBACKS */ JWmark_cursor (1); #ifdef CALLBACKS } #endif /* CALLBACKS */ } void JWcursor_invisible () { #ifdef CALLBACKS if (IsPreeditCallbacks (cur_x)) { CBCursorMark (0); } else { #endif /* CALLBACKS */ JWmark_cursor (0); #ifdef CALLBACKS } #endif /* CALLBACKS */ cur_p->cur_xl->cursor_flag = 0; } void JWcursor_move (x) int x; { register XIMLangRec *xl; xl = cur_p->cur_xl; if ((xl->visible != 0) && (xl->max_pos > 0)) { visual_window (); } #ifdef CALLBACKS if (IsPreeditCallbacks (cur_x)) { if (xl->currentcol != x) { xl->currentcol = x; CBCursorMove (xl->currentcol); } } else { #endif /* CALLBACKS */ JWmark_cursor (0); xl->currentcol = x; if (x >= 0) JWmark_cursor (1); #ifdef CALLBACKS } #endif /* CALLBACKS */ if (IsPreeditPosition (cur_x) && xl->max_pos < xl->max_cur && xl->max_pos >= x) { xl->del_x = xl->max_pos; } } void check_scroll () { register XIMLangRec *xl = cur_p->cur_xl; register int mb; mb = check_mb (xl->buf, xl->currentcol); if ((xl->currentcol < xl->vst) || ((xl->currentcol + xl->linefeed[(xl->visible_line ? (xl->visible_line - 1) : 0)] - xl->vst - mb) >= cur_p->max_columns)) { if (mb == 1) { check_move (cur_p, xl, 1); } else { check_move (cur_p, xl, 0); } } } void visible_root () { register XIMClientRec *xc; register XIMRootRec *root = cur_x->root_pointer; XWMHints wm_hints; if (!root->root_visible) return; for (xc = ximclient_list; xc != NULL; xc = xc->next) { if (xc->root_pointer == root && IsPreeditNothing (xc)) break; } if (!root->root_visible_flag && xc && !root->ximclient->cur_xl->w_c->h_flag) { wm_hints.initial_state = NormalState; wm_hints.flags = StateHint; XSetWMHints (dpy, root->ximclient->w, &wm_hints); XMapWindow (dpy, root->ximclient->w); root->root_visible_flag = (char) 1; } } void invisible_root () { register XIMRootRec *root = cur_x->root_pointer; if (!root->root_visible) return; if (root->root_visible_flag) { XWithdrawWindow (dpy, root->ximclient->w, DefaultScreen (dpy)); root->root_visible_flag = (char) 0; } } void check_root_mapping (root) register XIMRootRec *root; { register XIMClientRec *xc; XWMHints wm_hints; if (!root->root_visible) return; for (xc = ximclient_list; xc != NULL; xc = xc->next) { if (xc->root_pointer == root && IsPreeditNothing (xc)) break; } if (root->root_visible_flag && !xc) { XWithdrawWindow (dpy, root->ximclient->w, DefaultScreen (dpy)); root->root_visible_flag = (char) 0; } else if (!root->root_visible_flag && xc && !root->ximclient->cur_xl->w_c->h_flag) { wm_hints.initial_state = NormalState; wm_hints.flags = StateHint; XSetWMHints (dpy, root->ximclient->w, &wm_hints); XMapWindow (dpy, root->ximclient->w); root->root_visible_flag = (char) 1; } }