1 /* ATK - The Accessibility Toolkit for GTK+
2 * Copyright 2001 Sun Microsystems Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 #include "atkmarshal.h"
26 TEXT_SELECTION_CHANGED,
30 static const gchar * text_attr_name[] = {
60 static const gchar *bool[] = {"false",
62 static const gchar *style[] = {"normal",
65 static const gchar *variant[] = {"normal",
67 static const gchar *stretch[] = {"ultra_condensed",
76 static const gchar *justification[] = {"left",
81 static const gchar *direction[] = {"none",
84 static const gchar *wrap_mode[] = {"none",
87 static const gchar *underline[] = {"none",
92 static void atk_text_base_init (gpointer *g_class);
94 static guint atk_text_signals[LAST_SIGNAL] = { 0 };
99 static GType type = 0;
103 static const GTypeInfo tinfo =
105 sizeof (AtkTextIface),
106 (GBaseInitFunc) atk_text_base_init,
107 (GBaseFinalizeFunc) NULL,
108 (GClassInitFunc) NULL /* atk_text_interface_init */ ,
109 (GClassFinalizeFunc) NULL,
113 type = g_type_register_static (G_TYPE_INTERFACE, "AtkText", &tinfo, 0);
120 atk_text_base_init (gpointer *g_class)
122 static gboolean initialized = FALSE;
127 * Note that text_changed signal supports details "insert", "delete",
128 * possibly "replace".
131 atk_text_signals[TEXT_CHANGED] =
132 g_signal_new ("text_changed",
134 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
135 G_STRUCT_OFFSET (AtkTextIface, text_changed),
136 (GSignalAccumulator) NULL, NULL,
137 atk_marshal_VOID__INT_INT,
139 2, G_TYPE_INT, G_TYPE_INT);
141 atk_text_signals[CARET_MOVED] =
142 g_signal_new ("text_caret_moved",
145 G_STRUCT_OFFSET (AtkTextIface, caret_changed),
146 (GSignalAccumulator) NULL, NULL,
147 g_cclosure_marshal_VOID__INT,
150 atk_text_signals[TEXT_SELECTION_CHANGED] =
151 g_signal_new ("text_selection_changed",
154 G_STRUCT_OFFSET (AtkTextIface, text_selection_changed),
155 (GSignalAccumulator) NULL, NULL,
156 g_cclosure_marshal_VOID__VOID,
167 * @start_offset: start position
168 * @end_offset: end position
170 * Gets the specified text.
172 * Returns: the text from @start_offset up to, but not including @end_offset.
175 atk_text_get_text (AtkText *text,
181 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
183 iface = ATK_TEXT_GET_IFACE (text);
186 return (*(iface->get_text)) (text, start_offset, end_offset);
192 * atk_text_get_character_at_offset:
196 * Gets the specified text.
198 * Returns: the character at @offset.
201 atk_text_get_character_at_offset (AtkText *text,
206 g_return_val_if_fail (ATK_IS_TEXT (text), (gunichar) 0);
208 iface = ATK_TEXT_GET_IFACE (text);
210 if (iface->get_character_at_offset)
211 return (*(iface->get_character_at_offset)) (text, offset);
217 * atk_text_get_text_after_offset:
220 * @boundary_type: An #AtkTextBoundary
221 * @start_offset: the start offset of the returned string.
222 * @end_offset: the end offset of the returned string.
224 * Gets the specified text.
226 * If the boundary_type if ATK_TEXT_BOUNDARY_CHAR the character after the
227 * offset is returned.
229 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_START the returned string
230 * is from the word start after the offset to the next word start.
232 * The returned string will contain the word after the offset if the offset
233 * is inside a word or if the offset is not inside a word.
235 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_END the returned string
236 * is from the word end at or after the offset to the next work end.
238 * The returned string will contain the word after the offset if the offset
239 * is inside a word and will contain the word after the word after the offset
240 * if the offset is not inside a word.
242 * If the boundary type is ATK_TEXT_BOUNDARY_SENTENCE_START the returned
243 * string is from the sentence start after the offset to the next sentence
246 * The returned string will contain the sentence after the offset if the offset
247 * is inside a sentence or if the offset is not inside a sentence.
249 * If the boundary_type is ATK_TEXT_BOUNDARY_SENTENCE_END the returned string
250 * is from the sentence end at or after the offset to the next sentence end.
252 * The returned string will contain the sentence after the offset if the offset
253 * is inside a sentence and will contain the sentence after the sentence
254 * after the offset if the offset is not inside a sentence.
256 * If the boundary type is ATK_TEXT_BOUNDARY_LINE_START the returned
257 * string is from the line start after the offset to the next line start.
259 * If the boundary_type is ATK_TEXT_BOUNDARY_LINE_END the returned string
260 * is from the line end at or after the offset to the next line start.
262 * Returns: the text after @offset bounded by the specified @boundary_type.
265 atk_text_get_text_after_offset (AtkText *text,
267 AtkTextBoundary boundary_type,
272 gint local_start_offset, local_end_offset;
273 gint *real_start_offset, *real_end_offset;
275 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
278 real_start_offset = start_offset;
280 real_start_offset = &local_start_offset;
282 real_end_offset = end_offset;
284 real_end_offset = &local_end_offset;
286 iface = ATK_TEXT_GET_IFACE (text);
288 if (iface->get_text_after_offset)
289 return (*(iface->get_text_after_offset)) (text, offset, boundary_type, real_start_offset, real_end_offset);
295 * atk_text_get_text_at_offset:
298 * @boundary_type: An #AtkTextBoundary
299 * @start_offset: the start offset of the returned string.
300 * @end_offset: the end offset of the returned string.
302 * Gets the specified text.
304 * If the boundary_type if ATK_TEXT_BOUNDARY_CHAR the character at the
305 * offset is returned.
307 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_START the returned string
308 * is from the word start at or before the offset to the word start after
311 * The returned string will contain the word at the offset if the offset
312 * is inside a word and will contain the word before the offset if the
313 * offset is not inside a word.
315 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_END the returned string
316 * is from the word end before the offset to the word end at or after the
319 * The returned string will contain the word at the offset if the offset
320 * is inside a word and will contain the word after to the offset if the
321 * offset is not inside a word.
323 * If the boundary type is ATK_TEXT_BOUNDARY_SENTENCE_START the returned
324 * string is from the sentence start at or before the offset to the sentence
325 * start after the offset.
327 * The returned string will contain the sentence at the offset if the offset
328 * is inside a sentence and will contain the sentence before the offset
329 * if the offset is not inside a sentence.
331 * If the boundary_type is ATK_TEXT_BOUNDARY_SENTENCE_END the returned string
332 * is from the sentence end before the offset to the sentence end at or
335 * The returned string will contain the sentence at the offset if the offset
336 * is inside a sentence and will contain the sentence after the offset
337 * if the offset is not inside a sentence.
339 * If the boundary type is ATK_TEXT_BOUNDARY_LINE_START the returned
340 * string is from the line start at or before the offset to the line
341 * start after the offset.
343 * If the boundary_type is ATK_TEXT_BOUNDARY_LINE_END the returned string
344 * is from the line end before the offset to the line end at or after
347 * Returns: the text at @offset bounded by the specified @boundary_type.
350 atk_text_get_text_at_offset (AtkText *text,
352 AtkTextBoundary boundary_type,
357 gint local_start_offset, local_end_offset;
358 gint *real_start_offset, *real_end_offset;
360 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
363 real_start_offset = start_offset;
365 real_start_offset = &local_start_offset;
367 real_end_offset = end_offset;
369 real_end_offset = &local_end_offset;
371 iface = ATK_TEXT_GET_IFACE (text);
373 if (iface->get_text_at_offset)
374 return (*(iface->get_text_at_offset)) (text, offset, boundary_type, real_start_offset, real_end_offset);
380 * atk_text_get_text_before_offset:
383 * @boundary_type: An #AtkTextBoundary
384 * @start_offset: the start offset of the returned string.
385 * @end_offset: the end offset of the returned string.
387 * Gets the specified text.
389 * If the boundary_type if ATK_TEXT_BOUNDARY_CHAR the character before the
390 * offset is returned.
392 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_START the returned string
393 * is from the word start before the word start before the offset to
394 * the word start before the offset.
396 * The returned string will contain the word before the offset if the offset
397 * is inside a word and will contain the word before the word before the
398 * offset if the offset is not inside a word.
400 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_END the returned string
401 * is from the word end before the word end at or before the offset to the
402 * word end at or before the offset.
404 * The returned string will contain the word before the offset if the offset
405 * is inside a word or if the offset is not inside a word.
407 * If the boundary type is ATK_TEXT_BOUNDARY_SENTENCE_START the returned
408 * string is from the sentence start before the sentence start before
409 * the offset to the sentence start before the offset.
411 * The returned string will contain the sentence before the offset if the
412 * offset is inside a sentence and will contain the sentence before the
413 * sentence before the offset if the offset is not inside a sentence.
415 * If the boundary_type is ATK_TEXT_BOUNDARY_SENTENCE_END the returned string
416 * is from the sentence end before the sentence end at or before the offset to
417 * the sentence end at or before the offset.
419 * The returned string will contain the sentence before the offset if the
420 * offset is inside a sentence or if the offset is not inside a sentence.
422 * If the boundary type is ATK_TEXT_BOUNDARY_LINE_START the returned
423 * string is from the line start before the line start ar or before the offset
424 * to the line start ar or before the offset.
426 * If the boundary_type is ATK_TEXT_BOUNDARY_LINE_END the returned string
427 * is from the line end before the line end before the offset to the
428 * line end before the offset.
430 * Returns: the text before @offset bounded by the specified @boundary_type.
433 atk_text_get_text_before_offset (AtkText *text,
435 AtkTextBoundary boundary_type,
440 gint local_start_offset, local_end_offset;
441 gint *real_start_offset, *real_end_offset;
443 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
446 real_start_offset = start_offset;
448 real_start_offset = &local_start_offset;
450 real_end_offset = end_offset;
452 real_end_offset = &local_end_offset;
454 iface = ATK_TEXT_GET_IFACE (text);
456 if (iface->get_text_before_offset)
457 return (*(iface->get_text_before_offset)) (text, offset, boundary_type, real_start_offset, real_end_offset);
463 * atk_text_get_caret_offset:
466 * Gets the offset position of the caret (cursor).
468 * Returns: the offset position of the caret (cursor).
471 atk_text_get_caret_offset (AtkText *text)
475 g_return_val_if_fail (ATK_IS_TEXT (text), -1);
477 iface = ATK_TEXT_GET_IFACE (text);
479 if (iface->get_caret_offset)
480 return (*(iface->get_caret_offset)) (text);
486 * atk_text_get_character_extents:
489 * @x: x-position of character
490 * @y: y-position of character
491 * @width: width of character
492 * @height: height of character
493 * @coords: specify whether coordinates are relative to the screen or widget window
495 * Given an @offset, the @x, @y, @width, and @height values are filled
499 atk_text_get_character_extents (AtkText *text,
508 gint local_x, local_y, local_width, local_height;
509 gint *real_x, *real_y, *real_width, *real_height;
511 g_return_if_fail (ATK_IS_TEXT (text));
524 real_width = &local_width;
526 real_height = height;
528 real_height = &local_height;
530 iface = ATK_TEXT_GET_IFACE (text);
532 if (iface->get_character_extents)
533 (*(iface->get_character_extents)) (text, offset, real_x, real_y, real_width, real_height, coords);
544 *atk_text_get_run_attributes:
546 *@offset: the offset at which to get the attributes
547 *@start_offset: the address to put the start offset of the range
548 *@end_offset: the address to put the end offset of the range
550 *Creates an #AtkAttributeSet which consists of the attributes explicitly
551 *set at the position @offset in the text. @start_offset and @end_offset are
552 *set to the start and end of the range around @offset where the attributes are
553 *invariant. See the enum AtkTextAttribute for types of text attributes that
554 *can be returned. Note that other attributes may also be returned.
556 *Returns: an #AtkAttributeSet which contains the attributes explicitly set
557 *at @offset. This #AtkAttributeSet should be freed by a call to
558 *atk_attribute_set_free().
561 atk_text_get_run_attributes (AtkText *text,
567 gint local_start_offset, local_end_offset;
568 gint *real_start_offset, *real_end_offset;
570 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
573 real_start_offset = start_offset;
575 real_start_offset = &local_start_offset;
577 real_end_offset = end_offset;
579 real_end_offset = &local_end_offset;
581 iface = ATK_TEXT_GET_IFACE (text);
583 if (iface->get_run_attributes)
584 return (*(iface->get_run_attributes)) (text, offset, real_start_offset, real_end_offset);
590 *atk_text_get_default_attributes:
593 *Creates an #AtkAttributeSet which consists of the default values of
594 *attributes for the text. See the enum AtkTextAttribute for types of text
595 *attributes that can be returned. Note that other attributes may also be
598 *Returns: an #AtkAttributeSet which contains the default values of attributes.
599 *at @offset. This #AtkAttributeSet should be freed by a call to
600 *atk_attribute_set_free().
603 atk_text_get_default_attributes (AtkText *text)
607 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
609 iface = ATK_TEXT_GET_IFACE (text);
611 if (iface->get_default_attributes)
612 return (*(iface->get_default_attributes)) (text);
618 * atk_text_get_character_count:
621 * Gets the character count.
623 * Returns: the number of characters.
626 atk_text_get_character_count (AtkText *text)
630 g_return_val_if_fail (ATK_IS_TEXT (text), -1);
632 iface = ATK_TEXT_GET_IFACE (text);
634 if (iface->get_character_count)
635 return (*(iface->get_character_count)) (text);
641 * atk_text_get_offset_at_point:
643 * @x: screen x-position of character
644 * @y: screen y-position of character
645 * @coords: specify whether coordinates are relative to the screen or
648 * Gets the offset of the character located at coordinates @x and @y. @x and @y
649 * are interpreted as being relative to the screen or this widget's window
650 * depending on @coords.
652 * Returns: the offset to the character which is located at
653 * the specified @x and @y coordinates.
656 atk_text_get_offset_at_point (AtkText *text,
663 g_return_val_if_fail (ATK_IS_TEXT (text), -1);
665 iface = ATK_TEXT_GET_IFACE (text);
667 if (iface->get_offset_at_point)
668 return (*(iface->get_offset_at_point)) (text, x, y, coords);
674 * atk_text_get_n_selections:
677 * Gets the number of selected regions.
679 * Returns: The number of selected regions, or -1 if a failure
683 atk_text_get_n_selections (AtkText *text)
687 g_return_val_if_fail (ATK_IS_TEXT (text), -1);
689 iface = ATK_TEXT_GET_IFACE (text);
691 if (iface->get_n_selections)
692 return (*(iface->get_n_selections)) (text);
698 * atk_text_get_selection:
700 * @selection_num: The selection number. The selected regions are
701 * assigned numbers that correspond to how far the region is from the
702 * start of the text. The selected region closest to the beginning
703 * of the text region is assigned the number 0, etc. Note that adding,
704 * moving or deleting a selected region can change the numbering.
705 * @start_offset: passes back the start position of the selected region
706 * @end_offset: passes back the end position of the selected region
708 * Gets the text from the specified selection.
710 * Returns: the selected text.
713 atk_text_get_selection (AtkText *text,
719 gint local_start_offset, local_end_offset;
720 gint *real_start_offset, *real_end_offset;
722 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
725 real_start_offset = start_offset;
727 real_start_offset = &local_start_offset;
729 real_end_offset = end_offset;
731 real_end_offset = &local_end_offset;
733 iface = ATK_TEXT_GET_IFACE (text);
735 if (iface->get_selection)
737 return (*(iface->get_selection)) (text, selection_num,
738 real_start_offset, real_end_offset);
745 * atk_text_add_selection:
747 * @start_offset: the start position of the selected region
748 * @end_offset: the end position of the selected region
750 * Adds a selection bounded by the specified offsets.
752 * Returns: %TRUE if success, %FALSE otherwise
755 atk_text_add_selection (AtkText *text,
761 g_return_val_if_fail (ATK_IS_TEXT (text), FALSE);
763 iface = ATK_TEXT_GET_IFACE (text);
765 if (iface->add_selection)
766 return (*(iface->add_selection)) (text, start_offset, end_offset);
772 * atk_text_remove_selection:
774 * @selection_num: The selection number. The selected regions are
775 * assigned numbers that correspond to how far the region is from the
776 * start of the text. The selected region closest to the beginning
777 * of the text region is assigned the number 0, etc. Note that adding,
778 * moving or deleting a selected region can change the numbering.
780 * Removes the specified selection.
782 * Returns: %TRUE if success, %FALSE otherwise
785 atk_text_remove_selection (AtkText *text,
790 g_return_val_if_fail (ATK_IS_TEXT (text), FALSE);
792 iface = ATK_TEXT_GET_IFACE (text);
794 if (iface->remove_selection)
795 return (*(iface->remove_selection)) (text, selection_num);
801 * atk_text_set_selection:
803 * @selection_num: The selection number. The selected regions are
804 * assigned numbers that correspond to how far the region is from the
805 * start of the text. The selected region closest to the beginning
806 * of the text region is assigned the number 0, etc. Note that adding,
807 * moving or deleting a selected region can change the numbering.
808 * @start_offset: the new start position of the selection
809 * @end_offset: the new end position of the selection
811 * Changes the start and end offset of the specified selection.
813 * Returns: %TRUE if success, %FALSE otherwise
816 atk_text_set_selection (AtkText *text,
823 g_return_val_if_fail (ATK_IS_TEXT (text), FALSE);
825 iface = ATK_TEXT_GET_IFACE (text);
827 if (iface->set_selection)
829 return (*(iface->set_selection)) (text, selection_num,
830 start_offset, end_offset);
837 * atk_text_set_caret_offset:
841 * Sets the caret (cursor) position to the specified @offset.
843 * Returns: %TRUE if success, %FALSE otherwise.
846 atk_text_set_caret_offset (AtkText *text,
851 g_return_val_if_fail (ATK_IS_TEXT (text), FALSE);
853 iface = ATK_TEXT_GET_IFACE (text);
855 if (iface->set_caret_offset)
857 return (*(iface->set_caret_offset)) (text, offset);
866 * atk_attribute_set_free:
867 * @attrib_set: The #AtkAttributeSet to free
869 * Frees the memory used by an #AtkAttributeSet, including all its
873 atk_attribute_set_free(AtkAttributeSet *attrib_set)
890 g_slist_free (attrib_set);
894 * atk_attribute_get_name:
895 * @attr: The #AtkTextAttribute whose name is required
897 * Gets the name corresponding to the #AtkTextAttribute
899 * Returns: a string containing the name; this string should not be freed
901 G_CONST_RETURN gchar*
902 atk_attribute_get_name (AtkTextAttribute attr)
904 g_assert (attr >= 0 && attr <= ATK_TEXT_ATTR_STYLE);
905 return text_attr_name[attr];
909 * atk_attribute_get_value:
910 * @attr: The #AtkTextAttribute for which a value is required
911 * @index: The index of the required value
913 * Gets the value for the index of the #AtkTextAttribute
915 * Returns: a string containing the value; this string should not be freed;
916 * NULL is returned if there are no values maintained for the attr value.
918 G_CONST_RETURN gchar*
919 atk_attribute_get_value (AtkTextAttribute attr,
924 case ATK_TEXT_ATTR_INVISIBLE:
925 case ATK_TEXT_ATTR_EDITABLE:
926 case ATK_TEXT_ATTR_BG_FULL_HEIGHT:
927 case ATK_TEXT_ATTR_STRIKETHROUGH:
928 case ATK_TEXT_ATTR_BG_STIPPLE:
929 case ATK_TEXT_ATTR_FG_STIPPLE:
930 g_assert (index >= 0 && index < 2);
932 case ATK_TEXT_ATTR_UNDERLINE:
933 g_assert (index >= 0 && index < 4);
934 return underline[index];
935 case ATK_TEXT_ATTR_WRAP_MODE:
936 g_assert (index >= 0 && index < 3);
937 return wrap_mode[index];
938 case ATK_TEXT_ATTR_DIRECTION:
939 g_assert (index >= 0 && index < 3);
940 return direction[index];
941 case ATK_TEXT_ATTR_JUSTIFICATION:
942 g_assert (index >= 0 && index < 3);
943 return justification[index];
944 case ATK_TEXT_ATTR_STRETCH:
945 g_assert (index >= 0 && index < 9);
946 return stretch[index];
947 case ATK_TEXT_ATTR_VARIANT:
948 g_assert (index >= 0 && index < 2);
949 return variant[index];
950 case ATK_TEXT_ATTR_STYLE:
951 g_assert (index >= 0 && index < 3);