summaryrefslogtreecommitdiff
path: root/gtk/gtktextmark.c
diff options
context:
space:
mode:
Diffstat (limited to 'gtk/gtktextmark.c')
-rw-r--r--gtk/gtktextmark.c339
1 files changed, 339 insertions, 0 deletions
diff --git a/gtk/gtktextmark.c b/gtk/gtktextmark.c
new file mode 100644
index 0000000000..739504732b
--- /dev/null
+++ b/gtk/gtktextmark.c
@@ -0,0 +1,339 @@
+/*
+ * tkTextMark.c --
+ *
+ * This file contains the procedure that implement marks for
+ * text widgets.
+ *
+ * Copyright (c) 1994 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id$
+ */
+
+#include "gtktextbtree.h"
+
+gboolean
+gtk_text_mark_is_visible(GtkTextMark *mark)
+{
+ GtkTextLineSegment *seg;
+
+ seg = (GtkTextLineSegment*)mark;
+
+ return seg->body.mark.visible;
+}
+
+char *
+gtk_text_mark_get_name (GtkTextMark *mark)
+{
+ GtkTextLineSegment *seg;
+
+ seg = (GtkTextLineSegment*)mark;
+
+ return g_strdup (seg->body.mark.name);
+}
+
+/*
+ * Macro that determines the size of a mark segment:
+ */
+
+#define MSEG_SIZE ((unsigned) (G_STRUCT_OFFSET(GtkTextLineSegment, body) \
+ + sizeof(GtkTextMarkBody)))
+
+
+GtkTextLineSegment*
+mark_segment_new(GtkTextBTree *tree,
+ gboolean left_gravity,
+ const gchar *name)
+{
+ GtkTextLineSegment *mark;
+
+ mark = (GtkTextLineSegment *) g_malloc0(MSEG_SIZE);
+ mark->body.mark.name = g_strdup(name);
+
+ if (left_gravity)
+ mark->type = &gtk_text_left_mark_type;
+ else
+ mark->type = &gtk_text_right_mark_type;
+
+ mark->byte_count = 0;
+ mark->char_count = 0;
+
+ mark->body.mark.tree = tree;
+ mark->body.mark.line = NULL;
+ mark->next = NULL;
+
+ mark->body.mark.refcount = 1;
+
+ mark->body.mark.visible = FALSE;
+
+ return mark;
+}
+
+void
+mark_segment_ref(GtkTextLineSegment *mark)
+{
+ g_return_if_fail(mark != NULL);
+ g_return_if_fail(mark->type == &gtk_text_right_mark_type ||
+ mark->type == &gtk_text_left_mark_type);
+ g_return_if_fail(mark->body.mark.refcount > 0);
+
+ mark->body.mark.refcount += 1;
+}
+
+void
+mark_segment_unref(GtkTextLineSegment *mark)
+{
+ g_return_if_fail(mark != NULL);
+ g_return_if_fail(mark->type == &gtk_text_right_mark_type ||
+ mark->type == &gtk_text_left_mark_type);
+ g_return_if_fail(mark->body.mark.refcount > 0);
+
+ mark->body.mark.refcount -= 1;
+
+ if (mark->body.mark.refcount == 0)
+ {
+ g_free(mark->body.mark.name);
+
+ g_free(mark);
+ }
+}
+
+/*
+ * Forward references for procedures defined in this file:
+ */
+
+static int mark_segment_delete_func (GtkTextLineSegment *segPtr,
+ GtkTextLine *line,
+ int treeGone);
+static GtkTextLineSegment *mark_segment_cleanup_func (GtkTextLineSegment *segPtr,
+ GtkTextLine *line);
+static void mark_segment_check_func (GtkTextLineSegment *segPtr,
+ GtkTextLine *line);
+
+/*
+ * The following structures declare the "mark" segment types.
+ * There are actually two types for marks, one with left gravity
+ * and one with right gravity. They are identical except for
+ * their gravity property.
+ */
+
+GtkTextLineSegmentClass gtk_text_right_mark_type = {
+ "mark", /* name */
+ FALSE, /* leftGravity */
+ (GtkTextLineSegmentSplitFunc) NULL, /* splitFunc */
+ mark_segment_delete_func, /* deleteFunc */
+ mark_segment_cleanup_func, /* cleanupFunc */
+ (GtkTextLineSegmentLineChangeFunc) NULL, /* lineChangeFunc */
+ mark_segment_check_func /* checkFunc */
+};
+
+GtkTextLineSegmentClass gtk_text_left_mark_type = {
+ "mark", /* name */
+ TRUE, /* leftGravity */
+ (GtkTextLineSegmentSplitFunc) NULL, /* splitFunc */
+ mark_segment_delete_func, /* deleteFunc */
+ mark_segment_cleanup_func, /* cleanupFunc */
+ (GtkTextLineSegmentLineChangeFunc) NULL, /* lineChangeFunc */
+ mark_segment_check_func /* checkFunc */
+};
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * mark_segment_delete_func --
+ *
+ * This procedure is invoked by the text B-tree code whenever
+ * a mark lies in a range of characters being deleted.
+ *
+ * Results:
+ * Returns 1 to indicate that deletion has been rejected.
+ *
+ * Side effects:
+ * None (even if the whole tree is being deleted we don't
+ * free up the mark; it will be done elsewhere).
+ *
+ *--------------------------------------------------------------
+ */
+
+ /* ARGSUSED */
+static int
+mark_segment_delete_func(segPtr, line, treeGone)
+ GtkTextLineSegment *segPtr; /* Segment being deleted. */
+ GtkTextLine *line; /* Line containing segment. */
+ int treeGone; /* Non-zero means the entire tree is
+ * being deleted, so everything must
+ * get cleaned up. */
+{
+ return 1;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * mark_segment_cleanup_func --
+ *
+ * This procedure is invoked by the B-tree code whenever a
+ * mark segment is moved from one line to another.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The line field of the segment gets updated.
+ *
+ *--------------------------------------------------------------
+ */
+
+static GtkTextLineSegment *
+mark_segment_cleanup_func(markPtr, line)
+ GtkTextLineSegment *markPtr; /* Mark segment that's being moved. */
+ GtkTextLine *line; /* Line that now contains segment. */
+{
+ markPtr->body.mark.line = line;
+ return markPtr;
+}
+
+#if 0
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GtkTextInsertDisplayFunc --
+ *
+ * This procedure is called to display the insertion
+ * cursor.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Graphics are drawn.
+ *
+ *--------------------------------------------------------------
+ */
+
+ /* ARGSUSED */
+void
+GtkTextInsertDisplayFunc(chunkPtr, x, y, height, baseline, display, dst, screenY)
+ GtkTextDisplayChunk *chunkPtr; /* Chunk that is to be drawn. */
+ int x; /* X-position in dst at which to
+ * draw this chunk (may differ from
+ * the x-position in the chunk because
+ * of scrolling). */
+ int y; /* Y-position at which to draw this
+ * chunk in dst (x-position is in
+ * the chunk itself). */
+ int height; /* Total height of line. */
+ int baseline; /* Offset of baseline from y. */
+ Display *display; /* Display to use for drawing. */
+ Drawable dst; /* Pixmap or window in which to draw
+ * chunk. */
+ int screenY; /* Y-coordinate in text window that
+ * corresponds to y. */
+{
+ GtkTextView *tkxt = (GtkTextView *) chunkPtr->clientData;
+ int halfWidth = tkxt->insertWidth/2;
+
+ if ((x + halfWidth) < 0) {
+ /*
+ * The insertion cursor is off-screen. Just return.
+ */
+
+ return;
+ }
+
+ /*
+ * As a special hack to keep the cursor visible on mono displays
+ * (or anywhere else that the selection and insertion cursors
+ * have the same color) write the default background in the cursor
+ * area (instead of nothing) when the cursor isn't on. Otherwise
+ * the selection might hide the cursor.
+ */
+
+ if (tkxt->flags & INSERT_ON) {
+ Tk_Fill3DRectangle(tkxt->tkwin, dst, tkxt->insertBorder,
+ x - tkxt->insertWidth/2, y, tkxt->insertWidth,
+ height, tkxt->insertBorderWidth, TK_RELIEF_RAISED);
+ } else if (tkxt->selBorder == tkxt->insertBorder) {
+ Tk_Fill3DRectangle(tkxt->tkwin, dst, tkxt->border,
+ x - tkxt->insertWidth/2, y, tkxt->insertWidth,
+ height, 0, TK_RELIEF_FLAT);
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * InsertUndisplayFunc --
+ *
+ * This procedure is called when the insertion cursor is no
+ * longer at a visible point on the display. It does nothing
+ * right now.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+ /* ARGSUSED */
+static void
+InsertUndisplayFunc(tkxt, chunkPtr)
+ GtkTextView *tkxt; /* Overall information about text
+ * widget. */
+ GtkTextDisplayChunk *chunkPtr; /* Chunk that is about to be freed. */
+{
+ return;
+}
+
+#endif
+/*
+ *--------------------------------------------------------------
+ *
+ * mark_segment_check_func --
+ *
+ * This procedure is invoked by the B-tree code to perform
+ * consistency checks on mark segments.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The procedure panics if it detects anything wrong with
+ * the mark.
+ *
+ *--------------------------------------------------------------
+ */
+
+static void
+mark_segment_check_func(markPtr, line)
+ GtkTextLineSegment *markPtr; /* Segment to check. */
+ GtkTextLine *line; /* Line containing segment. */
+{
+ if (markPtr->body.mark.line != line)
+ g_error("mark_segment_check_func: markPtr->body.mark.line bogus");
+
+ /* No longer do this because we don't have access to btree
+ struct members */
+#if 0
+ /*
+ * Make sure that the mark is still present in the text's mark
+ * hash table.
+ */
+ for (hPtr = Tcl_FirstHashEntry(&markPtr->body.mark.tkxt->markTable,
+ &search); hPtr != markPtr->body.mark.hPtr;
+ hPtr = Tcl_NextHashEntry(&search)) {
+ if (hPtr == NULL) {
+ panic("mark_segment_check_func couldn't find hash table entry for mark");
+ }
+ }
+#endif
+}