textbox cursor fix, h265 param files, bluray updates, new-proj theme fixes
[goodguy/history.git] / cinelerra-5.1 / guicast / bctextbox.C
index 0bcf9f464440069c1b517eac99987d0064a6fd61..5a9cac03f0c1dc783036e6326caa01b1f7c9e711 100644 (file)
@@ -161,6 +161,7 @@ int BC_TextBox::reset_parameters(int rows, int has_border, int font, int size)
        text_selected = 0;
        word_selected = 0;
        line_selected = 0;
+       unicode_active = -1;
        text_x = 0;
        enabled = 1;
        highlighted = 0;
@@ -733,14 +734,15 @@ void BC_TextBox::draw(int flush)
 
                if(k > top_margin-text_height && k < get_h()-bottom_margin) {
 // Draw highlighted region of row
-                       if(highlight_letter2 > highlight_letter1 &&
-                               highlight_letter2 > row_begin &&
-                               highlight_letter1 <= row_end) {
-                               if(active && enabled && get_has_focus())
-                                       set_color(resources->text_highlight);
-                               else
-                                       set_color(resources->text_inactive_highlight);
-
+                       if( highlight_letter2 > highlight_letter1 &&
+                           highlight_letter2 > row_begin &&
+                           highlight_letter1 <= row_end ) {
+                               int color = active && enabled && get_has_focus() ?
+                                       resources->text_highlight :
+                                       resources->text_inactive_highlight;
+                               if( unicode_active >= 0 )
+                                       color ^= LTBLUE;
+                               set_color(color);
                                if(highlight_letter1 >= row_begin &&
                                        highlight_letter1 <= row_end)
                                        highlight_x1 = positions[highlight_letter1];
@@ -764,6 +766,8 @@ void BC_TextBox::draw(int flush)
                                draw_wtext(text_x, k + text_ascent, wtext_row, len,
                                        0, &positions[wtext_row - wtext]);
                        }
+                       else
+                               positions[wtext_row - wtext] = 0;
 
 // Get ibeam location
                        if(ibeam_letter >= row_begin && ibeam_letter <= row_end) {
@@ -776,14 +780,8 @@ void BC_TextBox::draw(int flush)
 
 //printf("BC_TextBox::draw 3 %d\n", ibeam_y);
        if(need_ibeam) {
-               if( wtext_len == 0 ) {
-                       ibeam_x = 0;
-                       ibeam_y = 0;
-               }
-               else {
-                       ibeam_x = -1;
-                       ibeam_y = -1;
-               }
+//             ibeam_x = ibeam_y = !wtext_len ? 0 : -1;
+               ibeam_x = 0;  ibeam_y = k - text_y;
        }
 
 //printf("BC_TextBox::draw 4 %d\n", ibeam_y);
@@ -1195,9 +1193,8 @@ int BC_TextBox::repeat_event(int64_t duration)
 
 void BC_TextBox::default_keypress(int &dispatch_event, int &result)
 {
-    if((top_level->get_keypress() == RETURN) ||
-        (top_level->get_keypress() > 30 && top_level->get_keypress() <= 255))
-       {
+       if( (top_level->get_keypress() == RETURN) ||
+           (top_level->get_keypress() > 30 && top_level->get_keypress() <= 255)) {
                int len;
                wchar_t *temp_string = top_level->get_wkeystring(&len);
                if(top_level->get_keypress() == RETURN) {
@@ -1224,99 +1221,139 @@ int BC_TextBox::keypress_event()
 
        int wtext_len = wtext_update();
        last_keypress = get_keypress();
+
+       if( unicode_active >= 0 ) {
+               wchar_t wch = 0;
+               int wlen =  -1;
+               switch( last_keypress ) {
+//unicode active acitons
+               case RETURN: {
+                       for( int i=highlight_letter1+1; i<highlight_letter2; ++i ) {
+                               int ch = nib(wtext[i]);
+                               if( ch < 0 ) return 1;
+                               wch = (wch<<4) + ch;
+                       }
+                       if( wch ) {
+                               dispatch_event = 1;
+                               unicode_active = -1;
+                               result = 1;
+                               wlen = 1;
+                               break;
+                       } } // fall through
+               case ESC: {
+                       unicode_active = -1;
+                       result = 1;
+                       wlen = 0;
+                       break; }
+               case BACKSPACE: {
+                       if(ibeam_letter > 0) {
+                               delete_selection(ibeam_letter - 1, ibeam_letter, wtext_len);
+                               highlight_letter2 = --ibeam_letter;
+                               if( highlight_letter1 >= highlight_letter2 )
+                                       unicode_active = -1;
+                       }
+                       result = 1;
+                       wlen = 0;
+                       break; }
+               case '0': case '1': case '2': case '3': case '4':
+               case '5': case '6': case '7': case '8': case '9':
+               case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+               case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': {
+                       int n = nib(last_keypress);
+                       wch = n < 10 ? '0'+n : 'A'+n-10;
+                       result = 1;
+                       wlen = 1;
+                       break; }
+//normal actions
+               case TAB:
+               case LEFTTAB:
+                       break;
+//ignored actions
+               default:
+                       result = 1;
+                       break;
+               }
+               if( wlen >= 0 ) {
+                       insert_text(&wch, wlen);
+                       find_ibeam(1);
+                       if( unicode_active >= 0 )
+                               highlight_letter2 = ibeam_letter;
+                       else
+                               highlight_letter1 = highlight_letter2 = 0;
+                       draw(1);
+               }
+       }
+
+       if( !result ) {
 //printf("BC_TextBox::keypress_event %d %x\n", __LINE__, last_keypress)
-       switch(last_keypress)
-       {
-               case ESC:
+               switch(last_keypress) {
+               case ESC: {
 // Deactivate the suggestions
-                       if(suggestions && suggestions_popup)
-                       {
+                       if(suggestions && suggestions_popup) {
                                delete suggestions_popup;
                                suggestions_popup = 0;
                                result = 1;
                        }
-                       else
-                       {
+                       else {
                                top_level->deactivate();
                                result = 0;
                        }
-                       break;
-
-
-
-
+                       break; }
 
-               case RETURN:
-                       if(rows == 1)
-                       {
+               case RETURN: {
+                       if( rows == 1 ) {
                                top_level->deactivate();
                                dispatch_event = 1;
                                result = 0;
                        }
-                       else
-                       {
+                       else {
                                default_keypress(dispatch_event, result);
                        }
-                       break;
-
-
+                       break; }
 
 
 // Handle like a default keypress
-               case TAB:
+               case TAB: {
                        top_level->cycle_textboxes(1);
                        result = 1;
-                       break;
+                       break; }
 
-
-
-               case LEFTTAB:
+               case LEFTTAB: {
                        top_level->cycle_textboxes(-1);
                        result = 1;
-                       break;
+                       break; }
 
-               case LEFT:
-                       if(ibeam_letter > 0)
-                       {
+               case LEFT: {
+                       if(ibeam_letter > 0) {
                                int old_ibeam_letter = ibeam_letter;
 // Single character
-                               if(!ctrl_down())
-                               {
+                               if(!ctrl_down()) {
                                        ibeam_letter--;
                                }
-                               else
+                               else {
 // Word
-                               {
                                        ibeam_letter--;
                                        while(ibeam_letter > 0 && isalnum(wtext[ibeam_letter - 1]))
                                                ibeam_letter--;
                                }
 
-
 // Extend selection
-                               if(top_level->shift_down())
-                               {
+                               if(top_level->shift_down()) {
 // Initialize highlighting
-                                       if(highlight_letter1 == highlight_letter2)
-                                       {
+                                       if(highlight_letter1 == highlight_letter2) {
                                                highlight_letter1 = ibeam_letter;
                                                highlight_letter2 = old_ibeam_letter;
                                        }
-                                       else
+                                       else if(highlight_letter1 == old_ibeam_letter) {
 // Extend left highlight
-                                       if(highlight_letter1 == old_ibeam_letter)
-                                       {
                                                highlight_letter1 = ibeam_letter;
                                        }
-                                       else
+                                       else if(highlight_letter2 == old_ibeam_letter) {
 // Shrink right highlight
-                                       if(highlight_letter2 == old_ibeam_letter)
-                                       {
                                                highlight_letter2 = ibeam_letter;
                                        }
                                }
-                               else
-                               {
+                               else {
                                        highlight_letter1 = highlight_letter2 = ibeam_letter;
                                }
 
@@ -1325,50 +1362,39 @@ int BC_TextBox::keypress_event()
                                if(keypress_draw) draw(1);
                        }
                        result = 1;
-                       break;
+                       break; }
 
-               case RIGHT:
-                       if(ibeam_letter < wtext_len)
-                       {
+               case RIGHT: {
+                       if(ibeam_letter < wtext_len) {
                                int old_ibeam_letter = ibeam_letter;
 // Single character
-                               if(!ctrl_down())
-                               {
+                               if(!ctrl_down()) {
                                        ibeam_letter++;
                                }
-                               else
+                               else {
 // Word
-                               {
-                                       while(ibeam_letter < wtext_len && isalnum(wtext[ibeam_letter++]))
-                                               ;
+                                       while(ibeam_letter < wtext_len && isalnum(wtext[ibeam_letter++]));
                                }
 
 
 
 // Extend selection
-                               if(top_level->shift_down())
-                               {
+                               if(top_level->shift_down()) {
 // Initialize highlighting
-                                       if(highlight_letter1 == highlight_letter2)
-                                       {
+                                       if(highlight_letter1 == highlight_letter2) {
                                                highlight_letter1 = old_ibeam_letter;
                                                highlight_letter2 = ibeam_letter;
                                        }
-                                       else
+                                       else if(highlight_letter1 == old_ibeam_letter) {
 // Shrink left highlight
-                                       if(highlight_letter1 == old_ibeam_letter)
-                                       {
                                                highlight_letter1 = ibeam_letter;
                                        }
-                                       else
+                                       else if(highlight_letter2 == old_ibeam_letter) {
 // Expand right highlight
-                                       if(highlight_letter2 == old_ibeam_letter)
-                                       {
                                                highlight_letter2 = ibeam_letter;
                                        }
                                }
-                               else
-                               {
+                               else {
                                        highlight_letter1 = highlight_letter2 = ibeam_letter;
                                }
 
@@ -1376,52 +1402,42 @@ int BC_TextBox::keypress_event()
                                if(keypress_draw) draw(1);
                        }
                        result = 1;
-                       break;
+                       break; }
 
-               case UP:
-                       if(suggestions && suggestions_popup)
-                       {
+               case UP: {
+                       if(suggestions && suggestions_popup) {
 // Pass to suggestions popup
 //printf("BC_TextBox::keypress_event %d\n", __LINE__);
                                suggestions_popup->activate(1);
                                suggestions_popup->keypress_event();
                                result = 1;
                        }
-                       else
-                       if(ibeam_letter > 0)
-                       {
+                       else if(ibeam_letter > 0) {
 //printf("BC_TextBox::keypress_event 1 %d %d %d\n", ibeam_x, ibeam_y, ibeam_letter);
                                int new_letter = get_cursor_letter2(ibeam_x + text_x,
                                        ibeam_y + text_y - text_height);
 //printf("BC_TextBox::keypress_event 2 %d %d %d\n", ibeam_x, ibeam_y, new_letter);
 
 // Extend selection
-                               if(top_level->shift_down())
-                               {
+                               if(top_level->shift_down()) {
 // Initialize highlighting
-                                       if(highlight_letter1 == highlight_letter2)
-                                       {
+                                       if(highlight_letter1 == highlight_letter2) {
                                                highlight_letter1 = new_letter;
                                                highlight_letter2 = ibeam_letter;
                                        }
-                                       else
+                                       else if(highlight_letter1 == ibeam_letter) {
 // Expand left highlight
-                                       if(highlight_letter1 == ibeam_letter)
-                                       {
                                                highlight_letter1 = new_letter;
                                        }
-                                       else
+                                       else if(highlight_letter2 == ibeam_letter) {
 // Shrink right highlight
-                                       if(highlight_letter2 == ibeam_letter)
-                                       {
                                                highlight_letter2 = new_letter;
                                        }
                                }
                                else
                                        highlight_letter1 = highlight_letter2 = new_letter;
 
-                               if(highlight_letter1 > highlight_letter2)
-                               {
+                               if(highlight_letter1 > highlight_letter2) {
                                        int temp = highlight_letter1;
                                        highlight_letter1 = highlight_letter2;
                                        highlight_letter2 = temp;
@@ -1432,41 +1448,33 @@ int BC_TextBox::keypress_event()
                                if(keypress_draw) draw(1);
                        }
                        result = 1;
-                       break;
+                       break; }
 
-               case PGUP:
-                       if(ibeam_letter > 0)
-                       {
+               case PGUP: {
+                       if(ibeam_letter > 0) {
                                int new_letter = get_cursor_letter2(ibeam_x + text_x,
                                        ibeam_y + text_y - get_h());
 
 // Extend selection
-                               if(top_level->shift_down())
-                               {
+                               if(top_level->shift_down()) {
 // Initialize highlighting
-                                       if(highlight_letter1 == highlight_letter2)
-                                       {
+                                       if(highlight_letter1 == highlight_letter2) {
                                                highlight_letter1 = new_letter;
                                                highlight_letter2 = ibeam_letter;
                                        }
-                                       else
+                                       else if(highlight_letter1 == ibeam_letter) {
 // Expand left highlight
-                                       if(highlight_letter1 == ibeam_letter)
-                                       {
                                                highlight_letter1 = new_letter;
                                        }
-                                       else
+                                       else if(highlight_letter2 == ibeam_letter) {
 // Shrink right highlight
-                                       if(highlight_letter2 == ibeam_letter)
-                                       {
                                                highlight_letter2 = new_letter;
                                        }
                                }
                                else
                                        highlight_letter1 = highlight_letter2 = new_letter;
 
-                               if(highlight_letter1 > highlight_letter2)
-                               {
+                               if(highlight_letter1 > highlight_letter2) {
                                        int temp = highlight_letter1;
                                        highlight_letter1 = highlight_letter2;
                                        highlight_letter2 = temp;
@@ -1477,15 +1485,14 @@ int BC_TextBox::keypress_event()
                                if(keypress_draw) draw(1);
                        }
                        result = 1;
-                       break;
+                       break; }
 
-               case DOWN:
+               case DOWN: {
 // printf("BC_TextBox::keypress_event %d %p %p\n",
 // __LINE__,
 // suggestions,
 // suggestions_popup);
-                       if(suggestions && suggestions_popup)
-                       {
+                       if(suggestions && suggestions_popup) {
 // Pass to suggestions popup
                                suggestions_popup->activate(1);
                                suggestions_popup->keypress_event();
@@ -1499,32 +1506,25 @@ int BC_TextBox::keypress_event()
                                        ibeam_y + text_y + text_height);
 //printf("BC_TextBox::keypress_event 10 %d\n", new_letter);
 
-                               if(top_level->shift_down())
-                               {
+                               if(top_level->shift_down()) {
 // Initialize highlighting
-                                       if(highlight_letter1 == highlight_letter2)
-                                       {
+                                       if(highlight_letter1 == highlight_letter2) {
                                                highlight_letter1 = new_letter;
                                                highlight_letter2 = ibeam_letter;
                                        }
-                                       else
+                                       else if(highlight_letter1 == ibeam_letter) {
 // Shrink left highlight
-                                       if(highlight_letter1 == ibeam_letter)
-                                       {
                                                highlight_letter1 = new_letter;
                                        }
-                                       else
+                                       else if(highlight_letter2 == ibeam_letter) {
 // Expand right highlight
-                                       if(highlight_letter2 == ibeam_letter)
-                                       {
                                                highlight_letter2 = new_letter;
                                        }
                                }
                                else
                                        highlight_letter1 = highlight_letter2 = new_letter;
 
-                               if(highlight_letter1 > highlight_letter2)
-                               {
+                               if(highlight_letter1 > highlight_letter2) {
                                        int temp = highlight_letter1;
                                        highlight_letter1 = highlight_letter2;
                                        highlight_letter2 = temp;
@@ -1537,57 +1537,47 @@ int BC_TextBox::keypress_event()
 //printf("BC_TextBox::keypress_event 20 %d\n", ibeam_letter);
                        }
                        result = 1;
-                       break;
+                       break; }
 
-               case PGDN:
-                       {
+               case PGDN: {
 // Extend selection
-                               int new_letter = get_cursor_letter2(ibeam_x + text_x,
-                                       ibeam_y + text_y + get_h());
+                       int new_letter = get_cursor_letter2(ibeam_x + text_x,
+                               ibeam_y + text_y + get_h());
 //printf("BC_TextBox::keypress_event 10 %d\n", new_letter);
 
-                               if(top_level->shift_down())
-                               {
+                       if(top_level->shift_down()) {
 // Initialize highlighting
-                                       if(highlight_letter1 == highlight_letter2)
-                                       {
-                                               highlight_letter1 = new_letter;
-                                               highlight_letter2 = ibeam_letter;
-                                       }
-                                       else
+                               if(highlight_letter1 == highlight_letter2) {
+                                       highlight_letter1 = new_letter;
+                                       highlight_letter2 = ibeam_letter;
+                               }
+                               else if(highlight_letter1 == ibeam_letter) {
 // Shrink left highlight
-                                       if(highlight_letter1 == ibeam_letter)
-                                       {
-                                               highlight_letter1 = new_letter;
-                                       }
-                                       else
+                                       highlight_letter1 = new_letter;
+                               }
+                               else if(highlight_letter2 == ibeam_letter) {
 // Expand right highlight
-                                       if(highlight_letter2 == ibeam_letter)
-                                       {
-                                               highlight_letter2 = new_letter;
-                                       }
+                                       highlight_letter2 = new_letter;
                                }
-                               else
-                                       highlight_letter1 = highlight_letter2 = new_letter;
+                       }
+                       else
+                               highlight_letter1 = highlight_letter2 = new_letter;
 
-                               if(highlight_letter1 > highlight_letter2)
-                               {
-                                       int temp = highlight_letter1;
-                                       highlight_letter1 = highlight_letter2;
-                                       highlight_letter2 = temp;
-                               }
-                               ibeam_letter = new_letter;
+                       if(highlight_letter1 > highlight_letter2) {
+                               int temp = highlight_letter1;
+                               highlight_letter1 = highlight_letter2;
+                               highlight_letter2 = temp;
+                       }
+                       ibeam_letter = new_letter;
 
-                               find_ibeam(1);
-                               if(keypress_draw) draw(1);
+                       find_ibeam(1);
+                       if(keypress_draw) draw(1);
 
 //printf("BC_TextBox::keypress_event 20 %d\n", ibeam_letter);
-                       }
                        result = 1;
-                       break;
+                       break; }
 
-               case END:
-               {
+               case END: {
                        delete suggestions_popup;
                        suggestions_popup = 0;
 
@@ -1596,25 +1586,19 @@ int BC_TextBox::keypress_event()
                        while(ibeam_letter < wtext_len && wtext[ibeam_letter] != '\n')
                                ibeam_letter++;
 
-                       if(top_level->shift_down())
-                       {
+                       if(top_level->shift_down()) {
 // Begin selection
-                               if(highlight_letter1 == highlight_letter2)
-                               {
+                               if(highlight_letter1 == highlight_letter2) {
                                        highlight_letter2 = ibeam_letter;
                                        highlight_letter1 = old_ibeam_letter;
                                }
-                               else
+                               else if(highlight_letter1 == old_ibeam_letter) {
 // Shrink selection
-                               if(highlight_letter1 == old_ibeam_letter)
-                               {
                                        highlight_letter1 = highlight_letter2;
                                        highlight_letter2 = ibeam_letter;
                                }
-                               else
+                               else if(highlight_letter2 == old_ibeam_letter) {
 // Extend selection
-                               if(highlight_letter2 == old_ibeam_letter)
-                               {
                                        highlight_letter2 = ibeam_letter;
                                }
                        }
@@ -1624,11 +1608,9 @@ int BC_TextBox::keypress_event()
                        find_ibeam(1);
                        if(keypress_draw) draw(1);
                        result = 1;
-                       break;
-               }
+                       break; }
 
-               case HOME:
-               {
+               case HOME: {
                        delete suggestions_popup;
                        suggestions_popup = 0;
 
@@ -1665,26 +1647,21 @@ int BC_TextBox::keypress_event()
                        find_ibeam(1);
                        if(keypress_draw) draw(1);
                        result = 1;
-                       break;
-               }
+                       break; }
 
-       case BACKSPACE:
-                       if(suggestions_popup)
-                       {
+               case BACKSPACE: {
+                       if(suggestions_popup) {
                                delete suggestions_popup;
                                suggestions_popup = 0;
                        }
 
-                       if(highlight_letter1 == highlight_letter2)
-                       {
-                               if(ibeam_letter > 0)
-                               {
+                       if(highlight_letter1 == highlight_letter2) {
+                               if(ibeam_letter > 0) {
                                        delete_selection(ibeam_letter - 1, ibeam_letter, wtext_len);
                                        ibeam_letter--;
                                }
                        }
-                       else
-                       {
+                       else {
                                delete_selection(highlight_letter1, highlight_letter2, wtext_len);
                                highlight_letter2 = ibeam_letter = highlight_letter1;
                        }
@@ -1693,19 +1670,16 @@ int BC_TextBox::keypress_event()
                        if(keypress_draw) draw(1);
                        dispatch_event = 1;
                        result = 1;
-               break;
+                       break; }
 
-               case DELETE:
+               case DELETE: {
 //printf("BC_TextBox::keypress_event %d\n", __LINE__);
-                       if(highlight_letter1 == highlight_letter2)
-                       {
-                               if(ibeam_letter < wtext_len)
-                               {
+                       if(highlight_letter1 == highlight_letter2) {
+                               if(ibeam_letter < wtext_len) {
                                        delete_selection(ibeam_letter, ibeam_letter + 1, wtext_len);
                                }
                        }
-                       else
-                       {
+                       else {
                                delete_selection(highlight_letter1, highlight_letter2, wtext_len);
                                highlight_letter2 = ibeam_letter = highlight_letter1;
                        }
@@ -1714,35 +1688,26 @@ int BC_TextBox::keypress_event()
                        if(keypress_draw) draw(1);
                        dispatch_event = 1;
                        result = 1;
-                       break;
-
-
+                       break; }
 
-               default:
-                       if(ctrl_down())
-                       {
-                               if(get_keypress() == 'c' || get_keypress() == 'C')
-                               {
-                                       if(highlight_letter1 != highlight_letter2)
-                                       {
+               default: {
+                       if( ctrl_down() ) {
+                               switch( get_keypress() ) {
+                               case 'c': case 'C': {
+                                       if(highlight_letter1 != highlight_letter2) {
                                                copy_selection(SECONDARY_SELECTION);
                                                result = 1;
                                        }
-                               }
-                               else
-                               if(get_keypress() == 'v' || get_keypress() == 'V')
-                               {
+                                       break; }
+                               case 'v': case 'V': {
                                        paste_selection(SECONDARY_SELECTION);
                                        find_ibeam(1);
                                        if(keypress_draw) draw(1);
                                        dispatch_event = 1;
                                        result = 1;
-                               }
-                               else
-                               if(get_keypress() == 'x' || get_keypress() == 'X')
-                               {
-                                       if(highlight_letter1 != highlight_letter2)
-                                       {
+                                       break; }
+                               case 'x': case 'X': {
+                                       if(highlight_letter1 != highlight_letter2) {
                                                copy_selection(SECONDARY_SELECTION);
                                                delete_selection(highlight_letter1, highlight_letter2, wtext_len);
                                                highlight_letter2 = ibeam_letter = highlight_letter1;
@@ -1752,23 +1717,36 @@ int BC_TextBox::keypress_event()
                                        if(keypress_draw) draw(1);
                                        dispatch_event = 1;
                                        result = 1;
+                                       break; }
+                               case 'u': case 'U': {
+                                       if( shift_down() ) {
+                                               unicode_active = ibeam_letter;
+                                               wchar_t wkey = 'U';
+                                               insert_text(&wkey, 1);
+                                               find_ibeam(1);
+                                               highlight_letter1 = unicode_active;
+                                               highlight_letter2 = ibeam_letter;
+                                               draw(1);
+                                               result = 1;
+                                       }
+                                       break; }
                                }
-
                                break;
                        }
 
                        default_keypress(dispatch_event, result);
-                       break;
+                       break; }
+               }
        }
 
        if(result) skip_cursor->update();
        if(dispatch_event && handle_event())
                result = 1;
+
        return result;
 }
 
 
-
 int BC_TextBox::uses_text()
 {
        return 1;
@@ -1791,14 +1769,12 @@ void BC_TextBox::insert_text(const wchar_t *wcp, int len)
 {
        if( len < 0 ) len = wcslen(wcp);
        int wtext_len = wtext_update();
-       if(highlight_letter1 < highlight_letter2)
-       {
+       if( unicode_active < 0 && highlight_letter1 < highlight_letter2 ) {
                delete_selection(highlight_letter1, highlight_letter2, wtext_len);
                highlight_letter2 = ibeam_letter = highlight_letter1;
                wtext_len = wtext_update();
        }
 
-
        int i, j;
        for(i=wtext_len-1, j=wtext_len+len-1; i>=ibeam_letter; i--, j--) {
                if( j >= wsize ) continue;
@@ -1873,9 +1849,8 @@ void BC_TextBox::get_ibeam_position(int &x, int &y)
 {
        int i, row_begin, row_end;
        int wtext_len = wtext_update();
+       x = y = 0;
 
-       y = 0;
-       x = 0;
        for( i=0; i<wtext_len; ) {
                row_begin = i;
                for(; i<wtext_len && wtext[i]!='\n'; i++);
@@ -1975,15 +1950,15 @@ int BC_TextBox::get_cursor_letter(int cursor_x, int cursor_y)
                        first_visible_row = 1;
                        got_visible_row = 1;
                }
-               
-               if( (k+text_height >= get_h() - bottom_margin || 
-                       (row_end >= wtext_len && k < get_h() - bottom_margin && 
+
+               if( (k+text_height >= get_h() - bottom_margin ||
+                       (row_end >= wtext_len && k < get_h() - bottom_margin &&
                                k + text_height > 0)) )
                        last_visible_row = 1;
 
 // Cursor is inside vertical range of row
-               if((cursor_y >= top_margin && 
-                       cursor_y < get_h() - bottom_margin && 
+               if((cursor_y >= top_margin &&
+                       cursor_y < get_h() - bottom_margin &&
                        cursor_y >= k && cursor_y < k + text_height) ||
 // Cursor is above 1st row
                        (cursor_y < k + text_height && first_visible_row) ||
@@ -1996,7 +1971,7 @@ int BC_TextBox::get_cursor_letter(int cursor_x, int cursor_y)
                                if((column2 + column1) / 2 >= cursor_x) {
                                        result = j - 1;
                                        done = 1;
-// printf("BC_TextBox::get_cursor_letter %d %d %d %d\n", 
+// printf("BC_TextBox::get_cursor_letter %d %d %d %d\n",
 // __LINE__, result, first_visible_row, last_visible_row);
                                }
                                column1 = column2;
@@ -2020,7 +1995,7 @@ int BC_TextBox::get_cursor_letter(int cursor_x, int cursor_y)
        }
 
 
-// printf("BC_TextBox::get_cursor_letter %d cursor_y=%d k=%d h=%d %d %d\n", 
+// printf("BC_TextBox::get_cursor_letter %d cursor_y=%d k=%d h=%d %d %d\n",
 //  __LINE__, cursor_y, k, get_h(), first_visible_row, last_visible_row);
        if(result < 0) result = 0;
        if(result > wtext_len) {
@@ -2065,7 +2040,7 @@ int BC_TextBox::get_cursor_letter2(int cursor_x, int cursor_y)
                        }
                }
                if(wtext[i] == '\n') i++;
-               
+
                if(i >= wtext_len && !done) {
                        result = wtext_len;
                }
@@ -2079,50 +2054,29 @@ int BC_TextBox::get_cursor_letter2(int cursor_x, int cursor_y)
 void BC_TextBox::select_word(int &letter1, int &letter2, int ibeam_letter)
 {
        int wtext_len = wtext_update();
-       if(!wtext_len) return;
-
        letter1 = letter2 = ibeam_letter;
-       do {
-               if(iswalnum(wtext[letter1])) letter1--;
-       } while(letter1 > 0 && iswalnum(wtext[letter1]));
-
-       if( !iswalnum(wtext[letter1]) ) letter1++;
-
-       do {
-               if( iswalnum(wtext[letter2]) ) letter2++;
-       } while( letter2 < wtext_len && isalnum(wtext[letter2]) );
-
-       if( letter2 < wtext_len && wtext[letter2] == ' ') letter2++;
-
-       if(letter1 < 0) letter1 = 0;
-       if(letter2 < 0) letter2 = 0;
-       if(letter1 > wtext_len) letter1 = wtext_len;
-       if(letter2 > wtext_len) letter2 = wtext_len;
+       if( letter1 < 0 ) letter1 = 0;
+       if( letter2 < 0 ) letter2 = 0;
+       if( letter1 > wtext_len ) letter1 = wtext_len;
+       if( letter2 > wtext_len ) letter2 = wtext_len;
+       if( !wtext_len ) return;
+       for( int i=letter1; i>=0 && iswalnum(wtext[i]); --i ) letter1 = i;
+       for( int i=letter2; i<wtext_len && iswalnum(wtext[i]); ) letter2 = ++i;
+       if( letter2 < wtext_len && wtext[letter2] == ' ' ) ++letter2;
 }
 
+
 void BC_TextBox::select_line(int &letter1, int &letter2, int ibeam_letter)
 {
        int wtext_len = wtext_update();
-       if(!wtext_len) return;
-
        letter1 = letter2 = ibeam_letter;
-
-// Rewind to previous linefeed
-       do {
-               if( wtext[letter1] != '\n' ) letter1--;
-       } while( letter1 > 0 && wtext[letter1] != '\n' );
-       if( wtext[letter1] == '\n' ) letter1++;
-
-// Advance to next linefeed
-       do {
-               if( wtext[letter2] != '\n' ) letter2++;
-       } while( letter2 < wtext_len && wtext[letter2] != '\n' );
-       if( letter2 < wtext_len && wtext[letter2] == '\n') letter2++;
-
-       if(letter1 < 0) letter1 = 0;
-       if(letter2 < 0) letter2 = 0;
-       if(letter1 > wtext_len) letter1 = wtext_len;
-       if(letter2 > wtext_len) letter2 = wtext_len;
+       if( letter1 < 0 ) letter1 = 0;
+       if( letter2 < 0 ) letter2 = 0;
+       if( letter1 > wtext_len ) letter1 = wtext_len;
+       if( letter2 > wtext_len ) letter2 = wtext_len;
+       if( !wtext_len ) return;
+       for( int i=letter1; i>=0 && wtext[i]!='\n'; --i ) letter1 = i;
+       for( int i=letter2; i<wtext_len && wtext[i]!='\n'; ) letter2 = ++i;
 }
 
 void BC_TextBox::copy_selection(int clipboard_num)
@@ -2134,9 +2088,9 @@ void BC_TextBox::copy_selection(int clipboard_num)
                highlight_letter1 < 0 || highlight_letter2 < 0 ||
                highlight_letter2 - highlight_letter1 <= 0) return;
        int clip_len = highlight_letter2 - highlight_letter1;
-       char ctext[clip_len+1];
 //printf(" BC_TextBox::copy_selection %d %d %d\n",highlight_letter1, highlight_letter2, clip_len);
-       text_update(&wtext[highlight_letter1],clip_len, ctext,clip_len+1);
+       char ctext[4*clip_len+4];
+       clip_len = text_update(&wtext[highlight_letter1],clip_len, ctext,4*clip_len+4);
        get_clipboard()->to_clipboard(ctext, clip_len, clipboard_num);
 }
 
@@ -2146,11 +2100,11 @@ void BC_TextBox::paste_selection(int clipboard_num)
        int len = get_clipboard()->clipboard_len(clipboard_num);
        if( len > 0 )
        {
-               char cstring[len];  wchar_t wstring[len];  --len;
-               get_clipboard()->from_clipboard(cstring, len, clipboard_num);
+               char cstring[len];  wchar_t wstring[len];
+               get_clipboard()->from_clipboard(cstring, len, clipboard_num);  --len;
 //printf("BC_TextBox::paste_selection %d '%*.*s'\n",len,len,len,cstring);
-               BC_Resources::encode(BC_Resources::encoding, BC_Resources::wide_encoding,
-                       cstring,(len+1), (char *)wstring,(len+1)*sizeof(wchar_t));
+               len = BC_Resources::encode(BC_Resources::encoding, BC_Resources::wide_encoding,
+                       cstring,len, (char *)wstring,(len+1)*sizeof(wchar_t)) / sizeof(wchar_t);
                insert_text(wstring, len);
        }
 }
@@ -2268,8 +2222,8 @@ int BC_TextBoxSuggestions::handle_event()
 
 
 //printf("BC_TextBoxSuggestions::handle_event %d\n", __LINE__);
-       text_box->highlight_letter1 = 
-               text_box->highlight_letter2 = 
+       text_box->highlight_letter1 =
+               text_box->highlight_letter2 =
                text_box->ibeam_letter = text_box->tstrlen();
        text_box->wtext_update();
        text_box->draw(1);
@@ -2325,7 +2279,7 @@ void BC_ScrollTextBox::create_objects()
        parent_window->add_subwindow(yscroll = new BC_ScrollTextBoxYScroll(this));
        text->yscroll = yscroll;
        yscroll->bound_to = text;
-
+       set_text_row(0);
 }
 
 int BC_ScrollTextBox::handle_event()
@@ -2434,6 +2388,11 @@ void BC_ScrollTextBox::wset_selection(int char1, int char2, int ibeam)
        this->text->wset_selection(char1, char2, ibeam);
 }
 
+int BC_ScrollTextBox::get_ibeam_letter()
+{
+       return this->text->get_ibeam_letter();
+}
+