diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/FL/Fl.H fltk-xunicode/FL/Fl.H --- fltk-1.1.0b13/FL/Fl.H Fri Mar 8 04:22:55 2002 +++ fltk-xunicode/FL/Fl.H Wed Mar 27 20:10:43 2002 @@ -189,6 +189,14 @@ static FL_EXPORT int w(); static FL_EXPORT int h(); +#if defined(USE_XUNICODE) + // charcode: + static FL_EXPORT void set_charcode(const char *); + static FL_EXPORT const char *get_charcode(); + static FL_EXPORT void set_internal_charcode(const char *); + static FL_EXPORT const char *get_internal_charcode(); +#endif + // color map: static FL_EXPORT void set_color(Fl_Color, uchar, uchar, uchar); static FL_EXPORT void set_color(Fl_Color, unsigned); diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/FL/Fl_Input_.H fltk-xunicode/FL/Fl_Input_.H --- fltk-1.1.0b13/FL/Fl_Input_.H Fri Mar 8 04:22:56 2002 +++ fltk-xunicode/FL/Fl_Input_.H Wed Mar 27 20:10:43 2002 @@ -117,6 +117,8 @@ void textcolor(unsigned n) {textcolor_ = n;} Fl_Color cursor_color() const {return (Fl_Color)cursor_color_;} void cursor_color(unsigned n) {cursor_color_ = n;} + + void cursor_position(int& curx, int& cury); }; #endif diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/FL/Fl_Text_Buffer.H fltk-xunicode/FL/Fl_Text_Buffer.H --- fltk-1.1.0b13/FL/Fl_Text_Buffer.H Wed Jan 2 00:11:28 2002 +++ fltk-xunicode/FL/Fl_Text_Buffer.H Mon Mar 25 10:08:22 2002 @@ -75,7 +75,7 @@ const char* text(); void text(const char* text); const char* text_range(int start, int end); - char character(int pos); + char character(int pos, const char **ptr = 0); const char* text_in_rectangle(int start, int end, int rectStart, int rectEnd); void insert(int pos, const char* text); void append(const char* text) { insert(length(), text); } @@ -148,11 +148,16 @@ int word_start(int pos); int word_end(int pos); int expand_character(int pos, int indent, char *outStr); + int expand_character(int pos, int indent, char *outStr, int *skip); static int expand_character(char c, int indent, char* outStr, int tabDist, char nullSubsChar); + static int expand_character(const char *str, int indent, char* outStr, int tabDist, + char nullSubsChar, int *skip); static int character_width(char c, int indent, int tabDist, char nullSubsChar); + static int character_width(const char *str, int indent, int tabDist, + char nullSubsChar, int *skip); int count_displayed_characters(int lineStartPos, int targetPos); int skip_displayed_characters(int lineStartPos, int nChars); int count_lines(int startPos, int endPos); diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/FL/Fl_Text_Display.H fltk-xunicode/FL/Fl_Text_Display.H --- fltk-1.1.0b13/FL/Fl_Text_Display.H Wed Jan 2 00:11:28 2002 +++ fltk-xunicode/FL/Fl_Text_Display.H Mon Mar 25 11:14:00 2002 @@ -73,6 +73,7 @@ FL_EXPORT void insert(const char* text); FL_EXPORT void overstrike(const char* text); FL_EXPORT void insert_position(int newPos); + FL_EXPORT void insert_position(int newPos, int d); int insert_position() { return mCursorPos; } FL_EXPORT int in_selection(int x, int y); FL_EXPORT void show_insert_position(); diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/Makefile fltk-xunicode/Makefile --- fltk-1.1.0b13/Makefile Sun Jan 6 22:40:27 2002 +++ fltk-xunicode/Makefile Sun Mar 24 08:54:40 2002 @@ -26,7 +26,7 @@ include makeinclude SHELL = /bin/sh -DIRS = src fluid test documentation +DIRS = src fluid test all: makeinclude @for dir in $(DIRS); do\ diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/autom4te.cache/requests fltk-xunicode/autom4te.cache/requests --- fltk-1.1.0b13/autom4te.cache/requests Thu Apr 11 02:54:13 2002 +++ fltk-xunicode/autom4te.cache/requests Fri Apr 12 11:27:40 2002 @@ -7,10 +7,10 @@ '0', 1, [ - '/usr/share/autoconf' + '/usr/local/share/autoconf' ], [ - '--reload-state=/usr/share/autoconf/autoconf/autoconf.m4f', + '--reload-state=/usr/local/share/autoconf/autoconf/autoconf.m4f', 'configure.in' ], { diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/src/Fl.cxx fltk-xunicode/src/Fl.cxx --- fltk-1.1.0b13/src/Fl.cxx Thu Apr 11 01:26:33 2002 +++ fltk-xunicode/src/Fl.cxx Fri Apr 12 11:26:42 2002 @@ -31,6 +31,10 @@ #include #include "flstring.h" +#ifdef USE_XUNICODE +#include "../xunicode/xunicode.h" +#endif + // // Globals... @@ -741,7 +745,11 @@ # if USE_XFT fl_destroy_xft_draw(x->xid); # endif +# if defined(USE_XUNICODE) && !defined(WIN32) + XUDestroyWindow(fl_display, x->xid); +# else XDestroyWindow(fl_display, x->xid); +# endif #endif #ifdef WIN32 diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/src/Fl_Input.cxx fltk-xunicode/src/Fl_Input.cxx --- fltk-1.1.0b13/src/Fl_Input.cxx Fri Mar 8 04:22:56 2002 +++ fltk-xunicode/src/Fl_Input.cxx Thu Mar 28 00:15:50 2002 @@ -36,6 +36,19 @@ #define DND_OUT 1 +#ifdef USE_XUNICODE +#include "../xunicode/xunicode.h" +#if !defined(WIN32) +extern void fl_unset_xic_focus(Fl_Widget *w); +#endif /* !defined(WIN32) */ +#if defined(WIN32) +# include +# include +# include +# include "Fl_Font.H" +#endif /* defined(WIN32) */ +#endif /* defined(USE_XUNICODE) */ + void Fl_Input::draw() { if (type() == FL_HIDDEN_INPUT) return; Fl_Boxtype b = box(); @@ -144,24 +157,44 @@ } int i; +#ifdef USE_XUNICODE + int pos = position(); + const char *vpos = &value()[pos]; +#endif switch (ascii) { case ctrl('A'): return shift_position(line_start(position())) + NORMAL_INPUT_MOVE; case ctrl('B'): +#ifdef USE_XUNICODE + return shift_position(position()-XUutf8CharRLen(vpos,pos)) + NORMAL_INPUT_MOVE; +#else return shift_position(position()-1) + NORMAL_INPUT_MOVE; +#endif case ctrl('C'): // copy return copy(1); case ctrl('D'): case ctrl('?'): if (mark() != position()) return cut(); +#ifdef USE_XUNICODE + else return cut(XUutf8CharLen(vpos,size()-pos)); +#else else return cut(1); +#endif case ctrl('E'): return shift_position(line_end(position())) + NORMAL_INPUT_MOVE; case ctrl('F'): +#ifdef USE_XUNICODE + return shift_position(position()+XUutf8CharLen(vpos,size()-pos)) + NORMAL_INPUT_MOVE; +#else return shift_position(position()+1) + NORMAL_INPUT_MOVE; +#endif case ctrl('H'): if (mark() != position()) cut(); +#ifdef USE_XUNICODE + else cut(-XUutf8CharRLen(vpos,pos)); +#else else cut(-1); +#endif return 1; case ctrl('K'): if (position()>=size()) return 0; @@ -241,6 +274,21 @@ break; case FL_KEYBOARD: +#if defined(WIN32) && defined(USE_XUNICODE) + { + extern Fl_FontSize* fl_fontsize; + HIMC imc = ImmGetContext(fl_xid(window())); + LOGFONT lf; + GetObject(fl_fontsize->fid, sizeof(LOGFONT), &lf); + ImmSetCompositionFont(imc,&lf); + COMPOSITIONFORM cform; + cform.dwStyle = CFS_POINT; + int curx, cury; + cursor_position(curx, cury); + ImmSetCompositionWindow(imc,&cform); + ImmReleaseContext(fl_xid(window()), imc); + }; +#endif if (Fl::event_key() == FL_Tab && mark() != position()) { // Set the current cursor position to the end of the selection... if (mark() > position()) @@ -342,6 +390,12 @@ take_focus(); return 1; +#if defined(USE_XUNICODE) && !defined(WIN32) + case FL_UNFOCUS: + fl_unset_xic_focus(this); + break; +#endif + } Fl_Boxtype b = box(); return Fl_Input_::handletext(event, diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/src/Fl_Input_.cxx fltk-xunicode/src/Fl_Input_.cxx --- fltk-1.1.0b13/src/Fl_Input_.cxx Tue Apr 9 03:32:16 2002 +++ fltk-xunicode/src/Fl_Input_.cxx Fri Apr 12 11:26:42 2002 @@ -37,6 +37,13 @@ #include #include +#ifdef USE_XUNICODE +#include "../xunicode/xunicode.h" +#if !defined(WIN32) +extern void fl_set_xic_focus(Fl_Widget *w, int left, int top, int width, int height, int x, int y); +#endif /* !defined(WIN32) */ +#endif /* defined(USE_XUNICODE) */ + #define MAXBUF 1024 //////////////////////////////////////////////////////////////// @@ -62,7 +69,14 @@ int word_count = 0; #endif if (type()==FL_SECRET_INPUT) { +#ifndef USE_XUNICODE while (o= value_+size_ || isspace(*p))) { @@ -78,7 +92,13 @@ } #endif if (p >= value_+size_) break; +#ifndef USE_XUNICODE int c = *p++ & 255; +#else + int c = XUutf8CharEncode(p, value_+size_-p); + int clen = XUutf8CharLen(p, value_+size_-p); + p += clen; +#endif if (c < ' ' || c == 127) { if (c=='\n' && type()==FL_MULTILINE_INPUT) {p--; break;} if (c == '\t' && type()==FL_MULTILINE_INPUT) { @@ -99,7 +119,12 @@ } else if (c == 0xA0) { // nbsp *o++ = ' '; } else { +#ifndef USE_XUNICODE *o++ = c; +#else + strncpy(o, p-clen, clen); + o += clen; +#endif } } *o = 0; @@ -114,16 +139,30 @@ int* returnn // return offset into buf here ) const { int n = 0; +#ifndef USE_XUNICODE if (type()==FL_SECRET_INPUT) n = e-p; else while (p= 128 && c < 0xA0) { n += 4; } else { +#ifndef USE_XUNICODE n++; +#else + n += clen; +#endif } } if (returnn) *returnn = n; @@ -293,6 +332,10 @@ position() >= p-value() && position() <= e-value()) { fl_color(cursor_color()); fl_rectf(X+curx-xscroll_, Y+ypos, 2, height); +#if defined(USE_XUNICODE) && !defined(WIN32) + setfont(); + fl_set_xic_focus(this, X, Y, W, H, curx-xscroll_, ypos); +#endif } fl_color(color); fl_draw(buf, X-xscroll_, Y+ypos+desc); @@ -409,8 +452,14 @@ else r = t-1; } if (l < e) { // see if closer to character on right: +#ifndef USE_XUNICODE double f1 = X-xscroll_+expandpos(p, l+1, buf, 0)-Fl::event_x(); if (f1 < f0) l = l+1; +#else + int clen = XUutf8CharLen(l, value_+size_-l); + double f1 = X-xscroll_+expandpos(p, l+clen, buf, 0)-Fl::event_x(); + if (f1 < f0) l += clen; +#endif } newpos = l-value(); @@ -863,6 +912,49 @@ if (bufsize) free((void*)buffer); } +#if defined(USE_XUNICODE) && defined(WIN32) +void +Fl_Input_::cursor_position(int& curx, int& cury) { + Fl_Boxtype b = box(); + int W = w()-Fl::box_dw(b)-6; + const char *p, *e; + char buf[MAXBUF]; + + // count how many lines and put the last one into the buffer: + // And figure out where the cursor is: + int height = fl_height(); + int lines; + for (p=value(), curx=cury=lines=0; ;) { + e = expand(p, buf); + if (position() >= p-value() && position() <= e-value()) { + curx = int(expandpos(p, value()+position(), buf, 0)+.5); + if (Fl::focus()==this && !was_up_down) up_down_pos = curx; + cury = lines*height; + if (Fl::focus()==this) { + int fullw = int(expandpos(p, e, buf, 0)); + if (curx > xscroll_+W-20) { + xscroll_ = curx+20-W; + if (xscroll_ > fullw-W+2) xscroll_ = fullw-W+2; + mu_p = 0; erase_cursor_only = 0; + } + if (curx < xscroll_+20 && xscroll_) { + if (fullw > W-2) xscroll_ = curx-20; + else xscroll_ = 0; + mu_p = 0; erase_cursor_only = 0; + } + if (xscroll_ < 0) xscroll_ = 0; + } + } + lines++; + if (e >= value_+size_) break; + if (*e == '\n' || *e == ' ') e++; + p = e; + } + curx += x() + Fl::box_dx(b) + 3 - xscroll_; + cury += y()+Fl::box_dy(b) - yscroll_; +} +#endif /* defined(USE_XUNICODE) && defined(WIN32) */ + // -// End of "$Id: Fl_Input_.cxx,v 1.21.2.11.2.8 2002/04/08 18:32:16 easysw Exp $". +// End of "$Id: Fl_Input_.cxx,v 1.4 2002/04/12 02:26:42 ttate Exp $". // diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/src/Fl_Shared_Image.cxx fltk-xunicode/src/Fl_Shared_Image.cxx --- fltk-1.1.0b13/src/Fl_Shared_Image.cxx Fri Mar 29 20:59:56 2002 +++ fltk-xunicode/src/Fl_Shared_Image.cxx Fri Apr 12 11:26:42 2002 @@ -394,15 +394,10 @@ return temp; } - -// -// 'Fl_Shared_Image::add_handler()' - Add a shared image handler. -// - void Fl_Shared_Image::add_handler(Fl_Shared_Handler *f) { - int i; // Looping var... - Fl_Shared_Handler **temp; // New image handler array... + int i; // Looping var... + Fl_Shared_Handler **temp; // New image handler array... // First see if we have already added the handler... for (i = 0; i < num_handlers_; i ++) { @@ -434,7 +429,7 @@ void Fl_Shared_Image::remove_handler(Fl_Shared_Handler *f) { - int i; // Looping var... + int i; // Looping var... // First see if the handler has been added... for (i = 0; i < num_handlers_; i ++) { diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/src/Fl_Text_Buffer.cxx fltk-xunicode/src/Fl_Text_Buffer.cxx --- fltk-1.1.0b13/src/Fl_Text_Buffer.cxx Wed Jan 2 00:11:31 2002 +++ fltk-xunicode/src/Fl_Text_Buffer.cxx Thu Mar 28 00:15:50 2002 @@ -29,6 +29,16 @@ #include #include +#if defined(USE_XUNICODE) +#include "../xunicode/xunicode.h" +#endif + +#ifdef min +#undef min +#endif +#ifdef max +#undef max +#endif #define PREFERRED_GAP_SIZE 80 /* Initial size for the buffer gap (empty space @@ -201,13 +211,19 @@ /* ** Return the character at buffer position "pos". Positions start at 0. */ -char Fl_Text_Buffer::character( int pos ) { - if ( pos < 0 || pos > mLength ) +char Fl_Text_Buffer::character( int pos, const char **ptr ) { + if ( pos < 0 || pos > mLength ){ + if( ptr && *ptr ) *ptr = NULL; return '\0'; - if ( pos < mGapStart ) + }; + if ( pos < mGapStart ){ + if( ptr && *ptr ) *ptr = mBuf + pos; return mBuf[ pos ]; - else + } + else{ + if( ptr && *ptr ) *ptr = mBuf + (pos + mGapEnd - mGapStart); return mBuf[ pos + mGapEnd - mGapStart ]; + }; } /* @@ -747,6 +763,20 @@ mTabDist, mNullSubsChar ); } +#if defined(USE_XUNICODE) +int Fl_Text_Buffer::expand_character( int pos, int indent, char *outStr, int *skip){ + const char *ptr; + character(pos, &ptr); + return expand_character( ptr, indent, outStr, + mTabDist, mNullSubsChar, skip ); +} +#else +int Fl_Text_Buffer::expand_character( int pos, int indent, char *outStr, int *skip){ + return expand_character( character( pos ), indent, outStr, + mTabDist, mNullSubsChar); +} +#endif + /* ** Expand a single character from the text buffer into it's screen ** representation (which may be several characters for a tab or a @@ -785,6 +815,40 @@ return 1; } +#if defined(USE_XUNICODE) +int Fl_Text_Buffer::expand_character(const char *str, int indent, + char *outStr, int tabDist, + char nullSubsChar, int *skip) +{ + if( !str ){ + *skip = 0; + return Fl_Text_Buffer::expand_character('\0', indent, outStr, + tabDist, nullSubsChar); + }; + + if( str[0] < 0 ){ + int bytes = XUutf8CharLen(str, FL_TEXT_MAX_EXP_CHAR_LEN); + strncpy(outStr, str, bytes); + *skip = bytes - 1; + return bytes; + } + else{ + *skip = 0; + return Fl_Text_Buffer::expand_character(str[0], indent, outStr, + tabDist, nullSubsChar); + }; +} +#else +int Fl_Text_Buffer::expand_character(const char *str, int indent, + char *outStr, int tabDist, + char nullSubsChar, int *skip) +{ + *skip = 0; + return Fl_Text_Buffer::expand_character(str[0], indent, outStr, + tabDist, nullSubsChar); +} +#endif + /* ** Return the length in displayed characters of character "c" expanded ** for display (as discussed above in BufGetExpandedChar). If the @@ -805,6 +869,31 @@ return 1; } +#if defined(USE_XUNICODE) +int Fl_Text_Buffer::character_width(const char *str, int indent, int tabDist, + char nullSubsChar, int *skip) +{ + if( !str ) return 0; + if( str[0] < 0 ){ + *skip = XUutf8CharLen(str, FL_TEXT_MAX_EXP_CHAR_LEN) - 1; + return 2; + } + else{ + *skip = 0; + return Fl_Text_Buffer::character_width(str[0], indent, tabDist, nullSubsChar); + }; +} +#else +int Fl_Text_Buffer::character_width(const char *str, int indent, int tabDist, + char nullSubsChar, int *skip) +{ + if( !str ) return 0; + + *skip = 0; + return Fl_Text_Buffer::character_width(str[0], indent, tabDist, nullSubsChar); +} +#endif + /* ** Count the number of displayed characters between buffer position ** "lineStartPos" and "targetPos". (displayed characters are the characters diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/src/Fl_Text_Display.cxx fltk-xunicode/src/Fl_Text_Display.cxx --- fltk-1.1.0b13/src/Fl_Text_Display.cxx Fri Mar 8 04:22:56 2002 +++ fltk-xunicode/src/Fl_Text_Display.cxx Sat Mar 30 14:17:58 2002 @@ -32,6 +32,13 @@ #include #include +#if defined(USE_XUNICODE) +#include "../xunicode/xunicode.h" +extern void fl_set_xic_focus(Fl_Widget *w, int left, int top, + int width, int height, int x, int y); +extern void fl_unset_xic_focus(Fl_Widget *w); +#endif /* USE_XUNICODE */ + #undef min #undef max @@ -449,6 +456,56 @@ redisplay_range(mCursorPos - 1, mCursorPos + 1); } +void Fl_Text_Display::insert_position( int newPos, int d ) +{ +#if defined(USE_XUNICODE) + int line_start, line_end; + + /* make sure new position is ok, do nothing if it hasn't changed */ + if ( newPos == mCursorPos ) + return; + if ( newPos < 0 ) newPos = 0; + if ( newPos > mBuffer->length() ) newPos = mBuffer->length(); + + /* cursor movement cancels vertical cursor motion column */ + mCursorPreferredCol = -1; + + if( d ){ + int i, len; + const char *str; + for( i=1; i<6; i++ ){ + if( mBuffer->character(newPos-i,&str) < 0 ){ + if( i < (len = XUutf8CharLen(str,-1)) ){ + /* newPos is inside of a multibyte character. */ + if( d > 0 ){ + newPos = newPos - i + len; + } + else if( d < 0 ){ + newPos = newPos - i; + }; + break; + }; + }; + }; + } + + /* erase the cursor at it's previous position */ + line_start = buffer()->line_start(mCursorPos); + line_end = buffer()->line_end(mCursorPos); + redisplay_range(line_start, line_end); + + mCursorPos = newPos; + + /* draw cursor at its new position */ + line_start = buffer()->line_start(newPos); + line_end = buffer()->line_end(newPos); + redisplay_range(line_start, line_end); +#else + insert_position(newPos); +#endif +}; + + void Fl_Text_Display::show_cursor(int b) { mCursorOn = b; redisplay_range(mCursorPos - 1, mCursorPos + 1); @@ -459,6 +516,7 @@ if (mCursorOn) show_cursor(); } + /* ** Insert "text" at the current cursor location. This has the same ** effect as inserting the text into the buffer using BufInsert and @@ -489,8 +547,17 @@ /* determine how many displayed character positions are covered */ startIndent = mBuffer->count_displayed_characters( lineStart, startPos ); indent = startIndent; - for ( c = text; *c != '\0'; c++ ) - indent += Fl_Text_Buffer::character_width( *c, indent, buf->tab_distance(), buf->null_substitution_character() ); + for ( c = text; *c != '\0'; c++ ){ +#if defined(USE_XUNICODE) + int skip; + indent += Fl_Text_Buffer::character_width(c, indent, buf->tab_distance(), + buf->null_substitution_character(),&skip); + c += skip; +#else + indent += Fl_Text_Buffer::character_width( *c, indent, buf->tab_distance(), + buf->null_substitution_character() ); +#endif + }; endIndent = indent; /* find which characters to remove, and if necessary generate additional @@ -499,10 +566,23 @@ for ( p = startPos; ; p++ ) { if ( p == buf->length() ) break; +#if defined(USE_XUNICODE) + const char *text; + ch = buf->character( p, &text ); +#else ch = buf->character( p ); +#endif if ( ch == '\n' ) break; - indent += Fl_Text_Buffer::character_width( ch, indent, buf->tab_distance(), buf->null_substitution_character() ); +#if defined(USE_XUNICODE) + int skip; + indent += Fl_Text_Buffer::character_width(text, indent, buf->tab_distance(), + buf->null_substitution_character(),&skip); + p += skip; +#else + indent += Fl_Text_Buffer::character_width(ch, indent, buf->tab_distance(), + buf->null_substitution_character()); +#endif if ( indent == endIndent ) { p++; break; @@ -566,8 +646,21 @@ xStep = text_area.x - mHorizOffset; outIndex = 0; for ( charIndex = 0; charIndex < pos - lineStartPos; charIndex++ ) { - charLen = Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, - mBuffer->tab_distance(), mBuffer->null_substitution_character() ); +#if defined(USE_XUNICODE) + int skip; + charLen = Fl_Text_Buffer::expand_character(lineStr + charIndex, + outIndex, expandedChar, + mBuffer->tab_distance(), + mBuffer->null_substitution_character(), + &skip); + charIndex += skip; +#else + charLen = Fl_Text_Buffer::expand_character( lineStr[ charIndex ], + outIndex, + expandedChar, + mBuffer->tab_distance(), + mBuffer->null_substitution_character() ); +#endif charStyle = position_style( lineStartPos, lineLen, charIndex, outIndex ); xStep += string_width( expandedChar, charLen, charStyle ); @@ -657,14 +750,22 @@ int Fl_Text_Display::move_right() { if ( mCursorPos >= mBuffer->length() ) return 0; +#if defined(USE_XUNICODE) + insert_position( mCursorPos + 1, 1 ); +#else insert_position( mCursorPos + 1 ); +#endif return 1; } int Fl_Text_Display::move_left() { if ( mCursorPos <= 0 ) return 0; +#if defined(USE_XUNICODE) + insert_position( mCursorPos - 1, -1 ); +#else insert_position( mCursorPos - 1 ); +#endif return 1; } @@ -694,7 +795,11 @@ newPos = mBuffer->skip_displayed_characters( prevLineStartPos, column ); /* move the cursor */ +#if defined(USE_XUNICODE) + insert_position( newPos, -1 ); +#else insert_position( newPos ); +#endif /* if a preferred column wasn't aleady established, establish it */ mCursorPreferredCol = column; @@ -716,7 +821,11 @@ nextLineStartPos = buffer()->skip_lines( lineStartPos, 1 ); newPos = mBuffer->skip_displayed_characters( nextLineStartPos, column ); +#if defined(USE_XUNICODE) + insert_position( newPos, -1 ); +#else insert_position( newPos ); +#endif mCursorPreferredCol = column; return 1; } @@ -935,9 +1044,19 @@ X = text_area.x - mHorizOffset; outIndex = 0; for ( charIndex = 0; ; charIndex++ ) { +#if defined(USE_XUNICODE) + int skip = 0; + charLen = (charIndex >= lineLen) ? 1 : + Fl_Text_Buffer::expand_character(lineStr + charIndex, outIndex, expandedChar, + buf->tab_distance(), + buf->null_substitution_character(), + &skip); + charIndex += skip; +#else charLen = charIndex >= lineLen ? 1 : Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, buf->tab_distance(), buf->null_substitution_character() ); +#endif style = position_style( lineStartPos, lineLen, charIndex, outIndex + dispIndexOffset ); charWidth = charIndex >= lineLen ? stdCharWidth : @@ -970,9 +1089,18 @@ cursorX = X - 1; } } +#if defined(USE_XUNICODE) + int skip; + charLen = charIndex >= lineLen ? 1 : + Fl_Text_Buffer::expand_character( lineStr + charIndex, outIndex, + expandedChar, buf->tab_distance(), + buf->null_substitution_character(), &skip ); +#else charLen = charIndex >= lineLen ? 1 : - Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, - buf->tab_distance(), buf->null_substitution_character() ); + Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, + expandedChar, buf->tab_distance(), + buf->null_substitution_character() ); +#endif charStyle = position_style( lineStartPos, lineLen, charIndex, outIndex + dispIndexOffset ); for ( i = 0; i < charLen; i++ ) { @@ -994,6 +1122,9 @@ X += charWidth; outIndex++; } +#if defined(USE_XUNICODE) + charIndex += skip; +#endif if ( outPtr - outStr + FL_TEXT_MAX_EXP_CHAR_LEN >= MAX_DISP_LINE_LEN || X >= rightClip ) break; } @@ -1292,8 +1423,18 @@ xStep = text_area.x - mHorizOffset; outIndex = 0; for ( charIndex = 0; charIndex < lineLen; charIndex++ ) { - charLen = Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, - mBuffer->tab_distance(), mBuffer->null_substitution_character() ); +#if defined(USE_XUNICODE) + int skip; + charLen = Fl_Text_Buffer::expand_character( lineStr + charIndex, outIndex, + expandedChar, mBuffer->tab_distance(), + mBuffer->null_substitution_character(), + &skip); + charIndex += skip; +#else + charLen = Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, + expandedChar, mBuffer->tab_distance(), + mBuffer->null_substitution_character() ); +#endif charStyle = position_style( lineStart, lineLen, charIndex, outIndex ); charWidth = string_width( expandedChar, charLen, charStyle ); if ( X < xStep + ( posType == CURSOR_POS ? charWidth / 2 : charWidth ) ) { @@ -1650,8 +1791,15 @@ if (lineStartPos < 0) return 0; if ( mStyleBuffer == NULL ) { for ( i = 0; i < lineLen; i++ ) { +#if defined(USE_XUNICODE) + int skip; + len = mBuffer->expand_character( lineStartPos + i, + charCount, expandedChar, &skip ); + i += skip; +#else len = mBuffer->expand_character( lineStartPos + i, charCount, expandedChar ); +#endif fl_font( textfont(), textsize() ); @@ -1661,8 +1809,14 @@ } } else { for ( i = 0; i < lineLen; i++ ) { +#if defined(USE_XUNICODE) + int skip; + len = mBuffer->expand_character( lineStartPos + i, + charCount, expandedChar, &skip ); +#else len = mBuffer->expand_character( lineStartPos + i, charCount, expandedChar ); +#endif style = ( unsigned char ) mStyleBuffer->character( lineStartPos + i ) - 'A'; @@ -1671,6 +1825,9 @@ width += ( int ) fl_width( expandedChar, len ); charCount += len; +#if defined(USE_XUNICODE) + i += skip; +#endif } } return width; @@ -1841,6 +1998,16 @@ //printf("drew cursor at pos: %d (%d,%d)\n", mCursorPos, X, Y); mCursorOldY = Y; fl_pop_clip(); + +#if defined(USE_XUNICODE) && !defined(WIN32) + int curx, cury, rx, ry; + position_to_xy(mCursorPos, &curx, &cury); + rx = curx - x(); + ry = cury - y(); + if( rx > 0 && ry > 0 ){ + fl_set_xic_focus(this, x(), y(), w(), h(), rx, ry); + }; +#endif } } diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/src/Fl_Text_Editor.cxx fltk-xunicode/src/Fl_Text_Editor.cxx --- fltk-1.1.0b13/src/Fl_Text_Editor.cxx Fri Mar 8 04:22:56 2002 +++ fltk-xunicode/src/Fl_Text_Editor.cxx Wed Mar 27 20:10:44 2002 @@ -26,10 +26,17 @@ #include #include +#include #include #include #include +#if defined(USE_XUNICODE) +#include "../xunicode/xunicode.h" +extern void fl_set_xic_focus(Fl_Widget *w, int left, int top, + int width, int height, int x, int y); +extern void fl_unset_xic_focus(Fl_Widget *w); +#endif Fl_Text_Editor::Fl_Text_Editor(int X, int Y, int W, int H, const char* l) : Fl_Text_Display(X, Y, W, H, l) { @@ -415,6 +422,9 @@ case FL_UNFOCUS: show_cursor(mCursorOn); // redraws the cursor +#if defined(USE_XUNICODE) && !defined(WIN32) + fl_unset_xic_focus(this); +#endif return 1; case FL_KEYBOARD: diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/src/Fl_compose.cxx fltk-xunicode/src/Fl_compose.cxx --- fltk-1.1.0b13/src/Fl_compose.cxx Wed Jan 2 00:11:31 2002 +++ fltk-xunicode/src/Fl_compose.cxx Sun Mar 24 07:13:10 2002 @@ -107,11 +107,13 @@ int i = e_keysym; +#ifndef USE_XUNICODE // See if they type the compose prefix key: if (i == FL_Control_R || i == 0xff20/* Multi-Key */) { compose_state = 1; return 1; } +#endif #ifndef WIN32 // X only // See if they typed a dead key. This gets it into the same state as diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/src/Fl_win32.cxx fltk-xunicode/src/Fl_win32.cxx --- fltk-1.1.0b13/src/Fl_win32.cxx Thu Apr 11 00:01:20 2002 +++ fltk-xunicode/src/Fl_win32.cxx Fri Apr 12 11:26:42 2002 @@ -52,6 +52,9 @@ # include #endif // !__GNUC__ || __GNUC__ >= 3 +#if defined(USE_XUNICODE) +# include "../../xunicode/xunicode.c" +#endif // // USE_ASYNC_SELECT - define it if you have WSAAsyncSelect()... diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/src/Fl_x.cxx fltk-xunicode/src/Fl_x.cxx --- fltk-1.1.0b13/src/Fl_x.cxx Wed Apr 10 10:32:03 2002 +++ fltk-xunicode/src/Fl_x.cxx Fri Apr 12 11:26:42 2002 @@ -44,6 +44,19 @@ # include # include +#ifdef USE_XUNICODE +#include "../xunicode/xunicode.c" +static Fl_Widget *xicFocusWidget = NULL; +static Window xicFocusWindow = None; + +#include +#define CHARCODE "EUC-JP" +#define INTERNAL_CHARCODE "UTF-8" + +static char fl_charcode_[21] = CHARCODE; +static char fl_internal_charcode_[21] = INTERNAL_CHARCODE; +#endif /* USE_XUNICODE */ + //////////////////////////////////////////////////////////////// // interface to poll/select call: @@ -169,7 +182,16 @@ while (XEventsQueued(fl_display,QueuedAfterReading)) { XEvent xevent; XNextEvent(fl_display, &xevent); +#if defined(USE_XUNICODE) + if( xicFocusWindow && XFilterEvent(&xevent,xicFocusWindow) ){ + // do nothing + } + else{ + fl_handle(xevent); + }; +#else fl_handle(xevent); +#endif } // we send FL_LEAVE only if the mouse did not enter some other window: if (!fl_xmousewin) Fl::handle(FL_LEAVE, 0); @@ -267,6 +289,10 @@ XVisualInfo *fl_visual; Colormap fl_colormap; +#ifdef USE_XUNICODE +XUInfoDisplay *fl_info_display; +#endif + static Atom WM_DELETE_WINDOW; static Atom WM_PROTOCOLS; static Atom fl_MOTIF_WM_HINTS; @@ -297,6 +323,9 @@ static int xerror_handler(Display* d, XErrorEvent* e) { char buf1[128], buf2[128]; +#ifdef USE_XUNICODE + if (!XUErrorHandler(d, e)) return 0; +#endif sprintf(buf1, "XRequest.%d", e->request_code); XGetErrorDatabaseText(d,"",buf1,buf1,buf2,128); XGetErrorText(d, e->error_code, buf1, 128); @@ -311,6 +340,10 @@ XSetIOErrorHandler(io_error_handler); XSetErrorHandler(xerror_handler); +#ifdef USE_XUNICODE + XUInit(); +#endif + Display *d = XOpenDisplay(0); if (!d) Fl::fatal("Can't open display: %s",XDisplayName(0)); @@ -319,6 +352,9 @@ void fl_open_display(Display* d) { fl_display = d; +#ifdef USE_XUNICODE + fl_info_display = XUGetInfoDisplay(d); +#endif WM_DELETE_WINDOW = XInternAtom(d, "WM_DELETE_WINDOW", 0); WM_PROTOCOLS = XInternAtom(d, "WM_PROTOCOLS", 0); @@ -353,11 +389,20 @@ #if !USE_COLORMAP Fl::visual(FL_RGB); #endif + +#ifdef USE_XUNICODE + XUIMOpen(d); +#endif } void fl_close_display() { Fl::remove_fd(ConnectionNumber(fl_display)); +#ifdef USE_XUNICODE + fl_info_display = NULL; + XUCloseDisplay(fl_display); +#else XCloseDisplay(fl_display); +#endif } int Fl::h() { @@ -499,6 +544,28 @@ //////////////////////////////////////////////////////////////// +#if defined(USE_XUNICODE) +void Fl::set_charcode(const char *code) +{ + strncpy(fl_charcode_, code, 21); +} + +const char *Fl::get_charcode(void) +{ + return fl_charcode_; +} + +void Fl::set_internal_charcode(const char *code) +{ + strncpy(fl_internal_charcode_, code, 21); +} + +const char *Fl::get_internal_charcode(void) +{ + return fl_internal_charcode_; +}; +#endif // USE_XUNIOCODE + int fl_handle(const XEvent& xevent) { fl_xevent = &xevent; @@ -603,6 +670,13 @@ case UnmapNotify: xid = xevent.xmaprequest.window; break; +#ifdef USE_XUNICODE + case ClientMessage: + if (xevent.xclient.message_type == fl_info_display->setSrv) { + XUUISet(fl_display, &xevent); + } + break; +#endif } int event = 0; @@ -727,16 +801,60 @@ case KeyPress: case KeyRelease: { +#ifdef USE_XUNICODE + if (xid == xicFocusWindow) XUUISend(fl_display, xid, &xevent); +#endif int keycode = xevent.xkey.keycode; fl_key_vector[keycode/8] |= (1 << (keycode%8)); +#if defined(USE_XUNICODE) + static char buffer[101]; +#else static char buffer[21]; +#endif int len; KeySym keysym; if (xevent.type == KeyPress) { event = FL_KEYDOWN; //static XComposeStatus compose; +#ifdef USE_XUNICODE + XUInfoWindow *w = XUGetInfoWindow(fl_display,xid); + XIC xic = w->xic; + Status status; + if( xic ){ + len = XmbLookupString(xic,(XKeyEvent*)&(xevent.xkey),buffer,100,&keysym,&status); + if( status == XLookupChars || status == XLookupBoth ){ + iconv_t cd = iconv_open(Fl::get_internal_charcode(), Fl::get_charcode()); + char ibuff[BUFSIZ], obuff[BUFSIZ]; + char *iptr,*optr; + size_t ileft, oleft, b; + strncpy(ibuff,buffer,101); + ileft = len; + oleft = BUFSIZ; + iptr = ibuff; + optr = obuff; + b = 0; + if( cd >= 0 ){ + while( (b = iconv(cd, &iptr, &ileft, &optr, &oleft)) > 0 ){ + }; + iconv_close(cd); + if( b >= 0 ){ + strncpy(buffer,obuff,101); + len = BUFSIZ - oleft; + }; + } + else{ + Fl::warning("Can't encode the buffer with UTF-8.\n"); + len = 0; + }; + }; + } + else{ + len = XLookupString((XKeyEvent*)&(xevent.xkey),buffer,100,&keysym,0); + }; +#else len = XLookupString((XKeyEvent*)&(xevent.xkey), buffer, 20, &keysym, 0/*&compose*/); +#endif if (keysym && keysym < 0x400) { // a character in latin-1,2,3,4 sets // force it to type a character (not sure if this ever is needed): if (!len) {buffer[0] = char(keysym); len = 1;} @@ -803,6 +921,9 @@ break;} case ButtonPress: +#if defined(USE_XUNICODE) + XUUICancel(fl_display); +#endif Fl::e_keysym = FL_Button + xevent.xbutton.button; set_event_xy(); if (xevent.xbutton.button == Button4) { @@ -1074,6 +1195,13 @@ w->handle(FL_SHOW); // get child windows to appear w->redraw(); } +#ifdef USE_XUNICODE + static bool fl_first_create_window = true; + if (fl_first_create_window) { + XUUISearch(fl_display, x->xid); + fl_first_create_window = false; + } +#endif } //////////////////////////////////////////////////////////////// @@ -1226,6 +1354,52 @@ fl_clip_region(0); } +#ifdef USE_XUNICODE +#if defined(USE_XFT) +static XFontStruct *xim_font = 0; +#endif + +void fl_set_xic_focus(Fl_Widget *w, int left, int top, int width, int height, int x, int y) { + Fl_Window *w1 = w->window(), *w2 = NULL; + if (!w1) return; + XPoint p; + for (;;) { + w2 = w1; + w1 = w1->window(); + if (!w1) break; + XUGetWindowPos(&p, fl_display, fl_xid(w2)); + left += p.x; + top += p.y; + } + xicFocusWidget = w; + xicFocusWindow = fl_xid(w2); +#if defined(USE_XFT) + if( !xim_font ){ + xim_font = XLoadQueryFont(fl_display, "fixed"); + }; + XUIMSet(fl_display, xicFocusWindow, xim_font, + left, top, width, height, left+x, top+y+xim_font->ascent); +#else + XUIMSet(fl_display, xicFocusWindow, fl_xfont, + left, top, width, height, left+x, top+y+fl_xfont->ascent); +#endif +} + +void fl_unset_xic_focus(Fl_Widget *w) { + if (w == xicFocusWidget) { + XUIMUnset(fl_display, xicFocusWindow); + xicFocusWidget = NULL; + xicFocusWindow = None; + return; + } + Fl_Window *w1, *w2; + for (w1 = w->window(), w2 = NULL; w1; w2 = w1, w1 = w1->window()); + if (!w2) return; + Window xid = fl_xid(w2); + if (xid != xicFocusWindow) XUIMUnset(fl_display, xid); +} +#endif + #endif // diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/src/fl_draw.cxx fltk-xunicode/src/fl_draw.cxx --- fltk-1.1.0b13/src/fl_draw.cxx Thu Jan 24 01:58:01 2002 +++ fltk-xunicode/src/fl_draw.cxx Sun Mar 24 07:13:10 2002 @@ -37,6 +37,10 @@ #include #include +#ifdef USE_XUNICODE +#include "../xunicode/xunicode.h" +#endif + #define MAXBUF 1024 char fl_draw_shortcut; // set by fl_labeltypes.cxx @@ -63,7 +67,13 @@ const char* p = from; for (;; p++) { +#ifndef USE_XUNICODE int c = *p & 255; +#else + int c = XUutf8CharEncode(p, -1); + int clen = XUutf8CharLen(p, -1); + if(clen > 1) p += clen - 1; +#endif if (!c || c == ' ' || c == '\n') { // test for word-wrap: @@ -99,7 +109,12 @@ *o++ = c; if (p[1]) p++; } else { +#ifndef USE_XUNICODE *o++ = c; +#else + strncpy(o, p+1-clen,clen); + o += clen; +#endif } } diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/src/fl_font_win32.cxx fltk-xunicode/src/fl_font_win32.cxx --- fltk-1.1.0b13/src/fl_font_win32.cxx Thu Mar 7 03:11:01 2002 +++ fltk-xunicode/src/fl_font_win32.cxx Thu Mar 28 00:15:50 2002 @@ -150,7 +150,18 @@ void fl_draw(const char* str, int n, int x, int y) { COLORREF oldColor = SetTextColor(fl_gc, fl_RGB()); SelectObject(fl_gc, fl_fontsize->fid); +#if defined(USE_XUNICODE) + wchar_t *wstr; + int len; + len = MultiByteToWideChar(CP_UTF8, 0, str, n, 0, 0); + wstr = new wchar_t[len+1]; + MultiByteToWideChar(CP_UTF8, 0, str, n, wstr, len); + // XUEncode(wstr, len, str, n, XU_CONV_LOCALE); + TextOutW(fl_gc, x, y, wstr, len); + delete wstr; +#else TextOut(fl_gc, x, y, str, n); +#endif SetTextColor(fl_gc, oldColor); } diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/src/fl_font_x.cxx fltk-xunicode/src/fl_font_x.cxx --- fltk-1.1.0b13/src/fl_font_x.cxx Thu Mar 7 04:42:30 2002 +++ fltk-xunicode/src/fl_font_x.cxx Thu Mar 28 00:15:50 2002 @@ -23,6 +23,10 @@ // Please report all bugs and problems to "fltk-bugs@fltk.org". // +#ifdef USE_XUNICODE +#include "../xunicode/xunicode.h" +#endif + Fl_FontSize::Fl_FontSize(const char* name) { font = XLoadQueryFont(fl_display, name); if (!font) { @@ -216,6 +220,9 @@ } double fl_width(const char* c, int n) { +#if defined(USE_XUNICODE) + return XUutf8TextWidth(fl_display, fl_xfont, c, n); +#else XCharStruct* p = fl_xfont->per_char; if (!p) return n*fl_xfont->min_bounds.width; int a = fl_xfont->min_char_or_byte2; @@ -227,6 +234,7 @@ else w += fl_xfont->min_bounds.width; } return w; +#endif } double fl_width(uchar c) { @@ -244,9 +252,15 @@ if (font_gc != fl_gc) { if (!fl_xfont) fl_font(FL_HELVETICA, 14); font_gc = fl_gc; +#if !defined(USE_XUNICODE) XSetFont(fl_display, fl_gc, fl_xfont->fid); +#endif } +#if defined(USE_XUNICODE) + XUutf8DrawString(fl_display, fl_window, fl_xfont, fl_gc, x, y, str, n, False); +#else XDrawString(fl_display, fl_window, fl_gc, x, y, str, n); +#endif } // diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/src/fl_font_xft.cxx fltk-xunicode/src/fl_font_xft.cxx --- fltk-1.1.0b13/src/fl_font_xft.cxx Sun Mar 10 06:33:54 2002 +++ fltk-xunicode/src/fl_font_xft.cxx Sat Mar 30 14:17:58 2002 @@ -160,7 +160,7 @@ double fl_width(const char *str, int n) { XGlyphInfo i; - XftTextExtents8(fl_display, current_font, (XftChar8 *)str, n, &i); + XftTextExtentsUtf8(fl_display, current_font, (XftChar8 *)str, n, &i); return i.xOff; } @@ -229,7 +229,7 @@ color.color.blue = b*0x101; color.color.alpha = 0xffff; - XftDrawString8(draw, &color, current_font, x, y, (XftChar8 *)str, n); + XftDrawStringUtf8(draw, &color, current_font, x, y, (XftChar8 *)str, n); } // diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/test/hello.cxx fltk-xunicode/test/hello.cxx --- fltk-1.1.0b13/test/hello.cxx Wed Jan 2 00:11:33 2002 +++ fltk-xunicode/test/hello.cxx Sat Mar 30 14:17:59 2002 @@ -26,12 +26,29 @@ #include #include #include +#include "../config.h" int main(int argc, char **argv) { +#if defined(USE_XUNICODE) + Fl_Window *window = new Fl_Window(400,180); + Fl_Box *box = new Fl_Box(FL_UP_BOX,20,40,360,100,"こんにちは,世界!"); +#if defined(WIN32) + Fl::set_font(FL_FREE_FONT, ""); +#else +# if defined(USE_XFT) + Fl::set_font(FL_FREE_FONT, " Kochi Gothic"); +# else + Fl::set_font(FL_FREE_FONT, "-*-helvetica-medium-r-normal--*"); +# endif +#endif +#else Fl_Window *window = new Fl_Window(300,180); Fl_Box *box = new Fl_Box(FL_UP_BOX,20,40,260,100,"Hello, World!"); - box->labelfont(FL_BOLD+FL_ITALIC); - box->labelsize(36); +#endif + + box->labelfont(FL_FREE_FONT); + + box->labelsize(24); box->labeltype(FL_SHADOW_LABEL); window->end(); window->show(argc, argv); diff -x CVS -x documentation -x configure -ru -I $Id: fltk-1.1.0b13/test/input.cxx fltk-xunicode/test/input.cxx --- fltk-1.1.0b13/test/input.cxx Wed Jan 2 00:11:33 2002 +++ fltk-xunicode/test/input.cxx Sat Mar 30 14:17:59 2002 @@ -34,6 +34,7 @@ #include #include #include +#include "../config.h" void cb(Fl_Widget *ob) { printf("Callback for %s '%s'\n",ob->label(),((Fl_Input*)ob)->value()); @@ -77,6 +78,18 @@ int y = 10; input[0] = new Fl_Input(70,y,300,30,"Normal:"); y += 35; +#if defined(USE_XUNICODE) +#if defined(WIN32) + Fl::set_font(FL_FREE_FONT,""); + input[0]->textfont(FL_FREE_FONT); +#else +# if defined(USE_XFT) + Fl::set_font(FL_FREE_FONT, " Kochi Gothic"); + input[0]->textfont(FL_FREE_FONT); + input[0]->textsize(12); +# endif +#endif +#endif // input[0]->cursor_color(FL_SELECTION_COLOR); // input[0]->maximum_size(20); // input[0]->static_value("this is a testgarbage");