Show pageOld revisionsBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ====== Input method in FreeBSD virtual terminal (Week9 & 10) ====== Date: 08/02 ~ 08/15 ===== Progress ===== During these two weeks, I have almost done the part of the display of the status bar. The general ''%%vt%%'' display process begins with the one of ''%%vt%%'' hardware backends such as vga reading the instance of ''%%vt_buf%%'' content, then rendering it pixel by pixel onto the screen. However, we don’t want to mess up the terminal content buffer when showing the status bar. To separate the status bar from the data buffer ''%%vb_buffer%%'' in struct ''%%vt_buf%%'', I defined an additional member called ''%%vb_ime_buffer%%'' in ''%%vt_buf%%'' for storing the data. Furthermore, the macro ''%%VTBUF_GET_FIELD%%'', which serves as a helper to access the data buffer with the given row and column, also needs to be changed. I extended the macro into a inline function and added a if-else statement to access ''%%vb_ime_buffer%%'' only when the IME mode is enabled and the hardware is accessing at the row 0 (line 0); otherwise, read the origin buffer. That will show the status bar on the top of screen when the IME mode is enabled and hide it when disabled. The following code snippet shows the diff. <code diff> - #define VTBUF_GET_FIELD(vb, r, c) \ + #ifdef VT_IME + inline term_char_t + VTBUF_GET_FIELD(const struct vt_buf *vb, int r, int c) + { + if (vt_ime_buf_state && r == 0) + return vb->vb_ime_buffer[c]; + else + return ((vb)->vb_rows[((vb)->vb_roffset + (r)) % VTBUF_MAX_HEIGHT(vb)][(c)]); + } + #else + #define VTBUF_GET_FIELD(vb, r, c) \ + ((vb)->vb_rows[((vb)->vb_roffset + (r)) % VTBUF_MAX_HEIGHT(vb)][(c)]) + #endif </code> Next, we need to consider how to store the status bar data in the buffer. As the string sent from the IME server is a utf-8-encoded character sequence, we cannot directly place those utf-8 characters into the buffer. Fortunately, this issue has been solved in Week8 as we can take use of the functions ''%%teken_input_byte()%%'' and ''%%teken_input()%%'' to convert them into the ''%%term_char_t%%'' string. Also we need to deal with the issue caused by the width of a single CJK character, which takes twice the width of a single Latin character does. To address this, we first check the width of the character; if is 2, we know it is a CJK character, and we must render the character twice: one for the left half, and another for the right half with ''%%TFORMAT(TF_CJK_RIGHT)%%''; otherwise, just output it. The following code snippet shows the process of printing a character. <code c> while (len-- > 0) { ret = vt_ime_convert_utf8_byte(&utf8_left, &utf8_partial, *c++); if (ret <= 0) continue; if (teken_wcwidth(utf8_partial) == 2 && blen < vb->vb_scr_size.tp_col - 2) { vb->vb_ime_buffer[blen++] = utf8_partial | (ch); vb->vb_ime_buffer[blen++] = utf8_partial | (ch) | TFORMAT(TF_CJK_RIGHT); } else if (blen < vb->vb_scr_size.tp_col - 1) { vb->vb_ime_buffer[blen++] = utf8_partial | (ch); } else { break; } } </code> ===== Todo ===== * Organize my all kernel patches. * Write a final summary summerofcode2021projects/inputmethodinfreebsdvirtualterminal/week9.txt Last modified: 2021/08/30 17:05by FanChung