/* * SetCursorOnLine - set cursor at specified column in single line text string */ void SetCursorOnLine( window_id id, int col, char *str, type_style *style ) { window *w; int x, y; int width, height; if( BAD_ID( id ) ) { return; } w = WINDOW_FROM_ID( id ); // y = FontHeight( WIN_FONT( w ) ) - cursorHeight; x = MyTextExtent( id, style, str, col - 1 ); width = MyTextExtent( id, style, str, col ) - x; /* adjust so that Insert cursor is 0 width * Also make the overstrike cursor the height of the insert cursor. */ width = (long) width * cursorType.width / 100L; height = EditVars.InsertCursorType.height; y = FontHeight( WIN_FONT( w ) ) - height; MyHideCaret( id ); DestroyCaret(); // CreateCaret( id, (HBITMAP)NULLHANDLE, width, cursorHeight ); CreateCaret( id, (HBITMAP)NULLHANDLE, width, height ); SetCaretPos( x, y ); MyShowCaret( id ); } /* SetCursorOnLine */
/* * InvokeColSelHook - invoke column hook with specified data */ vi_rc InvokeColSelHook( int sc, int ec ) { int j, i; char wordbuff[MAX_STR]; char data[MAX_STR + 32]; int lne; #ifndef __WIN__ int x1; int has_bord; #endif #ifndef __WIN__ has_bord = WindowAuxInfo( CurrentWindow, WIND_INFO_HAS_BORDER ); x1 = WindowAuxInfo( CurrentWindow, WIND_INFO_X1 ); if( LastEvent != VI_KEY( MOUSEEVENT ) ) { lne = WindowAuxInfo( CurrentWindow, WIND_INFO_Y1 ) + CurrentPos.line - LeftTopPos.line; if( has_bord ) { ++lne; } } else { lne = MouseRow; } #else if( LastEvent != VI_KEY( FAKEMOUSE ) ) { lne = (CurrentPos.line - LeftTopPos.line) * FontHeight( WIN_FONT( &EditWindow ) ); } else { lne = MouseY; } #endif j = 0; if( ec - sc >= MAX_STR ) { ec = sc + MAX_STR - 2; } for( i = sc - 1; i <= ec - 1; i++ ) { wordbuff[j++] = CurrentLine->data[i]; } wordbuff[j] = 0; #ifndef __WIN__ sc = x1 + VirtualColumnOnCurrentLine( sc ) - LeftTopPos.column; ec = x1 + VirtualColumnOnCurrentLine( ec ) - LeftTopPos.column; if( !has_bord ) { sc--; ec--; } #else sc = MyTextExtent( CurrentWindow, WIN_STYLE( &EditWindow ), &CurrentLine->data[0], sc ); ec = MyTextExtent( CurrentWindow, WIN_STYLE( &EditWindow ), &CurrentLine->data[0], ec ); #endif MySprintf( data, "\"%s\" %d %d %d %d", wordbuff, lne, sc, ec, ec - sc + 1 ); return( SourceHookData( SRC_HOOK_MOUSE_CHARSEL, data ) ); } /* InvokeColSelHook */
static void displayLine( input_buffer *input ) { char display[MAX_STR]; char *buffer, *dest; int length; int cursor_pos; if( EditFlags.NoInputWindow ) { return; } assert( strlen( input->prompt ) < MAX_STR ); strcpy( display, input->prompt ); length = strlen( display ); dest = &display[length]; buffer = input->buffer + input->left_column; while( *buffer != '\0' && length < input->window.width ) { *dest++ = *buffer++; length += 1; } *dest = '\0'; cursor_pos = input->curr_pos - input->left_column + 1; cursor_pos += strlen( input->prompt ); #ifdef __WIN__ { RECT rect; char *ptr, *c; int len, x; window_id wid; wid = input->window.id; MyHideCaret( wid ); GetClientRect( wid, &rect ); // BlankRectIndirect( input->window.id, input->window.style.background, &rect ); c = input->cache; for( len = 0, ptr = input->buffer; *ptr; ptr++, len++ ) { if( *c != *ptr ) { break; } c++; } x = MyTextExtent( wid, &input->window.style, input->cache, len ); WriteString( wid, x, 0, &input->window.style, display + len ); rect.left = MyTextExtent( wid, &input->window.style, display, strlen( display ) ); BlankRectIndirect( wid, input->window.style.background, &rect ); MyShowCaret( wid ); SetCursorOnLine( input->window.id, cursor_pos, display, &input->window.style ); } #else DisplayLineInWindowWithColor( input->window.id, input->window.line, display, &input->window.style, 0 ); SetGenericWindowCursor( input->window.id, input->window.line, cursor_pos ); #endif } /* displayLine */
static int getCursorInfo( HWND hwnd, int row, int col, int *x, int *width ) { ss_block *ss, *ss_start, *ss_prev; dc dc_line; int len; int old_col = 0; char *str; int funny = 0; col--; // we like base 0 row--; // this section checks if current line is valid. assert( hwnd == CurrentInfo->CurrentWindow ); if( row < 0 || row >= CurrentInfo->dc_size ) { // not on screen -> not displayed *x = -10; *width = 0; return( 0 ); } dc_line = DCFindLine( row, hwnd ); if( dc_line->display != 0 ){ // line has not been drawn yet. Can't set cursor. *x = -10; *width = 0; return( 0 ); } assert( dc_line->valid ); if( dc_line->start_col != LeftTopPos.column ) { // not in cache -> not on screen -> not displayed *x = -10; *width = 0; return( 0 ); } ss_start = ss = dc_line->ss; ss_prev = NULL; // this bit adjusts col for real tabs if( EditFlags.RealTabs ){ // this takes it from the current line!!!! %$#@! // what if row isn't the current line! oops!!! // luckily this works because who wants to know cursor info // for any line but the current one! // if( thisLine == CurrentLine ){ int real_left = RealColumnOnCurrentLine( LeftTopPos.column + 1 ); old_col = col; col = RealColumnOnCurrentLine( col + 1 ) - real_left; // kludge! - Real Cursor position refuses to say cursor is to right // of last character like it ought to when Modeless if( CursorPositionOffRight( old_col + 1 ) && (EditFlags.Modeless == FALSE) ) { col++; } // } else { // int real_left = RealCursorPositionOnLine( thisLine, LeftColumn + 1 ); // old_col = col; // col = RealCursorPositionOnLine( thisLine, col + 1 ) - real_left; // } } // this bit finds the block we want while( ss->end < col ) { ss++; } // handle cursor being off the right of text if( ss->end == BEYOND_TEXT ) { *width = FontAverageWidth( SEType[ss->type].font ); if( ss == ss_start ) { *x = (*width) * col; } else { ss_prev = ss - 1; *x = ((*width) * (col - ss_prev->end - 1)) + ss_prev->offset; } return( 0 ); } // setup to figure out where cursor is within text. if( ss != ss_start ) { ss_prev = ss - 1; str = dc_line->text + ss_prev->end + 1; len = col - ss_prev->end - 1; } else { str = dc_line->text; len = col; } // Magic Tabs positioning if( EditFlags.RealTabs ) { type_style *this_style = &SEType[ss->type]; int no_tab = FALSE; int avg_width = FontAverageWidth( SEType[ss->type].font ); int left, extent, end_tab; char *cur_pos; char *end_str; if( ss != ss_start ) { left = ss_prev->offset; } else { left = 0; } if( len > 0 ) { // Note: this will not work with 16bit chars or embedded chars // but niether will the drawing routines, so not to worry (yet) // Is there a tab in the current block ? end_str = cur_pos = str + len; while( *(--cur_pos) != '\t' ){ if(cur_pos == str){ no_tab = TRUE; break; } } // if so, figure out where the last tab stop is. if( no_tab == FALSE ) { // dist is the virtual curpos - the number of chars before // the first tab. this should be the tab boundry. int dist = (old_col + 1) - (end_str - cur_pos); // unless the end_str was also a tab, So we round down. left = (dist - (dist % EditVars.HardTab) - LeftTopPos.column) * avg_width; cur_pos++; } // now get the extent of the leading chars ... extent = MyTextExtent( hwnd, this_style, cur_pos, end_str - cur_pos ); } else { extent = 0; cur_pos = str; end_str = str; } // ... and find the position and width of the cursor. if( *end_str == '\t' ){ // in strange case, tab may start before end of prev string end_tab = (old_col - LeftTopPos.column + 1) * avg_width; *x = left + extent; if( *x > end_tab ) *x = end_tab; *width = end_tab - *x; if( *width < 1 ) *width = 1; funny = 0; } else { *x = left + extent; *width = MyTextExtent( hwnd, this_style, cur_pos, end_str - cur_pos + 1 ) - extent; funny = (*width) / 2; } } else { type_style *this_style = &SEType[ss->type]; *x = MyTextExtent( hwnd, this_style, str, len ); *width = MyTextExtent( hwnd, this_style, str, len + 1 ) - *x; if( ss != ss_start ) { *x += ss_prev->offset; } funny = (*width) / 2; } if( FontIsFunnyItalic( SEType[ss->type].font ) ) { return( funny ); } else { return( 0 ); } }