diff -cr canfep-1.0.org/Makefile canfep-1.0/Makefile *** canfep-1.0.org/Makefile 2001-12-18 16:09:27.000000000 +0900 --- canfep-1.0/Makefile 2004-09-28 13:01:43.000000000 +0900 *************** *** 1,7 **** # Linux CC=c++ ! LIBS=-lcanna -ltermcap ! CFLAGS=-O2 -g # Solaris 2.6J #CC=c++ --- 1,7 ---- # Linux CC=c++ ! LIBS=-lcanna -ltermcap -lutil ! CFLAGS=-O2 -g -DUSE_PTYLIB # Solaris 2.6J #CC=c++ *************** *** 18,23 **** --- 18,26 ---- all: $(TARGET) + install : $(TARGET) + cp canfep /usr/bin/canfep + $(TARGET): $(OBJS) $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) diff -cr canfep-1.0.org/canna.C canfep-1.0/canna.C *** canfep-1.0.org/canna.C 2001-12-18 15:44:51.000000000 +0900 --- canfep-1.0/canna.C 2004-09-23 10:01:34.000000000 +0900 *************** *** 4,13 **** --- 4,90 ---- #define FEP_KEY 15 #define ESC_KEY 27 + void Canna::write_utf8(int fd, char *p, int len) + { + if (eucjp_to_utf8_cd == (iconv_t)-1) + write(fd, p, strlen(p)); + else + { + char *putf8 = iconv_string(eucjp_to_utf8_cd, p, len); + write(fd, putf8, strlen(putf8)); + free(putf8); + } + } + + char * Canna::iconv_string(iconv_t fd, char *str, int slen) + { + char *from; + size_t fromlen; + char *to; + size_t tolen; + size_t len = 0; + size_t done = 0; + char *result = NULL; + char *p; + int l; + + from = (char *)str; + fromlen = slen; + for (;;) + { + if (len == 0 || errno == E2BIG) + { + /* Allocate enough room for most conversions. When re-allocating + * increase the buffer size. */ + len = len + fromlen * 2 + 40; + p = (char*)malloc((unsigned)len); + if (p != NULL && done > 0) + memcpy(p, result, done); + free(result); + result = p; + if (result == NULL) /* out of memory */ + break; + } + + to = (char *)result + done; + tolen = len - done - 2; + /* Avoid a warning for systems with a wrong iconv() prototype by + * casting the second argument to void *. */ + if (iconv(fd, &from, &fromlen, &to, &tolen) != (size_t)-1) + { + /* Finished, append a NUL. */ + *to = 0; + break; + } + /* Check both ICONV_EILSEQ and EILSEQ, because the dynamically loaded + * iconv library may use one of them. */ + if (errno == EILSEQ || errno == EILSEQ) + { + /* Can't convert: insert a '?' and skip a character. This assumes + * conversion from 'encoding' to something else. In other + * situations we don't know what to skip anyway. */ + *to++ = *from++; + fromlen -= 1; + } + else if (errno != E2BIG) + { + /* conversion failed */ + free(result); + result = NULL; + break; + } + /* Not enough room or skipping illegal sequence. */ + done = to - (char *)result; + } + return result; + } + // コンストラクタだよん Canna::Canna(int ac, char** av, char* amsg, char* emsg): Pty(ac, av, amsg, emsg) { + char *p_lang = getenv("LANG"); + // かんなの初期化 jrKanjiControl(0, KC_INITIALIZE, 0); jrKanjiControl(0, KC_SETAPPNAME, "canfep"); *************** *** 15,20 **** --- 92,100 ---- jrKanjiControl(0, KC_QUERYMODE, (char*) saveMode); jrKanjiControl(0, KC_SETWIDTH, (char*) 72); + if (p_lang == NULL || strstr(p_lang, "-8")) + eucjp_to_utf8_cd = iconv_open("utf-8", "euc-jp"); + mode(saveMode); } *************** *** 25,30 **** --- 105,112 ---- jrKanjiControl(0, KC_KILL, (char*) &ksv); jrKanjiControl(0, KC_FINALIZE, 0); + if (eucjp_to_utf8_cd != (iconv_t)-1) + iconv_close(eucjp_to_utf8_cd); mode(saveMode); } *************** *** 32,38 **** void Canna::kakutei(unsigned char* p) { ! write(wfd, p, strlen((char*) p)); } // 変換中(未確定)の文字列を出力する --- 114,120 ---- void Canna::kakutei(unsigned char* p) { ! write_utf8(wfd, (char*)p, strlen((char*) p)); } // 変換中(未確定)の文字列を出力する *************** *** 42,54 **** write(rfd, sc, strlen(sc)); write(rfd, rc, strlen(rc)); write(rfd, us, strlen(us)); ! write(rfd, p, pos); write(rfd, ue, strlen(ue)); write(rfd, so, strlen(so)); ! write(rfd, p + pos, len); write(rfd, se, strlen(se)); write(rfd, us, strlen(us)); ! write(rfd, p + pos + len, strlen((char*) p + pos + len)); write(rfd, ue, strlen(ue)); } --- 124,136 ---- write(rfd, sc, strlen(sc)); write(rfd, rc, strlen(rc)); write(rfd, us, strlen(us)); ! write_utf8(rfd, (char*)p, pos); write(rfd, ue, strlen(ue)); write(rfd, so, strlen(so)); ! write_utf8(rfd, (char*)p + pos, len); write(rfd, se, strlen(se)); write(rfd, us, strlen(us)); ! write_utf8(rfd, (char*)p + pos + len, strlen((char*) p + pos + len)); write(rfd, ue, strlen(ue)); } *************** *** 73,79 **** write(rfd, sc, strlen(sc)); write(rfd, ts, strlen(ts)); write(rfd, ce, strlen(ce)); ! write(rfd, p, strlen((char*) p)); write(rfd, fs, strlen(fs)); } --- 155,161 ---- write(rfd, sc, strlen(sc)); write(rfd, ts, strlen(ts)); write(rfd, ce, strlen(ce)); ! write_utf8(rfd, (char*)p, strlen((char*) p)); write(rfd, fs, strlen(fs)); } *************** *** 84,96 **** write(rfd, sc, strlen(sc)); write(rfd, ts, strlen(ts)); write(rfd, ce, strlen(ce)); ! write(rfd, p, strlen((char*) p)); write(rfd, " ", 1); ! write(rfd, l, pos); write(rfd, so, strlen(so)); ! write(rfd, l + pos, len); write(rfd, se, strlen(se)); ! write(rfd, l + pos + len, strlen((char*) l + pos +len)); write(rfd, fs, strlen(fs)); } --- 166,178 ---- write(rfd, sc, strlen(sc)); write(rfd, ts, strlen(ts)); write(rfd, ce, strlen(ce)); ! write_utf8(rfd, (char*)p, strlen((char*) p)); write(rfd, " ", 1); ! write_utf8(rfd, (char*)l, pos); write(rfd, so, strlen(so)); ! write_utf8(rfd, (char*)l + pos, len); write(rfd, se, strlen(se)); ! write_utf8(rfd, (char*)l + pos + len, strlen((char*) l + pos +len)); write(rfd, fs, strlen(fs)); } diff -cr canfep-1.0.org/canna.H canfep-1.0/canna.H *** canfep-1.0.org/canna.H 2001-09-02 17:25:05.000000000 +0900 --- canfep-1.0/canna.H 2004-09-23 10:01:34.000000000 +0900 *************** *** 5,10 **** --- 5,12 ---- #include #include #include + #include + #include #include #include "pty.H" *************** *** 17,22 **** --- 19,25 ---- jrKanjiStatus ks; jrKanjiStatusWithValue ksv; private: + iconv_t eucjp_to_utf8_cd; unsigned char currentMode[BUFSIZ]; unsigned char saveMode[BUFSIZ]; private: *************** *** 25,30 **** --- 28,35 ---- void delhenkan(int len); void mode(unsigned char* p); void gline(unsigned char* p, unsigned char* l, int pos, int len); + void write_utf8(int fd, char *p, int len); + char* iconv_string(iconv_t fd, char *str, int slen); public: void loop(); }; diff -cr canfep-1.0.org/pty.C canfep-1.0/pty.C *** canfep-1.0.org/pty.C 2001-12-22 23:57:31.000000000 +0900 --- canfep-1.0/pty.C 2004-09-28 14:27:43.000000000 +0900 *************** *** 112,117 **** --- 112,189 ---- if (shell == NULL) shell = "/bin/sh"; + #ifdef USE_PTYLIB + struct winsize win; + ioctl(0, TIOCGWINSZ, &win); + if (!hs) + win.ws_row--; + child = openpty(&master, &slave, line, &tt, &win); + if (child < 0) { + perror("openpty"); + fail(); + } + + tcgetattr(0, &tt); + tt.c_iflag &= ~ISTRIP; + ioctl(0, TIOCGWINSZ, (char*) &win); + + // 端末の初期化 + fixtty(); + + // フォークします + child = fork(); + + // 子供です + if (child == 0) { + subchild = child = fork(); + if (child < 0) { + perror("fork"); + fail(); + } + if (child) { + close(0); + int cc; + int ret; + char obuf[BUFSIZ]; + char buff[BUFSIZ]; + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(master, &readfds); + while (1) { + int status; + if (waitpid(subchild, &status, WNOHANG)) { + break; + } + ret = select(master + 1, &readfds, 0, 0, 0); + if (ret == -1) + break; + if (!FD_ISSET(master, &readfds)) + continue; + cc = (int) read(master, obuf, BUFSIZ); + if (cc <= 0) + break; + write(1, obuf, cc); + } + done(); + } + tcsetattr(slave, TCSAFLUSH, &tt); + ioctl(slave, TIOCSWINSZ, (char*) &win); + setsid(); + close(master); + dup2(slave, 0); + dup2(slave, 1); + dup2(slave, 2); + close(slave); + if (ac > 1) + execvp(av[1], &av[1]); + else + execl(shell, strrchr(shell, '/') + 1, 0); + perror(shell); + fail(); + } + + close(slave); + #else // マスタデバイスの取得 getmaster(); *************** *** 172,177 **** --- 244,250 ---- perror(shell); fail(); } + #endif // 親です rfd = 0; diff -cr canfep-1.0.org/pty.H canfep-1.0/pty.H *** canfep-1.0.org/pty.H 2001-12-22 23:56:54.000000000 +0900 --- canfep-1.0/pty.H 2004-09-28 14:26:49.000000000 +0900 *************** *** 20,25 **** --- 20,29 ---- #else #include #endif + #ifdef USE_PTYLIB + #include + #include + #endif typedef void (*SIG_PF)(int);