/* vi: set sw=4 ts=4: */ /* * CCE - Console Chinese Environment - * Copyright (C) 1998-2003 Rui He (rhe@3eti.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define QUWEI_AVAIL(encoding) (encoding == CODE_GB || encoding == CODE_GBK || \ encoding == CODE_EUC || encoding == CODE_KSC) #define QUWEI_MAX_1STDIGIT(encoding) (encoding == CODE_GBK ? 7: 9) hz_input_table* Init_IntCodeInput(hz_input_table *table, int sysCoding) { int i,index; strcpy(table->cname, IntCode_CNameStr[sysCoding]); for(i = 0; i < 128; i++) { table->KeyMap[i] = -1; if ((i >= '0' && i <= '9') || (i >= 'a' && i <= 'f')) { if (i >= '0' && i <= '9') index = i - '0'; else index = i -'a' + 10; table->KeyMap[i] = index; table->KeyName[index][0] = toupper(i); table->KeyName[index][1] = '\0'; } } table->MaxPress = 4; table->auto_select = 1; table->FontMapped = 1; /* using system font */ table->item = (ITEM *)-1; /* 0 unmapped, -1 (no table) other: mapped */ table->encoding = sysCoding; table->HZFilter = Intcode_HZFilter; table->RefreshInput = NULL; table->InputAreaX = cal_input_xpos(table); table->InputAreaWidth = 5; /* 4; // 5 bytes */ table->SelAreaX = table->InputAreaX + table->InputAreaWidth; table->SelAreaWidth = dispInfo.tx_avail - table->SelAreaX - dispInfo.show_terminal * WINDOW_TERMINAL_STR_WIDTH; /* 18 or 0 */ return table; } #define STR_AF "abcdef" #define STR_89AF "89abcdef" #define STR_09AF "0123456789abcdef" #define STR_89E "89e" #define STR_49AF "456789abcdef" #define STR_47AF "4567abcdef" static unsigned char *ValidCharCode[][4] = { /* coding, valid input string */ { STR_AF, STR_09AF, STR_AF, STR_09AF }, /* ISO-2022-JP 7 bits, use JIS/EUC */ { STR_AF, STR_09AF, STR_AF, STR_09AF }, /* EUC-JP */ { STR_89E, STR_09AF, STR_49AF, STR_09AF }, /* SJIS */ { STR_AF, STR_09AF, STR_47AF, STR_09AF }, /* Big5 */ { STR_AF, STR_09AF, STR_AF, STR_09AF }, /* GB */ { STR_89AF, STR_09AF, STR_49AF, STR_09AF }, /* GBK */ { STR_AF, STR_09AF, STR_AF, STR_09AF }, }; static int ValidIntCode[][4][2] = { /* Coding, InputCount, min/max */ { { 0xA, 0xF}, { 0xA1, 0xFE}, { 0xA, 0xF}, { 0xA1, 0xFF} }, /* ISO-2022-JP 7 bits */ { { 0xA, 0xF}, { 0xA1, 0xFE}, { 0xA, 0xF}, { 0xA1, 0xFE} }, /* EUC-JP */ { { 0x8, 0xE}, { 0x81, 0xEF}, { 0x4, 0xF}, { 0x40, 0xFC } }, /* Shift-JIS */ { { 0xA, 0xF}, { 0xA1, 0xFE}, { 0x4, 0xF}, { 0x40, 0xFE} }, /* Big5, 2nd Byte 0x7F-A0 invalid */ { { 0xA, 0xF}, { 0xA1, 0xFE}, { 0xA, 0xF}, { 0xA1, 0xFE} }, /* GB */ { { 0x8, 0xF}, { 0x81, 0xFE}, { 0x4, 0xF}, { 0x40, 0xFE} }, /* GBK, 2nd Byte 0x7F invalid */ { { 0xA, 0xF}, { 0xA1, 0xFE}, { 0xA, 0xF}, { 0xA1, 0xFE} }, /* KSC */ }; void IntCode_FindMatchKey(int sysCoding) { unsigned int Byte1, Byte2, CandNum; if (InpKey[0] <= QUWEI_MAX_1STDIGIT(sysCoding) && QUWEI_AVAIL(sysCoding)) { Byte1 = 0xA0 + (InpKey[0]*10 + InpKey[1]); /* A1~FE */ Byte2 = InpKey[2] * 10 + 0xA0; if (Byte2 == 0xA0) { Byte2 = 0xA1; /* make it 0xA1 (for GBK) */ CandNum = 9; } else CandNum = 10; } else { Byte1 = (InpKey[0] << 4) | InpKey[1]; Byte2 = (InpKey[2] << 4); CandNum = 16; } Byte1 <<= 8; switch(InputCount) { case 0: case 1: StartIndex = EndIndex = MultiPageMode = 0; /* not display selection */ break; case 2: StartIndex = Byte1 + ValidIntCode[sysCoding][3][0]; /* 0xA1; GB only */ EndIndex = Byte1 + ValidIntCode[sysCoding][3][1] + 1; /* 0xFF; // A1-A9,B0-F7 A1-FE GB only */ break; case 3: StartIndex = Byte1 + Byte2; EndIndex = StartIndex + CandNum; if (Byte2 < ValidIntCode[sysCoding][3][0]) StartIndex = Byte1 + ValidIntCode[sysCoding][3][0]; /* 0xA0->0xA1 */ if (Byte2+CandNum-1 > ValidIntCode[sysCoding][3][1]) EndIndex = Byte1 + ValidIntCode[sysCoding][3][1]+1; break; } IsDirectSelect = 1; MultiPageMode = 0; CurrentPageIndex = NextPageIndex = StartIndex; memset( SelTab, 0, sizeof(SelTab) ); /* reset the selection */ IntCode_FillMatchChars(sysCoding, StartIndex); } void IntCode_FillMatchChars(int sysCoding, int index) { int MaxSel,i, byte1, byte2; if (index < StartIndex || index >= EndIndex) index = StartIndex; CurSelNum = 0; if (InputCount < /* big5/gbk xx4-8x, conflict with the 0-9 selection key */ (sysCoding == CODE_GBK || sysCoding == CODE_BIG5 || sysCoding == CODE_SJIS ? 3 : 2) ) return; if (InpKey[0] <= QUWEI_MAX_1STDIGIT(sysCoding) && QUWEI_AVAIL(sysCoding)) { if (InputCount == 2) return; MaxSel = 10; if (index % 256 <= 0xA1) /* 0xA1 or 0xA0 */ SelTab[CurSelNum++][0] = '\0'; } else { if (InputCount == 2) MaxSel = 10; else MaxSel = 16; if (InputCount == 3 && index % 256 == 0xA1 && ValidIntCode[sysCoding][3][0] == 0xA1) /* it's possible to be 0x40 */ SelTab[CurSelNum++][0] = '\0'; } while( CurSelNum < MaxSel && index < EndIndex) { byte1 = index >> 8; byte2 = index & 0xFF; if (InputCount == 3 && ( byte2 == 0x7F || /* GBK/SJIS/Big5 doesn't allow 0x7F */ ( sysCoding == CODE_BIG5 && byte2 == 0xA0 ) || ( sysCoding == CODE_SJIS && byte1 >= 0xA0 && byte1 <= 0xDF ) ) ) /* SJIS 1st byte 0xA0-DF invalid */ { SelTab[CurSelNum][0] = '\0'; } else { SelTab[CurSelNum][0] = index >> 8; SelTab[CurSelNum][1] = byte2; SelTab[CurSelNum][2] = '\0'; } CurSelNum++; index++; } for(i = CurSelNum; i < 16; i++) SelTab[i][0] = '\0'; /* zero out the unused area */ InputMatch = InputCount; if ( index < EndIndex && CurSelNum == MaxSel && MaxSel == 10) { NextPageIndex = index; MultiPageMode = 1; } else if (MultiPageMode) { NextPageIndex = StartIndex; /* rotate selection */ } DisplaySelection(); /* show it */ } int Intcode_HZFilter(int tty_fd, unsigned char key) { int inkey = -1; if (MultiPageMode) { if (index(cur_table->pageprevkey, key)) /* not NULL found */ { CurrentPageIndex -= 10; IntCode_FillMatchChars(cur_table->encoding, CurrentPageIndex); return 1; } else if (index(cur_table->pagenextkey, key) ) { CurrentPageIndex = NextPageIndex; IntCode_FillMatchChars(cur_table->encoding, CurrentPageIndex); return 1; } } switch ( key ) { case '\010': /* BackSpace Ctrl+H */ case '\177': /* BackSpace */ if ( InputCount > 0 ) { int tmpSave; InpKey[--InputCount]=0; switch(InputCount) { case 0: ResetInput(0,1); break; case 1: tmpSave = InpKey[0]; ResetInput(0,1); InpKey[0] = tmpSave; InputCount = 1; /* restore the values */ break; case 2: ClearSelectionArea(); /* clear it up first */ IntCode_FindMatchKey(cur_table->encoding); break; } DisplayInput(); return 1; /* we handled it */ } return 0; case '\033': /* ESCAPE */ if (InputCount > 0) { ResetInput(1,1); return 1; } return 0; case ' ': if ( CurSelNum == 0 ) return 0; if ( SelTab[0][0] || (SelTab[0][0] == '\0' && SelTab[1][0]) ) { OutputSelection(cur_table->encoding, tty_fd, SelTab[0][0] ? SelTab[0] : SelTab[1]); return 1; } break; default: inkey = cur_table->KeyMap[key]; /* -1 is invalid 0-15 is valid */ if (inkey >= 0 && inkey < CurSelNum && SelTab[inkey][0] && InputCount >= 2 ) { OutputSelection(cur_table->encoding, tty_fd, SelTab[inkey]); return 1; /* go back */ } if (InputCount == 3) return 1; /* not a valid 4th char, ignore it, no output */ if (inkey < 0) break; /* not 0-9a-f */ if ( QUWEI_AVAIL(cur_table->encoding) && ((InputCount == 0 && inkey >=0 && inkey <= QUWEI_MAX_1STDIGIT(cur_table->encoding) ) || (InputCount > 0 && InpKey[0] <= QUWEI_MAX_1STDIGIT(cur_table->encoding) )) ) { if (inkey > 9) return 1; /* ignore a~f */ if ( InputCount == 1 ) { int byte1 = InpKey[0] * 10 + inkey; if (byte1 < 1 || byte1 > 94) return 1; /* invalid */ } } else if (strchr(ValidCharCode[cur_table->encoding][InputCount], key)) { if ( InputCount == 1) { int byte1 = (InpKey[0] << 4) | inkey; if (byte1 < ValidIntCode[cur_table->encoding][1][0] || byte1 > ValidIntCode[cur_table->encoding][1][1] ) return 1; /* not a valid 2nd Char, ignore it */ } } else break; InpKey[InputCount++] = inkey; if (InputCount >= 2) IntCode_FindMatchKey(cur_table->encoding); DisplayInput(); return 1; /* processed */ } /* switch */ return (InputCount > 0 ? 1 : 0); /* ignore it if we have something */ }