/* * NewCursor - create a new cursor for a window */ void NewCursor( window_id id, cursor_type ct ) { window *w; int height; int width; if( BAD_ID( id ) ) { return; } w = WINDOW_FROM_ID( id ); height = FontHeight( WIN_FONT( w ) ); width = FontAverageWidth( WIN_FONT( w ) ); height = (long) height * ct.height / 100L; width = (long) width * ct.width / 100L; MyHideCaret( id ); DestroyCaret(); cursorHeight = height; cursorWidth = width; if( !haveOldBlinkTime ) { oldBlinkTime = GetCaretBlinkTime(); haveOldBlinkTime = TRUE; } CreateCaret( id, (HBITMAP)NULLHANDLE, cursorWidth, cursorHeight ); SetCursorBlinkRate( EditVars.CursorBlinkRate ); MyShowCaret( id ); cursorType = ct; } /* NewCursor */
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 ); } }
int WindowAuxInfo( window_id wid, int type ) { window *w; int value, height; RECT area; if( BAD_ID( wid ) || !IsWindow( wid ) ) { return( 0 ); } w = WINDOW_FROM_ID( wid ); GetClientRect( wid, &area ); switch( type ) { case WIND_INFO_X1: value = area.left; break; case WIND_INFO_Y1: value = area.top; break; case WIND_INFO_X2: value = area.right; break; case WIND_INFO_Y2: value = area.bottom; break; case WIND_INFO_TEXT_LINES: height = FontHeight( WIN_TEXT_FONT( w ) ); // the 4/5 is a rather arbitrary constant chosen so that we don't show // less than 20% of a line // value = area.bottom - area.top + (height / 5); value = area.bottom - area.top; // + height - 1; value /= height; break; case WIND_INFO_TEXT_COLS: value = area.right - area.left; value /= FontAverageWidth( WIN_TEXT_FONT( w ) ); break; case WIND_INFO_HEIGHT: value = area.bottom - area.top; break; case WIND_INFO_WIDTH: value = area.right - area.left; break; case WIND_INFO_TEXT_COLOR: value = WIN_TEXT_COLOR( w ); break; case WIND_INFO_BACKGROUND_COLOR: value = WIN_TEXT_BACKCOLOR( w ); break; case WIND_INFO_HAS_SCROLL_GADGETS: case WIND_INFO_HAS_BORDER: value = false; break; case WIND_INFO_TEXT_FONT: value = WIN_TEXT_FONT( w ); break; case WIND_INFO_BORDER_COLOR1: case WIND_INFO_BORDER_COLOR2: value = -1; break; default: value = 0; break; } return( value ); }