]> Pileus Git - ~andy/gtk/blob - gtk/gtktextmark.c
make it a static function
[~andy/gtk] / gtk / gtktextmark.c
1 /* gtktextmark.c - mark segments
2  * 
3  * Copyright (c) 1994 The Regents of the University of California.
4  * Copyright (c) 1994-1997 Sun Microsystems, Inc.
5  * Copyright (c) 2000      Red Hat, Inc.
6  * Tk -> Gtk port by Havoc Pennington <hp@redhat.com>
7  *
8  * This software is copyrighted by the Regents of the University of
9  * California, Sun Microsystems, Inc., and other parties.  The
10  * following terms apply to all files associated with the software
11  * unless explicitly disclaimed in individual files.
12  * 
13  * The authors hereby grant permission to use, copy, modify,
14  * distribute, and license this software and its documentation for any
15  * purpose, provided that existing copyright notices are retained in
16  * all copies and that this notice is included verbatim in any
17  * distributions. No written agreement, license, or royalty fee is
18  * required for any of the authorized uses.  Modifications to this
19  * software may be copyrighted by their authors and need not follow
20  * the licensing terms described here, provided that the new terms are
21  * clearly indicated on the first page of each file where they apply.
22  * 
23  * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
24  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
25  * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,
26  * OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED
27  * OF THE POSSIBILITY OF SUCH DAMAGE.
28  * 
29  * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
30  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
32  * NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
33  * AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
34  * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
35  *
36  * GOVERNMENT USE: If you are acquiring this software on behalf of the
37  * U.S. government, the Government shall have only "Restricted Rights"
38  * in the software and related documentation as defined in the Federal
39  * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
40  * are acquiring the software on behalf of the Department of Defense,
41  * the software shall be classified as "Commercial Computer Software"
42  * and the Government shall have only "Restricted Rights" as defined
43  * in Clause 252.227-7013 (c) (1) of DFARs.  Notwithstanding the
44  * foregoing, the authors grant the U.S. Government and others acting
45  * in its behalf permission to use and distribute the software in
46  * accordance with the terms specified in this license.
47  * 
48  */
49
50
51 #include "gtktextbtree.h"
52
53 static void gtk_text_mark_init       (GtkTextMark      *mark);
54 static void gtk_text_mark_class_init (GtkTextMarkClass *klass);
55 static void gtk_text_mark_finalize   (GObject          *obj);
56
57
58 static gpointer parent_class = NULL;
59
60 GType
61 gtk_text_mark_get_type (void)
62 {
63   static GType object_type = 0;
64
65   if (!object_type)
66     {
67       static const GTypeInfo object_info =
68       {
69         sizeof (GtkTextMarkClass),
70         (GBaseInitFunc) NULL,
71         (GBaseFinalizeFunc) NULL,
72         (GClassInitFunc) gtk_text_mark_class_init,
73         NULL,           /* class_finalize */
74         NULL,           /* class_data */
75         sizeof (GtkTextMark),
76         0,              /* n_preallocs */
77         (GInstanceInitFunc) gtk_text_mark_init,
78       };
79       
80       object_type = g_type_register_static (G_TYPE_OBJECT,
81                                             "GtkTextMark",
82                                             &object_info);
83     }
84   
85   return object_type;
86 }
87
88 static void
89 gtk_text_mark_init (GtkTextMark *mark)
90 {
91   mark->segment = NULL;
92 }
93
94 static void
95 gtk_text_mark_class_init (GtkTextMarkClass *klass)
96 {
97   GObjectClass *object_class = G_OBJECT_CLASS (klass);
98
99   parent_class = g_type_class_peek_parent (klass);
100
101   object_class->finalize = gtk_text_mark_finalize;
102 }
103
104 static void
105 gtk_text_mark_finalize (GObject *obj)
106 {
107   GtkTextMark *mark;
108   GtkTextLineSegment *seg;
109
110   mark = GTK_TEXT_MARK (obj);
111
112   seg = mark->segment;
113
114   if (seg)
115     {
116       g_return_if_fail (seg->body.mark.tree == NULL);
117
118       if (seg->body.mark.tree != NULL)
119         g_warning ("GtkTextMark being finalized while still in the buffer; "
120                    "someone removed a reference they didn't own! Crash "
121                    "impending");
122       
123       g_free (seg->body.mark.name);
124       g_free (seg);
125
126       mark->segment = NULL;
127     }
128 }
129
130 gboolean
131 gtk_text_mark_is_visible(GtkTextMark *mark)
132 {
133   GtkTextLineSegment *seg;
134
135   seg = mark->segment;
136
137   return seg->body.mark.visible;
138 }
139
140 const char *
141 gtk_text_mark_get_name (GtkTextMark *mark)
142 {
143   GtkTextLineSegment *seg;
144
145   seg = mark->segment;
146
147   return seg->body.mark.name;
148 }
149
150 gboolean
151 gtk_text_mark_get_deleted (GtkTextMark *mark)
152 {
153   GtkTextLineSegment *seg;
154   
155   g_return_val_if_fail (mark != NULL, FALSE);
156
157   seg = mark->segment;
158
159   if (seg == NULL)
160     return TRUE;
161   
162   return seg->body.mark.tree == NULL;
163 }
164
165 /*
166  * Macro that determines the size of a mark segment:
167  */
168
169 #define MSEG_SIZE ((unsigned) (G_STRUCT_OFFSET(GtkTextLineSegment, body) \
170         + sizeof(GtkTextMarkBody)))
171
172
173 GtkTextLineSegment*
174 _mark_segment_new (GtkTextBTree *tree,
175                    gboolean      left_gravity,
176                    const gchar  *name)
177 {
178   GtkTextLineSegment *mark;
179
180   mark = (GtkTextLineSegment *) g_malloc0 (MSEG_SIZE);
181   mark->body.mark.name = g_strdup (name);
182
183   if (left_gravity)
184     mark->type = &gtk_text_left_mark_type;
185   else
186     mark->type = &gtk_text_right_mark_type;
187   
188   mark->byte_count = 0;
189   mark->char_count = 0;
190
191   mark->body.mark.obj = g_object_new (GTK_TYPE_TEXT_MARK, NULL);
192   mark->body.mark.obj->segment = mark;
193   
194   mark->body.mark.tree = tree;
195   mark->body.mark.line = NULL;
196   mark->next = NULL;
197
198   mark->body.mark.visible = FALSE;
199   mark->body.mark.not_deleteable = FALSE;
200   
201   return mark;
202 }
203
204 static int                 mark_segment_delete_func  (GtkTextLineSegment *segPtr,
205                                                       GtkTextLine        *line,
206                                                       int                 treeGone);
207 static GtkTextLineSegment *mark_segment_cleanup_func (GtkTextLineSegment *segPtr,
208                                                       GtkTextLine        *line);
209 static void                mark_segment_check_func   (GtkTextLineSegment *segPtr,
210                                                       GtkTextLine        *line);
211
212
213 /*
214  * The following structures declare the "mark" segment types.
215  * There are actually two types for marks, one with left gravity
216  * and one with right gravity.  They are identical except for
217  * their gravity property.
218  */
219
220 GtkTextLineSegmentClass gtk_text_right_mark_type = {
221     "mark",                                             /* name */
222     FALSE,                                              /* leftGravity */
223     NULL,                                               /* splitFunc */
224     mark_segment_delete_func,                           /* deleteFunc */
225     mark_segment_cleanup_func,                          /* cleanupFunc */
226     NULL,                                               /* lineChangeFunc */
227     mark_segment_check_func                             /* checkFunc */
228 };
229
230 GtkTextLineSegmentClass gtk_text_left_mark_type = {
231     "mark",                                             /* name */
232     TRUE,                                               /* leftGravity */
233     NULL,                                               /* splitFunc */
234     mark_segment_delete_func,                           /* deleteFunc */
235     mark_segment_cleanup_func,                          /* cleanupFunc */
236     NULL,                                               /* lineChangeFunc */
237     mark_segment_check_func                             /* checkFunc */
238 };
239
240 /*
241  *--------------------------------------------------------------
242  *
243  * mark_segment_delete_func --
244  *
245  *      This procedure is invoked by the text B-tree code whenever
246  *      a mark lies in a range of characters being deleted.
247  *
248  * Results:
249  *      Returns 1 to indicate that deletion has been rejected.
250  *
251  * Side effects:
252  *      None (even if the whole tree is being deleted we don't
253  *      free up the mark;  it will be done elsewhere).
254  *
255  *--------------------------------------------------------------
256  */
257
258 static gboolean
259 mark_segment_delete_func (GtkTextLineSegment *segPtr,
260                           GtkTextLine        *line,
261                           gboolean            tree_gone)
262 {
263   return TRUE;
264 }
265
266 /*
267  *--------------------------------------------------------------
268  *
269  * mark_segment_cleanup_func --
270  *
271  *      This procedure is invoked by the B-tree code whenever a
272  *      mark segment is moved from one line to another.
273  *
274  * Results:
275  *      None.
276  *
277  * Side effects:
278  *      The line field of the segment gets updated.
279  *
280  *--------------------------------------------------------------
281  */
282
283 static GtkTextLineSegment *
284 mark_segment_cleanup_func(GtkTextLineSegment *seg,
285                           GtkTextLine        *line)
286 {
287   /* not sure why Tk did this here and not in LineChangeFunc */
288   seg->body.mark.line = line;
289   return seg;
290 }
291
292 /*
293  *--------------------------------------------------------------
294  *
295  * mark_segment_check_func --
296  *
297  *      This procedure is invoked by the B-tree code to perform
298  *      consistency checks on mark segments.
299  *
300  * Results:
301  *      None.
302  *
303  * Side effects:
304  *      The procedure panics if it detects anything wrong with
305  *      the mark.
306  *
307  *--------------------------------------------------------------
308  */
309
310 static void
311 mark_segment_check_func(GtkTextLineSegment *seg,
312                         GtkTextLine        *line)
313 {
314   if (seg->body.mark.line != line)
315     g_error("mark_segment_check_func: seg->body.mark.line bogus");
316 }