/* * This file is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. * Users may copy, modify or distribute this file at will. * * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * This file is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even * if Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * Modifications to the original Sun Microsystems, Inc. source code * made by the Grasshopper Group are in the Public Domain. * * Extensions to this file by Eric Messick of the Grasshopper Group. * * Grasshopper Group * 212 Clayton St * San Francisco, CA 94117 * */ #ifndef lint static char sccsid[] = "@(#)selection.c 9.4 88/01/19 Copyright 1987 Sun Micro"; static char RCSid[] = "@(#)$Header: selection.c,v 2.3 88/10/04 05:59:54 gnu Release $"; #endif /* * Copyright (c) 1987 by Sun Microsystems, Inc. */ /*- selection.c selection.c, Fri Feb 27 23:51:49 1987 */ /* * Selection module * * The external interfaces of this module are * tc_extend_to(col, row, rank, rect) * tc_report_selection(rank) * tc_deselect(rank) * tc_refresh_selection() */ #include #ifdef REF #include #endif #include "screen.h" #include "tcap.h" extern int CharsPerLine; extern int LinesPerScreen; extern int ScrollY; extern int ScrollLength; extern int ScrollLinesSaved; static int FixedRow, FixedCol, FloatRow, FloatCol; static int ValidSelectionRange = 0 ; static int FixedPointSet = 0 ; static int Selecting = 0 ; static int RectSelection = 0 ; static char spaces[MaxCharsPerLine]; #define SelectionThreshold 32000 StartSelection(col, row) int col, row; { if (FixedPointSet) return; if (row=ScrollLength) row = ScrollLength - 1 ; if (col<0) col = 0 ; if (RectSelection) { if (col>=CharsPerLine) col = CharsPerLine - 1 ; } else { if (col>lines[row]->length) col = lines[row]->length ; } DeSelect(); FixedRow = row ; FixedCol = col ; FixedPointSet = 1 ; } ExtendTo(col, row, strokeoutline) int col, row, strokeoutline; { /* if (row=ScrollY+LinesPerScreen) scroll_to(ScrollY - ScrollLength + ScrollLinesSaved + LinesPerScreen - row) ; */ if (row>=ScrollLength) row = ScrollLength - 1 ; if (col<0) col = 0 ; if (RectSelection) { if (col>=CharsPerLine) col = CharsPerLine - 1 ; } else { if (col>lines[row]->length) col = lines[row]->length ; } if (ValidSelectionRange) { if (FloatRow==FixedRow) { if (FloatCol > FixedCol) ChooseFixed(FixedCol, FixedRow, FloatCol, FloatRow, col, row); else ChooseFixed(FloatCol, FloatRow, FixedCol, FixedRow, col, row); } else if (FloatRow > FixedRow) ChooseFixed(FixedCol, FixedRow, FloatCol, FloatRow, col, row); else ChooseFixed(FloatCol, FloatRow, FixedCol, FixedRow, col, row); } else StartSelection(col, row); FloatRow = row ; FloatCol = col ; if (FloatRow==FixedRow) { if (FloatCol > FixedCol) HiLight(FixedCol, FixedRow, FloatCol, FloatRow, strokeoutline); else HiLight(FloatCol, FloatRow, FixedCol, FixedRow, strokeoutline); } else if (FloatRow > FixedRow) HiLight(FixedCol, FixedRow, FloatCol, FloatRow, strokeoutline); else HiLight(FloatCol, FloatRow, FixedCol, FixedRow, strokeoutline); } ReportSelection() { if (FloatRow==FixedRow) { if (FloatCol > FixedCol) Report(FixedCol, FixedRow, FloatCol, FloatRow); else Report(FloatCol, FloatRow, FixedCol, FixedRow); } else if (FloatRow > FixedRow) Report(FixedCol, FixedRow, FloatCol, FloatRow); else Report(FloatCol, FloatRow, FixedCol, FixedRow); FixedPointSet = 0 ; } ChooseFixed(startcol, startrow, endcol, endrow, col, row) int startcol, startrow, endcol, endrow, col, row; { if (RectSelection) { if (abs(startrow-row) > abs(endrow-row)) row = startrow ; else row = endrow ; if (abs(startcol-col) > abs(endcol-col)) col = startcol ; else col = endcol ; StartSelection(col, row) ; return; } if ((row < startrow) || ((row == startrow) && (col <= startcol))) { StartSelection(endcol, endrow); return; } if ((row > endrow) || ((row == endrow) && (col >= endcol))) { StartSelection(startcol, startrow); return; } if (countchars(startcol, startrow, col, row) < countchars(col, row, endcol, endrow)) { StartSelection(endcol, endrow); } else { StartSelection(startcol, startrow); } } countchars(startcol, startrow, endcol, endrow) int startcol, startrow, endcol, endrow; { int count ; struct line **sp; count = endcol-startcol ; for (sp = &lines[startrow]; startrowlength ; return count; } HiLight(startcol, startrow, endcol, endrow, strokeoutline) int startcol, startrow, endcol, endrow, strokeoutline; { int row, col; struct line **sp; extern int fontisfixedwidth; startrow -= ScrollY ; endrow -= ScrollY ; if (RectSelection) { if (startrow>endrow) { row = startrow ; startrow = endrow ; endrow = row ; } if (startcol>endcol) { col = startcol ; startcol = endcol ; endcol = col ; } if (endrow < 0 || startrow >= LinesPerScreen) return; if (startrow < 0) startrow = 0 ; if (endrow >= LinesPerScreen) endrow = LinesPerScreen - 1 ; if (fontisfixedwidth) { HiLightRect(startcol, startrow, endcol, endrow, strokeoutline); } else { HiLightRect(startcol, startrow, endcol, endrow, strokeoutline); /* punt for now */ } } else { if (startrow < 0) { startrow = 0 ; startcol = 0 ; } if (endrow >= LinesPerScreen) { endrow = LinesPerScreen - 1 ; endcol = screen[endrow]->length ; } StartHiLighting(strokeoutline); for (sp = &lines[startrow+ScrollY], row = startrow; rowlength); else { (*sp)->body[(*sp)->length] = ' ' ; StrHiLightLine((*sp)->body, (*sp)->length + 1); } if (fontisfixedwidth) EndHiLighting(endcol, startcol, startrow); else { (*sp)->body[(*sp)->length] = ' ' ; StrEndHiLighting((*sp)->body, endcol+1, lines[startrow+ScrollY]->body, startcol, startrow); } } } Report(startcol, startrow, endcol, endrow) int startcol, startrow, endcol, endrow; { int row, col, selection_length, extra; struct line **sp; selection_length = 0 ; StartSavingSelection(); if (RectSelection) { RePaintHiLight(); if (startrow>endrow) { row = startrow ; startrow = endrow ; endrow = row ; } if (startcol>endcol) { col = startcol ; startcol = endcol ; endcol = col ; } for (sp = &lines[startrow]; startrow<=endrow; startrow++, sp++) { selection_length += endrow - startrow + 1 ; if (selection_length > SelectionThreshold) { bugprintf("Selection truncated. Max %d chars", SelectionThreshold, 0, 0); break; } if ((*sp)->length < startcol) { SaveSelectionPiece(spaces, endcol-startcol+1); } else if ((*sp)->length < endcol) { SaveSelectionPiece(&((*sp)->body[startcol]), (*sp)->length - startcol); SaveSelectionPiece(spaces, endcol - (*sp)->length + 1); } else { SaveSelectionPiece(&((*sp)->body[startcol]), endcol - startcol + 1); } SaveSelectionPiece("\r", 1); } } else { sp = &lines[startrow] ; if (startrow == endrow) { if (endcol >= (*sp)->length) extra = 0 ; else extra = 1 ; if ((*sp)->buffer_length > 0) SaveSelectionPiece(&((*sp)->body[startcol]), endcol - startcol + extra); (*sp)->changeposition = 0 ; (*sp)->end_of_changes = CharsPerLine ; if ((*sp)->buffer_length > 0) for (; startcol<=endcol; startcol++) (*sp)->prop[startcol] |= PrimSelMode ; } else { selection_length = (*sp)->length - startcol + 1 ; SaveSelectionPiece(&((*sp)->body[startcol]), (*sp)->length - startcol); if ((((*sp)->flags) & LINE_WRAPPED) == 0) SaveSelectionPiece("\r", 1); (*sp)->changeposition = 0 ; (*sp)->end_of_changes = CharsPerLine ; if ((*sp)->buffer_length > 0) for (; startcol<=(*sp)->length; startcol++) (*sp)->prop[startcol] |= PrimSelMode ; for (sp++, startrow++; startrowlength + 1 ; if (selection_length > SelectionThreshold) { break; } if ((*sp)->buffer_length > 0) SaveSelectionPiece((*sp)->body, (*sp)->length); if ((((*sp)->flags) & LINE_WRAPPED) == 0) SaveSelectionPiece("\r", 1); (*sp)->changeposition = 0 ; (*sp)->end_of_changes = CharsPerLine ; if ((*sp)->buffer_length > 0) for (startcol=0; startcol<=(*sp)->length; startcol++) (*sp)->prop[startcol] |= PrimSelMode ; } selection_length += (endcol >= (*sp)->length) ? (*sp)->length+1 : endcol+1; if ((*sp)->buffer_length > 0) SaveSelectionPiece((*sp)->body, (endcol >= (*sp)->length) ? (*sp)->length : endcol+1); if (selection_length > SelectionThreshold) { bugprintf("Selection truncated. Max %d chars", SelectionThreshold, 0, 0); } else { (*sp)->changeposition = 0 ; (*sp)->end_of_changes = CharsPerLine ; if ((*sp)->buffer_length > 0) for (startcol=0; startcol<=((endcol >= (*sp)->length) ? (*sp)->length : endcol); startcol++) (*sp)->prop[startcol] |= PrimSelMode ; } } if (endcol>=(*sp)->length) SaveSelectionPiece("\r", 1); } FinishSavingSelection(); TakeDownOutline(); } DeSelect() { int row, col, endrow; if (ValidSelectionRange == 0) return; if (RectSelection) { RePaintHiLight(); } else { if (FixedRow > FloatRow) { row = FloatRow; endrow = FixedRow; } else { row = FixedRow; endrow = FloatRow; } for (; row<=endrow; row++) { lines[row]->changeposition = 0 ; lines[row]->end_of_changes = CharsPerLine; if (lines[row]->buffer_length > 0) for(col=0; collength+1; col++) lines[row]->prop[col] &= ~PrimSelMode ; } } ClearSelectionPath(); } /* --------------- External Routines Below ------------------- */ tc_init_selection() { int i; char *s; for (i=0, s=spaces; i