Bug Summary

File:/rootdir/_build/../src/bteaccess.cc
Warning:line 1428, column 9
This statement is never executed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name bteaccess.cc -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/_build -resource-dir /usr/lib/llvm-14/lib/clang/14.0.6 -I src/libbte-2.91.so.0.6500.0.p -I src -I ../src -I . -I .. -I src/bte -I ../src/bte -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/uuid -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/p11-kit-1 -I /usr/include/ctk-3.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -D _FILE_OFFSET_BITS=64 -D G_LOG_DOMAIN="BTE" -D LOCALEDIR="/usr/local/share/locale" -D BTE_DISABLE_DEPRECATION_WARNINGS -D BTE_COMPILATION -U PARSER_INCLUDE_NOP -D CDK_VERSION_MIN_REQUIRED=(G_ENCODE_VERSION(3,18)) -D CDK_VERSION_MAX_ALLOWED=(G_ENCODE_VERSION(3,20)) -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/x86_64-linux-gnu/c++/12 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/backward -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.6/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-address-of-packed-member -Wno-missing-field-initializers -Wno-packed -Wno-switch-enum -Wno-unused-parameter -Wwrite-strings -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/rootdir/_build -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-12-29-232038-10783-1 -x c++ ../src/bteaccess.cc
1/*
2 * Copyright (C) 2002,2003 Red Hat, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
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 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19/*
20 * SECTION: bte-access
21 * @short_description: Accessibility peer of #BteTerminal
22 *
23 * The accessibility peer of a #BteTerminal, implementing GNOME's accessibility
24 * framework.
25 */
26
27#include "config.h"
28
29#include <atk/atk.h>
30#include <ctk/ctk.h>
31#include <ctk/ctk-a11y.h>
32#include <string.h>
33#include "debug.h"
34#include <bte/bte.h>
35#include "bteaccess.h"
36#include "bteinternal.hh"
37
38#ifdef HAVE_LOCALE_H
39#include <locale.h>
40#endif
41#include <glib/gi18n-lib.h>
42
43#define TERMINAL_FROM_ACCESSIBLE(a)(((((BteTerminal*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_accessible_get_widget(((((CtkAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((a)), ((ctk_accessible_get_type ())))))))
)), ((bte_terminal_get_type())))))))
(BTE_TERMINAL(ctk_accessible_get_widget(CTK_ACCESSIBLE(a)))((((BteTerminal*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_accessible_get_widget(((((CtkAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((a)), ((ctk_accessible_get_type ())))))))
)), ((bte_terminal_get_type()))))))
)
44
45#define IMPL(t)(_bte_terminal_get_impl(t)) (_bte_terminal_get_impl(t))
46#define IMPL_FROM_WIDGET(w)((_bte_terminal_get_impl(((((BteTerminal*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((w)), ((bte_terminal_get_type())))))))))
(IMPL(BTE_TERMINAL(w))(_bte_terminal_get_impl(((((BteTerminal*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((w)), ((bte_terminal_get_type()))))))))
)
47#define IMPL_FROM_ACCESSIBLE(a)(((_bte_terminal_get_impl(((((BteTerminal*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((ctk_accessible_get_widget(((((CtkAccessible
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((a)
), ((ctk_accessible_get_type ()))))))))), ((bte_terminal_get_type
()))))))))))
(IMPL_FROM_WIDGET(ctk_accessible_get_widget(CTK_ACCESSIBLE(a)))((_bte_terminal_get_impl(((((BteTerminal*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((ctk_accessible_get_widget(((((CtkAccessible
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((a)
), ((ctk_accessible_get_type ()))))))))), ((bte_terminal_get_type
())))))))))
)
48
49enum {
50 ACTION_MENU,
51 LAST_ACTION
52};
53
54typedef struct _BteTerminalAccessiblePrivate {
55 gboolean snapshot_contents_invalid; /* This data is stale. */
56 gboolean snapshot_caret_invalid; /* This data is stale. */
57 GString *snapshot_text; /* Pointer to UTF-8 text. */
58 GArray *snapshot_characters; /* Offsets to character begin points. */
59 GArray *snapshot_attributes; /* Attributes, per byte. */
60 GArray *snapshot_linebreaks; /* Offsets to line breaks. */
61 gint snapshot_caret; /* Location of the cursor (in characters). */
62 gboolean text_caret_moved_pending;
63
64 char *action_descriptions[LAST_ACTION];
65} BteTerminalAccessiblePrivate;
66
67enum direction {
68 direction_previous = -1,
69 direction_current = 0,
70 direction_next = 1
71};
72
73static gunichar bte_terminal_accessible_get_character_at_offset(AtkText *text,
74 gint offset);
75
76static const char *bte_terminal_accessible_action_names[] = {
77 "menu",
78 NULL__null
79};
80
81static const char *bte_terminal_accessible_action_descriptions[] = {
82 "Popup context menu",
83 NULL__null
84};
85
86static void bte_terminal_accessible_text_iface_init(AtkTextIface *iface);
87static void bte_terminal_accessible_component_iface_init(AtkComponentIface *component);
88static void bte_terminal_accessible_action_iface_init(AtkActionIface *action);
89
90G_DEFINE_TYPE_WITH_CODE (BteTerminalAccessible, _bte_terminal_accessible, CTK_TYPE_WIDGET_ACCESSIBLE,static void _bte_terminal_accessible_init (BteTerminalAccessible
*self); static void _bte_terminal_accessible_class_init (BteTerminalAccessibleClass
*klass); static GType _bte_terminal_accessible_get_type_once
(void); static gpointer _bte_terminal_accessible_parent_class
= __null; static gint BteTerminalAccessible_private_offset; static
void _bte_terminal_accessible_class_intern_init (gpointer klass
) { _bte_terminal_accessible_parent_class = g_type_class_peek_parent
(klass); if (BteTerminalAccessible_private_offset != 0) g_type_class_adjust_private_offset
(klass, &BteTerminalAccessible_private_offset); _bte_terminal_accessible_class_init
((BteTerminalAccessibleClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer _bte_terminal_accessible_get_instance_private
(BteTerminalAccessible *self) { return (((gpointer) ((guint8
*) (self) + (glong) (BteTerminalAccessible_private_offset))))
; } GType _bte_terminal_accessible_get_type (void) { static gsize
static_g_define_type_id = 0; if ((__extension__ ({ static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); (void) (0 ? (gpointer) *(
&static_g_define_type_id) : __null); (!(__extension__ ({ static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); gpointer gapg_temp_newval
; gpointer *gapg_temp_atomic = (gpointer *)(&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = _bte_terminal_accessible_get_type_once
(); (__extension__ ({ static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } [[gnu::noinline]] static GType _bte_terminal_accessible_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((ctk_widget_accessible_get_type ()), g_intern_static_string
("BteTerminalAccessible"), sizeof (BteTerminalAccessibleClass
), (GClassInitFunc)(void (*)(void)) _bte_terminal_accessible_class_intern_init
, sizeof (BteTerminalAccessible), (GInstanceInitFunc)(void (*
)(void)) _bte_terminal_accessible_init, (GTypeFlags) 0); { {{
BteTerminalAccessible_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (BteTerminalAccessiblePrivate)); }
{ const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) bte_terminal_accessible_text_iface_init, __null
, __null }; g_type_add_interface_static (g_define_type_id, (atk_text_get_type
()), &g_implement_interface_info); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) bte_terminal_accessible_component_iface_init, __null,
__null }; g_type_add_interface_static (g_define_type_id, (atk_component_get_type
()), &g_implement_interface_info); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) bte_terminal_accessible_action_iface_init, __null, __null
}; g_type_add_interface_static (g_define_type_id, (atk_action_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
91 G_ADD_PRIVATE (BteTerminalAccessible)static void _bte_terminal_accessible_init (BteTerminalAccessible
*self); static void _bte_terminal_accessible_class_init (BteTerminalAccessibleClass
*klass); static GType _bte_terminal_accessible_get_type_once
(void); static gpointer _bte_terminal_accessible_parent_class
= __null; static gint BteTerminalAccessible_private_offset; static
void _bte_terminal_accessible_class_intern_init (gpointer klass
) { _bte_terminal_accessible_parent_class = g_type_class_peek_parent
(klass); if (BteTerminalAccessible_private_offset != 0) g_type_class_adjust_private_offset
(klass, &BteTerminalAccessible_private_offset); _bte_terminal_accessible_class_init
((BteTerminalAccessibleClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer _bte_terminal_accessible_get_instance_private
(BteTerminalAccessible *self) { return (((gpointer) ((guint8
*) (self) + (glong) (BteTerminalAccessible_private_offset))))
; } GType _bte_terminal_accessible_get_type (void) { static gsize
static_g_define_type_id = 0; if ((__extension__ ({ static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); (void) (0 ? (gpointer) *(
&static_g_define_type_id) : __null); (!(__extension__ ({ static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); gpointer gapg_temp_newval
; gpointer *gapg_temp_atomic = (gpointer *)(&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = _bte_terminal_accessible_get_type_once
(); (__extension__ ({ static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } [[gnu::noinline]] static GType _bte_terminal_accessible_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((ctk_widget_accessible_get_type ()), g_intern_static_string
("BteTerminalAccessible"), sizeof (BteTerminalAccessibleClass
), (GClassInitFunc)(void (*)(void)) _bte_terminal_accessible_class_intern_init
, sizeof (BteTerminalAccessible), (GInstanceInitFunc)(void (*
)(void)) _bte_terminal_accessible_init, (GTypeFlags) 0); { {{
BteTerminalAccessible_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (BteTerminalAccessiblePrivate)); }
{ const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) bte_terminal_accessible_text_iface_init, __null
, __null }; g_type_add_interface_static (g_define_type_id, (atk_text_get_type
()), &g_implement_interface_info); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) bte_terminal_accessible_component_iface_init, __null,
__null }; g_type_add_interface_static (g_define_type_id, (atk_component_get_type
()), &g_implement_interface_info); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) bte_terminal_accessible_action_iface_init, __null, __null
}; g_type_add_interface_static (g_define_type_id, (atk_action_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
92 G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, bte_terminal_accessible_text_iface_init)static void _bte_terminal_accessible_init (BteTerminalAccessible
*self); static void _bte_terminal_accessible_class_init (BteTerminalAccessibleClass
*klass); static GType _bte_terminal_accessible_get_type_once
(void); static gpointer _bte_terminal_accessible_parent_class
= __null; static gint BteTerminalAccessible_private_offset; static
void _bte_terminal_accessible_class_intern_init (gpointer klass
) { _bte_terminal_accessible_parent_class = g_type_class_peek_parent
(klass); if (BteTerminalAccessible_private_offset != 0) g_type_class_adjust_private_offset
(klass, &BteTerminalAccessible_private_offset); _bte_terminal_accessible_class_init
((BteTerminalAccessibleClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer _bte_terminal_accessible_get_instance_private
(BteTerminalAccessible *self) { return (((gpointer) ((guint8
*) (self) + (glong) (BteTerminalAccessible_private_offset))))
; } GType _bte_terminal_accessible_get_type (void) { static gsize
static_g_define_type_id = 0; if ((__extension__ ({ static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); (void) (0 ? (gpointer) *(
&static_g_define_type_id) : __null); (!(__extension__ ({ static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); gpointer gapg_temp_newval
; gpointer *gapg_temp_atomic = (gpointer *)(&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = _bte_terminal_accessible_get_type_once
(); (__extension__ ({ static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } [[gnu::noinline]] static GType _bte_terminal_accessible_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((ctk_widget_accessible_get_type ()), g_intern_static_string
("BteTerminalAccessible"), sizeof (BteTerminalAccessibleClass
), (GClassInitFunc)(void (*)(void)) _bte_terminal_accessible_class_intern_init
, sizeof (BteTerminalAccessible), (GInstanceInitFunc)(void (*
)(void)) _bte_terminal_accessible_init, (GTypeFlags) 0); { {{
BteTerminalAccessible_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (BteTerminalAccessiblePrivate)); }
{ const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) bte_terminal_accessible_text_iface_init, __null
, __null }; g_type_add_interface_static (g_define_type_id, (atk_text_get_type
()), &g_implement_interface_info); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) bte_terminal_accessible_component_iface_init, __null,
__null }; g_type_add_interface_static (g_define_type_id, (atk_component_get_type
()), &g_implement_interface_info); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) bte_terminal_accessible_action_iface_init, __null, __null
}; g_type_add_interface_static (g_define_type_id, (atk_action_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
93 G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, bte_terminal_accessible_component_iface_init)static void _bte_terminal_accessible_init (BteTerminalAccessible
*self); static void _bte_terminal_accessible_class_init (BteTerminalAccessibleClass
*klass); static GType _bte_terminal_accessible_get_type_once
(void); static gpointer _bte_terminal_accessible_parent_class
= __null; static gint BteTerminalAccessible_private_offset; static
void _bte_terminal_accessible_class_intern_init (gpointer klass
) { _bte_terminal_accessible_parent_class = g_type_class_peek_parent
(klass); if (BteTerminalAccessible_private_offset != 0) g_type_class_adjust_private_offset
(klass, &BteTerminalAccessible_private_offset); _bte_terminal_accessible_class_init
((BteTerminalAccessibleClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer _bte_terminal_accessible_get_instance_private
(BteTerminalAccessible *self) { return (((gpointer) ((guint8
*) (self) + (glong) (BteTerminalAccessible_private_offset))))
; } GType _bte_terminal_accessible_get_type (void) { static gsize
static_g_define_type_id = 0; if ((__extension__ ({ static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); (void) (0 ? (gpointer) *(
&static_g_define_type_id) : __null); (!(__extension__ ({ static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); gpointer gapg_temp_newval
; gpointer *gapg_temp_atomic = (gpointer *)(&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = _bte_terminal_accessible_get_type_once
(); (__extension__ ({ static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } [[gnu::noinline]] static GType _bte_terminal_accessible_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((ctk_widget_accessible_get_type ()), g_intern_static_string
("BteTerminalAccessible"), sizeof (BteTerminalAccessibleClass
), (GClassInitFunc)(void (*)(void)) _bte_terminal_accessible_class_intern_init
, sizeof (BteTerminalAccessible), (GInstanceInitFunc)(void (*
)(void)) _bte_terminal_accessible_init, (GTypeFlags) 0); { {{
BteTerminalAccessible_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (BteTerminalAccessiblePrivate)); }
{ const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) bte_terminal_accessible_text_iface_init, __null
, __null }; g_type_add_interface_static (g_define_type_id, (atk_text_get_type
()), &g_implement_interface_info); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) bte_terminal_accessible_component_iface_init, __null,
__null }; g_type_add_interface_static (g_define_type_id, (atk_component_get_type
()), &g_implement_interface_info); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) bte_terminal_accessible_action_iface_init, __null, __null
}; g_type_add_interface_static (g_define_type_id, (atk_action_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
94 G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, bte_terminal_accessible_action_iface_init))static void _bte_terminal_accessible_init (BteTerminalAccessible
*self); static void _bte_terminal_accessible_class_init (BteTerminalAccessibleClass
*klass); static GType _bte_terminal_accessible_get_type_once
(void); static gpointer _bte_terminal_accessible_parent_class
= __null; static gint BteTerminalAccessible_private_offset; static
void _bte_terminal_accessible_class_intern_init (gpointer klass
) { _bte_terminal_accessible_parent_class = g_type_class_peek_parent
(klass); if (BteTerminalAccessible_private_offset != 0) g_type_class_adjust_private_offset
(klass, &BteTerminalAccessible_private_offset); _bte_terminal_accessible_class_init
((BteTerminalAccessibleClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer _bte_terminal_accessible_get_instance_private
(BteTerminalAccessible *self) { return (((gpointer) ((guint8
*) (self) + (glong) (BteTerminalAccessible_private_offset))))
; } GType _bte_terminal_accessible_get_type (void) { static gsize
static_g_define_type_id = 0; if ((__extension__ ({ static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); (void) (0 ? (gpointer) *(
&static_g_define_type_id) : __null); (!(__extension__ ({ static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); gpointer gapg_temp_newval
; gpointer *gapg_temp_atomic = (gpointer *)(&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = _bte_terminal_accessible_get_type_once
(); (__extension__ ({ static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } [[gnu::noinline]] static GType _bte_terminal_accessible_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((ctk_widget_accessible_get_type ()), g_intern_static_string
("BteTerminalAccessible"), sizeof (BteTerminalAccessibleClass
), (GClassInitFunc)(void (*)(void)) _bte_terminal_accessible_class_intern_init
, sizeof (BteTerminalAccessible), (GInstanceInitFunc)(void (*
)(void)) _bte_terminal_accessible_init, (GTypeFlags) 0); { {{
BteTerminalAccessible_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (BteTerminalAccessiblePrivate)); }
{ const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) bte_terminal_accessible_text_iface_init, __null
, __null }; g_type_add_interface_static (g_define_type_id, (atk_text_get_type
()), &g_implement_interface_info); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) bte_terminal_accessible_component_iface_init, __null,
__null }; g_type_add_interface_static (g_define_type_id, (atk_component_get_type
()), &g_implement_interface_info); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) bte_terminal_accessible_action_iface_init, __null, __null
}; g_type_add_interface_static (g_define_type_id, (atk_action_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
95
96static gint
97offset_from_xy (BteTerminalAccessiblePrivate *priv,
98 gint x, gint y)
99{
100 gint offset;
101 gint linebreak;
102 gint next_linebreak;
103
104 if (y >= (gint) priv->snapshot_linebreaks->len)
105 y = priv->snapshot_linebreaks->len -1;
106
107 linebreak = g_array_index (priv->snapshot_linebreaks, int, y)(((int*) (void *) (priv->snapshot_linebreaks)->data) [(
y)])
;
108 if (y + 1 == (gint) priv->snapshot_linebreaks->len)
109 next_linebreak = priv->snapshot_characters->len;
110 else
111 next_linebreak = g_array_index (priv->snapshot_linebreaks, int, y + 1)(((int*) (void *) (priv->snapshot_linebreaks)->data) [(
y + 1)])
;
112
113 offset = linebreak + x;
114 if (offset >= next_linebreak)
115 offset = next_linebreak -1;
116 return offset;
117}
118
119static void
120xy_from_offset (BteTerminalAccessiblePrivate *priv,
121 guint offset, gint *x, gint *y)
122{
123 guint i, linebreak;
124 gint cur_x, cur_y;
125 gint cur_offset = 0;
126
127 cur_x = -1;
128 cur_y = -1;
129 for (i = 0; i < priv->snapshot_linebreaks->len; i++) {
130 linebreak = g_array_index (priv->snapshot_linebreaks, int, i)(((int*) (void *) (priv->snapshot_linebreaks)->data) [(
i)])
;
131 if (offset < linebreak) {
132 cur_x = offset - cur_offset;
133 cur_y = i - 1;
134 break;
135
136 } else {
137 cur_offset = linebreak;
138 }
139 }
140 if (i == priv->snapshot_linebreaks->len) {
141 if (offset <= priv->snapshot_characters->len) {
142 cur_x = offset - cur_offset;
143 cur_y = i - 1;
144 }
145 }
146 *x = cur_x;
147 *y = cur_y;
148}
149
150static void
151emit_text_caret_moved(GObject *object, glong caret)
152{
153 _bte_debug_print(BTE_DEBUG_SIGNALS|BTE_DEBUG_ALLY,do { } while(0)
154 "Accessibility peer emitting "do { } while(0)
155 "`text-caret-moved'.\n")do { } while(0);
156 g_signal_emit_by_name(object, "text-caret-moved", caret);
157}
158
159static void
160emit_text_changed_insert(GObject *object,
161 const char *text, glong offset, glong len)
162{
163 glong start, count;
164 if (len == 0) {
165 return;
166 }
167 /* Convert the byte offsets to character offsets. */
168 start = g_utf8_pointer_to_offset (text, text + offset);
169 count = g_utf8_pointer_to_offset (text + offset, text + offset + len);
170 _bte_debug_print(BTE_DEBUG_SIGNALS|BTE_DEBUG_ALLY,do { } while(0)
171 "Accessibility peer emitting "do { } while(0)
172 "`text-changed::insert' (%ld, %ld) (%ld, %ld).\n"do { } while(0)
173 "Inserted text was `%.*s'.\n",do { } while(0)
174 offset, len, start, count,do { } while(0)
175 (int) len, text + offset)do { } while(0);
176 g_signal_emit_by_name(object, "text-changed::insert", start, count);
177}
178
179static void
180emit_text_changed_delete(GObject *object,
181 const char *text, glong offset, glong len)
182{
183 glong start, count;
184 if (len == 0) {
185 return;
186 }
187 /* Convert the byte offsets to characters. */
188 start = g_utf8_pointer_to_offset (text, text + offset);
189 count = g_utf8_pointer_to_offset (text + offset, text + offset + len);
190 _bte_debug_print(BTE_DEBUG_SIGNALS|BTE_DEBUG_ALLY,do { } while(0)
191 "Accessibility peer emitting "do { } while(0)
192 "`text-changed::delete' (%ld, %ld) (%ld, %ld).\n"do { } while(0)
193 "Deleted text was `%.*s'.\n",do { } while(0)
194 offset, len, start, count,do { } while(0)
195 (int) len, text + offset)do { } while(0);
196 g_signal_emit_by_name(object, "text-changed::delete", start, count);
197}
198
199static void
200bte_terminal_accessible_update_private_data_if_needed(BteTerminalAccessible *accessible,
201 GString **old_text,
202 GArray **old_characters)
203{
204 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
205 struct _BteCharAttributes attrs;
206 char *next;
207 long row, offset, caret;
208 long ccol, crow;
209 guint i;
210
211 /* If nothing's changed, just return immediately. */
212 if ((priv->snapshot_contents_invalid == FALSE(0)) &&
213 (priv->snapshot_caret_invalid == FALSE(0))) {
214 if (old_text) {
215 if (priv->snapshot_text) {
216 *old_text = g_string_new_len(priv->snapshot_text->str,
217 priv->snapshot_text->len);
218 } else {
219 *old_text = g_string_new("");
220 }
221 }
222 if (old_characters) {
223 if (priv->snapshot_characters) {
224 *old_characters = g_array_sized_new(FALSE(0), FALSE(0), sizeof(int),
225 priv->snapshot_characters->len);
226 g_array_append_vals(*old_characters,
227 priv->snapshot_characters->data,
228 priv->snapshot_characters->len);
229 } else {
230 *old_characters = g_array_new(FALSE(0), FALSE(0), sizeof(int));
231 }
232 }
233 return;
234 }
235
236 /* Re-read the contents of the widget if the contents have changed. */
237 BteTerminal* terminal = TERMINAL_FROM_ACCESSIBLE(accessible)(((((BteTerminal*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_accessible_get_widget(((((CtkAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((accessible)), ((ctk_accessible_get_type (
)))))))))), ((bte_terminal_get_type())))))))
;
238 auto impl = IMPL(terminal)(_bte_terminal_get_impl(terminal));
239 if (priv->snapshot_contents_invalid) {
240 /* Free the outdated snapshot data, unless the caller
241 * wants it. */
242 if (old_text) {
243 if (priv->snapshot_text != NULL__null) {
244 *old_text = priv->snapshot_text;
245 } else {
246 *old_text = g_string_new("");
247 }
248 } else {
249 if (priv->snapshot_text != NULL__null) {
250 g_string_free(priv->snapshot_text, TRUE(!(0)));
251 }
252 }
253 priv->snapshot_text = NULL__null;
254
255 /* Free the character offsets unless the caller wants it,
256 * and allocate a new array to hold them. */
257 if (old_characters) {
258 if (priv->snapshot_characters != NULL__null) {
259 *old_characters = priv->snapshot_characters;
260 } else {
261 *old_characters = g_array_new(FALSE(0), FALSE(0), sizeof(int));
262 }
263 } else {
264 if (priv->snapshot_characters != NULL__null) {
265 g_array_free(priv->snapshot_characters, TRUE(!(0)));
266 }
267 }
268 priv->snapshot_characters = g_array_new(FALSE(0), FALSE(0), sizeof(int));
269
270 /* Free the attribute lists and allocate a new array to hold
271 * them. */
272 if (priv->snapshot_attributes != NULL__null) {
273 g_array_free(priv->snapshot_attributes, TRUE(!(0)));
274 }
275 priv->snapshot_attributes = g_array_new(FALSE(0), FALSE(0),
276 sizeof(struct _BteCharAttributes));
277
278 /* Free the linebreak offsets and allocate a new array to hold
279 * them. */
280 if (priv->snapshot_linebreaks != NULL__null) {
281 g_array_free(priv->snapshot_linebreaks, TRUE(!(0)));
282 }
283 priv->snapshot_linebreaks = g_array_new(FALSE(0), FALSE(0), sizeof(int));
284
285 /* Get a new view of the uber-label. */
286 try {
287 priv->snapshot_text = impl->get_text_displayed_a11y(true /* wrap */,
288 priv->snapshot_attributes);
289 } catch (...) {
290 priv->snapshot_text = g_string_new("");
291 }
292 /* Get the offsets to the beginnings of each character. */
293 i = 0;
294 next = priv->snapshot_text->str;
295 while (i < priv->snapshot_attributes->len) {
296 g_array_append_val(priv->snapshot_characters, i)g_array_append_vals (priv->snapshot_characters, &(i), 1
)
;
297 next = g_utf8_next_char(next)(char *)((next) + g_utf8_skip[*(const guchar *)(next)]);
298 if (next == NULL__null) {
299 break;
300 } else {
301 i = next - priv->snapshot_text->str;
302 }
303 }
304 /* Find offsets for the beginning of lines. */
305 for (i = 0, row = 0; i < priv->snapshot_characters->len; i++) {
306 /* Get the attributes for the current cell. */
307 offset = g_array_index(priv->snapshot_characters,(((int*) (void *) (priv->snapshot_characters)->data) [(
i)])
308 int, i)(((int*) (void *) (priv->snapshot_characters)->data) [(
i)])
;
309 attrs = g_array_index(priv->snapshot_attributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(offset)])
310 struct _BteCharAttributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(offset)])
311 offset)(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(offset)])
;
312 /* If this character is on a row different from the row
313 * the character we looked at previously was on, then
314 * it's a new line and we need to keep track of where
315 * it is. */
316 if ((i == 0) || (attrs.row != row)) {
317 _bte_debug_print(BTE_DEBUG_ALLY,do { } while(0)
318 "Row %d/%ld begins at %u.\n",do { } while(0)
319 priv->snapshot_linebreaks->len,do { } while(0)
320 attrs.row, i)do { } while(0);
321 g_array_append_val(priv->snapshot_linebreaks, i)g_array_append_vals (priv->snapshot_linebreaks, &(i), 1
)
;
322 }
323 row = attrs.row;
324 }
325 /* Add the final line break. */
326 g_array_append_val(priv->snapshot_linebreaks, i)g_array_append_vals (priv->snapshot_linebreaks, &(i), 1
)
;
327 /* We're finished updating this. */
328 priv->snapshot_contents_invalid = FALSE(0);
329 }
330
331 /* Update the caret position. */
332 bte_terminal_get_cursor_position(terminal, &ccol, &crow);
333 _bte_debug_print(BTE_DEBUG_ALLY,do { } while(0)
334 "Cursor at (%ld, " "%ld).\n", ccol, crow)do { } while(0);
335
336 /* Get the offsets to the beginnings of each line. */
337 caret = 0;
338 for (i = 0; i < priv->snapshot_characters->len; i++) {
339 /* Get the attributes for the current cell. */
340 offset = g_array_index(priv->snapshot_characters,(((int*) (void *) (priv->snapshot_characters)->data) [(
i)])
341 int, i)(((int*) (void *) (priv->snapshot_characters)->data) [(
i)])
;
342 attrs = g_array_index(priv->snapshot_attributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(offset)])
343 struct _BteCharAttributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(offset)])
344 offset)(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(offset)])
;
345 /* If this cell is "before" the cursor, move the
346 * caret to be "here". */
347 if ((attrs.row < crow) ||
348 ((attrs.row == crow) && (attrs.column < ccol))) {
349 caret = i + 1;
350 }
351 }
352
353 /* Make a note that we'll need to notify observers if the caret moved.
354 * But only notify them after sending text-changed. */
355 if (caret != priv->snapshot_caret) {
356 priv->snapshot_caret = caret;
357 priv->text_caret_moved_pending = TRUE(!(0));
358 }
359
360 /* Done updating the caret position, whether we needed to or not. */
361 priv->snapshot_caret_invalid = FALSE(0);
362
363 _bte_debug_print(BTE_DEBUG_ALLY,do { } while(0)
364 "Refreshed accessibility snapshot, "do { } while(0)
365 "%ld cells, %ld characters.\n",do { } while(0)
366 (long)priv->snapshot_attributes->len,do { } while(0)
367 (long)priv->snapshot_characters->len)do { } while(0);
368}
369
370static void
371bte_terminal_accessible_maybe_emit_text_caret_moved(BteTerminalAccessible *accessible)
372{
373 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
374
375 if (priv->text_caret_moved_pending) {
376 emit_text_caret_moved(G_OBJECT(accessible)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), (((GType) ((20) << (2))))))))
, priv->snapshot_caret);
377 priv->text_caret_moved_pending = FALSE(0);
378 }
379}
380
381/* A signal handler to catch "text-inserted/deleted/modified" signals. */
382static void
383bte_terminal_accessible_text_modified(BteTerminal *terminal, gpointer data)
384{
385 BteTerminalAccessible *accessible = (BteTerminalAccessible *)data;
386 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
387 GString *old_text;
388 GArray *old_characters;
389 char *old, *current;
390 glong offset, caret_offset, olen, clen;
391 gint old_snapshot_caret;
392
393 old_snapshot_caret = priv->snapshot_caret;
394 priv->snapshot_contents_invalid = TRUE(!(0));
395 bte_terminal_accessible_update_private_data_if_needed(accessible,
396 &old_text,
397 &old_characters);
398 g_assert(old_text != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (old_text != __null) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
("BTE", "../src/bteaccess.cc", 398, ((const char*) (__PRETTY_FUNCTION__
)), "old_text != NULL"); } while (0)
;
399 g_assert(old_characters != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (old_characters != __null) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
("BTE", "../src/bteaccess.cc", 399, ((const char*) (__PRETTY_FUNCTION__
)), "old_characters != NULL"); } while (0)
;
400
401 current = priv->snapshot_text->str;
402 clen = priv->snapshot_text->len;
403 old = old_text->str;
404 olen = old_text->len;
405
406 if ((guint) priv->snapshot_caret < priv->snapshot_characters->len) {
407 caret_offset = g_array_index(priv->snapshot_characters,(((int*) (void *) (priv->snapshot_characters)->data) [(
priv->snapshot_caret)])
408 int, priv->snapshot_caret)(((int*) (void *) (priv->snapshot_characters)->data) [(
priv->snapshot_caret)])
;
409 } else {
410 /* caret was not in the line */
411 caret_offset = clen;
412 }
413
414 /* Find the offset where they don't match. */
415 offset = 0;
416 while ((offset < olen) && (offset < clen)) {
417 if (old[offset] != current[offset]) {
418 break;
419 }
420 offset++;
421 }
422
423 /* Check if we just backspaced over a space. */
424 if ((olen == offset) &&
425 (caret_offset < olen && old[caret_offset] == ' ') &&
426 (old_snapshot_caret == priv->snapshot_caret + 1)) {
427 GString *saved_text = priv->snapshot_text;
428 GArray *saved_characters = priv->snapshot_characters;
429
430 priv->snapshot_text = old_text;
431 priv->snapshot_characters = old_characters;
432 emit_text_changed_delete(G_OBJECT(accessible)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), (((GType) ((20) << (2))))))))
,
433 old, caret_offset, 1);
434 priv->snapshot_text = saved_text;
435 priv->snapshot_characters = saved_characters;
436 emit_text_changed_insert(G_OBJECT(accessible)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), (((GType) ((20) << (2))))))))
,
437 old, caret_offset, 1);
438 }
439
440
441 /* At least one of them had better have more data, right? */
442 if ((offset < olen) || (offset < clen)) {
443 /* Back up from both end points until we find the *last* point
444 * where they differed. */
445 gchar *op = old + olen;
446 gchar *cp = current + clen;
447 while (op > old + offset && cp > current + offset) {
448 gchar *opp = g_utf8_prev_char (op);
449 gchar *cpp = g_utf8_prev_char (cp);
450 if (g_utf8_get_char (opp) != g_utf8_get_char (cpp)) {
451 break;
452 }
453 op = opp;
454 cp = cpp;
455 }
456 /* recompute the respective lengths */
457 olen = op - old;
458 clen = cp - current;
459 /* At least one of them has to have text the other
460 * doesn't. */
461 g_assert((clen > offset) || (olen > offset))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((clen > offset) || (olen > offset)) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else
g_assertion_message_expr ("BTE", "../src/bteaccess.cc", 461,
((const char*) (__PRETTY_FUNCTION__)), "(clen > offset) || (olen > offset)"
); } while (0)
;
462 g_assert((clen >= 0) && (olen >= 0))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((clen >= 0) && (olen >= 0)) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else
g_assertion_message_expr ("BTE", "../src/bteaccess.cc", 462,
((const char*) (__PRETTY_FUNCTION__)), "(clen >= 0) && (olen >= 0)"
); } while (0)
;
463 /* Now emit a deleted signal for text that was in the old
464 * string but isn't in the new one... */
465 if (olen > offset) {
466 GString *saved_text = priv->snapshot_text;
467 GArray *saved_characters = priv->snapshot_characters;
468
469 priv->snapshot_text = old_text;
470 priv->snapshot_characters = old_characters;
471 emit_text_changed_delete(G_OBJECT(accessible)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), (((GType) ((20) << (2))))))))
,
472 old,
473 offset,
474 olen - offset);
475 priv->snapshot_text = saved_text;
476 priv->snapshot_characters = saved_characters;
477 }
478 /* .. and an inserted signal for text that wasn't in the old
479 * string but is in the new one. */
480 if (clen > offset) {
481 emit_text_changed_insert(G_OBJECT(accessible)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), (((GType) ((20) << (2))))))))
,
482 current,
483 offset,
484 clen - offset);
485 }
486 }
487
488 bte_terminal_accessible_maybe_emit_text_caret_moved(accessible);
489
490 g_string_free(old_text, TRUE(!(0)));
491 g_array_free(old_characters, TRUE(!(0)));
492}
493
494/* A signal handler to catch "text-scrolled" signals. */
495static void
496bte_terminal_accessible_text_scrolled(BteTerminal *terminal,
497 gint howmuch,
498 gpointer data)
499{
500 BteTerminalAccessible *accessible = (BteTerminalAccessible *)data;
501 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
502 struct _BteCharAttributes attr;
503 long delta, row_count;
504 guint i, len;
505
506 /* TODOegmont: Fix this for smooth scrolling */
507 /* g_assert(howmuch != 0); */
508 if (howmuch == 0) return;
509
510 row_count = bte_terminal_get_row_count(terminal);
511 if (((howmuch < 0) && (howmuch <= -row_count)) ||
512 ((howmuch > 0) && (howmuch >= row_count))) {
513 /* All of the text was removed. */
514 if (priv->snapshot_text != NULL__null) {
515 if (priv->snapshot_text->str != NULL__null) {
516 emit_text_changed_delete(G_OBJECT(accessible)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), (((GType) ((20) << (2))))))))
,
517 priv->snapshot_text->str,
518 0,
519 priv->snapshot_text->len);
520 }
521 }
522 priv->snapshot_contents_invalid = TRUE(!(0));
523 bte_terminal_accessible_update_private_data_if_needed(accessible,
524 NULL__null,
525 NULL__null);
526 /* All of the present text was added. */
527 if (priv->snapshot_text != NULL__null) {
528 if (priv->snapshot_text->str != NULL__null) {
529 emit_text_changed_insert(G_OBJECT(accessible)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), (((GType) ((20) << (2))))))))
,
530 priv->snapshot_text->str,
531 0,
532 priv->snapshot_text->len);
533 }
534 }
535 bte_terminal_accessible_maybe_emit_text_caret_moved(accessible);
536 return;
537 }
538 /* Find the start point. */
539 delta = 0;
540 if (priv->snapshot_attributes != NULL__null) {
541 if (priv->snapshot_attributes->len > 0) {
542 attr = g_array_index(priv->snapshot_attributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(0)])
543 struct _BteCharAttributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(0)])
544 0)(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(0)])
;
545 delta = attr.row;
546 }
547 }
548 /* We scrolled up, so text was added at the top and removed
549 * from the bottom. */
550 if ((howmuch < 0) && (howmuch > -row_count)) {
551 gboolean inserted = FALSE(0);
552 howmuch = -howmuch;
553 if (priv->snapshot_attributes != NULL__null &&
554 priv->snapshot_text != NULL__null) {
555 /* Find the first byte that scrolled off. */
556 for (i = 0; i < priv->snapshot_attributes->len; i++) {
557 attr = g_array_index(priv->snapshot_attributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(i)])
558 struct _BteCharAttributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(i)])
559 i)(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(i)])
;
560 if (attr.row >= delta + row_count - howmuch) {
561 break;
562 }
563 }
564 if (i < priv->snapshot_attributes->len) {
565 /* The rest of the string was deleted -- make a note. */
566 emit_text_changed_delete(G_OBJECT(accessible)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), (((GType) ((20) << (2))))))))
,
567 priv->snapshot_text->str,
568 i,
569 priv->snapshot_attributes->len - i);
570 }
571 inserted = TRUE(!(0));
572 }
573 /* Refresh. Note that i is now the length of the data which
574 * we expect to have left over. */
575 priv->snapshot_contents_invalid = TRUE(!(0));
576 bte_terminal_accessible_update_private_data_if_needed(accessible,
577 NULL__null,
578 NULL__null);
579 /* If we now have more text than before, the initial portion
580 * was added. */
581 if (inserted) {
582 len = priv->snapshot_text->len;
583 if (len > i) {
584 emit_text_changed_insert(G_OBJECT(accessible)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), (((GType) ((20) << (2))))))))
,
585 priv->snapshot_text->str,
586 0,
587 len - i);
588 }
589 }
590 bte_terminal_accessible_maybe_emit_text_caret_moved(accessible);
591 return;
592 }
593 /* We scrolled down, so text was added at the bottom and removed
594 * from the top. */
595 if ((howmuch > 0) && (howmuch < row_count)) {
596 gboolean inserted = FALSE(0);
597 if (priv->snapshot_attributes != NULL__null &&
598 priv->snapshot_text != NULL__null) {
599 /* Find the first byte that wasn't scrolled off the top. */
600 for (i = 0; i < priv->snapshot_attributes->len; i++) {
601 attr = g_array_index(priv->snapshot_attributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(i)])
602 struct _BteCharAttributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(i)])
603 i)(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(i)])
;
604 if (attr.row >= delta + howmuch) {
605 break;
606 }
607 }
608 /* That many bytes disappeared -- make a note. */
609 emit_text_changed_delete(G_OBJECT(accessible)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), (((GType) ((20) << (2))))))))
,
610 priv->snapshot_text->str,
611 0,
612 i);
613 /* Figure out how much text was left, and refresh. */
614 i = strlen(priv->snapshot_text->str + i);
615 inserted = TRUE(!(0));
616 }
617 priv->snapshot_contents_invalid = TRUE(!(0));
618 bte_terminal_accessible_update_private_data_if_needed(accessible,
619 NULL__null,
620 NULL__null);
621 /* Any newly-added string data is new, so note that it was
622 * inserted. */
623 if (inserted) {
624 len = priv->snapshot_text->len;
625 if (len > i) {
626 /* snapshot_text always contains a trailing '\n',
627 * insertion happens in front of it: bug 657960 */
628 g_assert(i >= 1)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (i >= 1) _g_boolean_var_ = 1; else _g_boolean_var_ = 0
; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr ("BTE"
, "../src/bteaccess.cc", 628, ((const char*) (__PRETTY_FUNCTION__
)), "i >= 1"); } while (0)
;
629 emit_text_changed_insert(G_OBJECT(accessible)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), (((GType) ((20) << (2))))))))
,
630 priv->snapshot_text->str,
631 i - 1,
632 len - i);
633 }
634 }
635 bte_terminal_accessible_maybe_emit_text_caret_moved(accessible);
636 return;
637 }
638 g_assert_not_reached()do { g_assertion_message_expr ("BTE", "../src/bteaccess.cc", 638
, ((const char*) (__PRETTY_FUNCTION__)), __null); } while (0)
;
639}
640
641/* A signal handler to catch "cursor-moved" signals. */
642static void
643bte_terminal_accessible_invalidate_cursor(BteTerminal *terminal, gpointer data)
644{
645 BteTerminalAccessible *accessible = (BteTerminalAccessible *)data;
646 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
647
648 _bte_debug_print(BTE_DEBUG_ALLY,do { } while(0)
649 "Invalidating accessibility cursor.\n")do { } while(0);
650 priv->snapshot_caret_invalid = TRUE(!(0));
651 bte_terminal_accessible_update_private_data_if_needed(accessible,
652 NULL__null, NULL__null);
653 bte_terminal_accessible_maybe_emit_text_caret_moved(accessible);
654}
655
656/* Handle title changes by resetting the description. */
657static void
658bte_terminal_accessible_title_changed(BteTerminal *terminal, gpointer data)
659{
660 BteTerminalAccessible *accessible = (BteTerminalAccessible *)data;
661
662 atk_object_set_description(ATK_OBJECT(accessible)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((atk_object_get_type ()))))))
, bte_terminal_get_window_title(terminal));
663}
664
665/* Reflect visibility-notify events. */
666static gboolean
667bte_terminal_accessible_visibility_notify(BteTerminal *terminal,
668 CdkEventVisibility *event,
669 gpointer data)
670{
671 BteTerminalAccessible *accessible = (BteTerminalAccessible *)data;
672 CtkWidget *widget;
673 gboolean visible;
674
675 visible = event->state != CDK_VISIBILITY_FULLY_OBSCURED;
676 /* The VISIBLE state indicates that this widget is "visible". */
677 atk_object_notify_state_change(ATK_OBJECT(accessible)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((atk_object_get_type ()))))))
,
678 ATK_STATE_VISIBLE,
679 visible);
680 widget = &terminal->widget;
681 while (visible) {
682 if (ctk_widget_get_toplevel(widget) == widget) {
683 break;
684 }
685 if (widget == NULL__null) {
686 break;
687 }
688 visible = visible && (ctk_widget_get_visible(widget));
689 widget = ctk_widget_get_parent(widget);
690 }
691 /* The SHOWING state indicates that this widget, and all of its
692 * parents up to the toplevel, are "visible". */
693 atk_object_notify_state_change(ATK_OBJECT(accessible)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((atk_object_get_type ()))))))
,
694 ATK_STATE_SHOWING,
695 visible);
696
697 return FALSE(0);
698}
699
700static void
701bte_terminal_accessible_selection_changed (BteTerminal *terminal,
702 gpointer data)
703{
704 BteTerminalAccessible *accessible = (BteTerminalAccessible *)data;
705
706 g_signal_emit_by_name (accessible, "text_selection_changed");
707}
708
709static void
710bte_terminal_accessible_initialize (AtkObject *obj, gpointer data)
711{
712 BteTerminal *terminal = BTE_TERMINAL (data)((((BteTerminal*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((bte_terminal_get_type()))))))
;
713 const char *window_title;
714
715 ATK_OBJECT_CLASS (_bte_terminal_accessible_parent_class)((((AtkObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((_bte_terminal_accessible_parent_class)), ((atk_object_get_type
()))))))
->initialize (obj, data);
716
717 auto impl = IMPL(terminal)(_bte_terminal_get_impl(terminal));
718 try {
719 impl->subscribe_accessible_events();
720 } catch (...) {
721 }
722
723 g_signal_connect(terminal, "text-inserted",g_signal_connect_data ((terminal), ("text-inserted"), (((GCallback
) (bte_terminal_accessible_text_modified))), (obj), __null, (
GConnectFlags) 0)
724 G_CALLBACK(bte_terminal_accessible_text_modified),g_signal_connect_data ((terminal), ("text-inserted"), (((GCallback
) (bte_terminal_accessible_text_modified))), (obj), __null, (
GConnectFlags) 0)
725 obj)g_signal_connect_data ((terminal), ("text-inserted"), (((GCallback
) (bte_terminal_accessible_text_modified))), (obj), __null, (
GConnectFlags) 0)
;
726 g_signal_connect(terminal, "text-deleted",g_signal_connect_data ((terminal), ("text-deleted"), (((GCallback
) (bte_terminal_accessible_text_modified))), (obj), __null, (
GConnectFlags) 0)
727 G_CALLBACK(bte_terminal_accessible_text_modified),g_signal_connect_data ((terminal), ("text-deleted"), (((GCallback
) (bte_terminal_accessible_text_modified))), (obj), __null, (
GConnectFlags) 0)
728 obj)g_signal_connect_data ((terminal), ("text-deleted"), (((GCallback
) (bte_terminal_accessible_text_modified))), (obj), __null, (
GConnectFlags) 0)
;
729 g_signal_connect(terminal, "text-modified",g_signal_connect_data ((terminal), ("text-modified"), (((GCallback
) (bte_terminal_accessible_text_modified))), (obj), __null, (
GConnectFlags) 0)
730 G_CALLBACK(bte_terminal_accessible_text_modified),g_signal_connect_data ((terminal), ("text-modified"), (((GCallback
) (bte_terminal_accessible_text_modified))), (obj), __null, (
GConnectFlags) 0)
731 obj)g_signal_connect_data ((terminal), ("text-modified"), (((GCallback
) (bte_terminal_accessible_text_modified))), (obj), __null, (
GConnectFlags) 0)
;
732 g_signal_connect(terminal, "text-scrolled",g_signal_connect_data ((terminal), ("text-scrolled"), (((GCallback
) (bte_terminal_accessible_text_scrolled))), (obj), __null, (
GConnectFlags) 0)
733 G_CALLBACK(bte_terminal_accessible_text_scrolled),g_signal_connect_data ((terminal), ("text-scrolled"), (((GCallback
) (bte_terminal_accessible_text_scrolled))), (obj), __null, (
GConnectFlags) 0)
734 obj)g_signal_connect_data ((terminal), ("text-scrolled"), (((GCallback
) (bte_terminal_accessible_text_scrolled))), (obj), __null, (
GConnectFlags) 0)
;
735 g_signal_connect(terminal, "cursor-moved",g_signal_connect_data ((terminal), ("cursor-moved"), (((GCallback
) (bte_terminal_accessible_invalidate_cursor))), (obj), __null
, (GConnectFlags) 0)
736 G_CALLBACK(bte_terminal_accessible_invalidate_cursor),g_signal_connect_data ((terminal), ("cursor-moved"), (((GCallback
) (bte_terminal_accessible_invalidate_cursor))), (obj), __null
, (GConnectFlags) 0)
737 obj)g_signal_connect_data ((terminal), ("cursor-moved"), (((GCallback
) (bte_terminal_accessible_invalidate_cursor))), (obj), __null
, (GConnectFlags) 0)
;
738 g_signal_connect(terminal, "window-title-changed",g_signal_connect_data ((terminal), ("window-title-changed"), (
((GCallback) (bte_terminal_accessible_title_changed))), (obj)
, __null, (GConnectFlags) 0)
739 G_CALLBACK(bte_terminal_accessible_title_changed),g_signal_connect_data ((terminal), ("window-title-changed"), (
((GCallback) (bte_terminal_accessible_title_changed))), (obj)
, __null, (GConnectFlags) 0)
740 obj)g_signal_connect_data ((terminal), ("window-title-changed"), (
((GCallback) (bte_terminal_accessible_title_changed))), (obj)
, __null, (GConnectFlags) 0)
;
741
742 g_signal_connect(terminal, "visibility-notify-event",g_signal_connect_data ((terminal), ("visibility-notify-event"
), (((GCallback) (bte_terminal_accessible_visibility_notify))
), (obj), __null, (GConnectFlags) 0)
743 G_CALLBACK(bte_terminal_accessible_visibility_notify), obj)g_signal_connect_data ((terminal), ("visibility-notify-event"
), (((GCallback) (bte_terminal_accessible_visibility_notify))
), (obj), __null, (GConnectFlags) 0)
;
744 g_signal_connect(terminal, "selection-changed",g_signal_connect_data ((terminal), ("selection-changed"), (((
GCallback) (bte_terminal_accessible_selection_changed))), (obj
), __null, (GConnectFlags) 0)
745 G_CALLBACK(bte_terminal_accessible_selection_changed), obj)g_signal_connect_data ((terminal), ("selection-changed"), (((
GCallback) (bte_terminal_accessible_selection_changed))), (obj
), __null, (GConnectFlags) 0)
;
746
747 atk_object_set_name(obj, "Terminal");
748 window_title = bte_terminal_get_window_title(terminal);
749 atk_object_set_description(obj, window_title ? window_title : "");
750
751 atk_object_notify_state_change(obj,
752 ATK_STATE_FOCUSABLE, TRUE(!(0)));
753 atk_object_notify_state_change(obj,
754 ATK_STATE_EXPANDABLE, FALSE(0));
755 atk_object_notify_state_change(obj,
756 ATK_STATE_RESIZABLE, TRUE(!(0)));
757 atk_object_set_role(obj, ATK_ROLE_TERMINAL);
758}
759
760static void
761_bte_terminal_accessible_init (BteTerminalAccessible *accessible)
762{
763 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private (accessible);
764
765 _bte_debug_print(BTE_DEBUG_ALLY, "Initialising accessible peer.\n")do { } while(0);
766
767 priv->snapshot_text = NULL__null;
768 priv->snapshot_characters = NULL__null;
769 priv->snapshot_attributes = NULL__null;
770 priv->snapshot_linebreaks = NULL__null;
771 priv->snapshot_caret = -1;
772 priv->snapshot_contents_invalid = TRUE(!(0));
773 priv->snapshot_caret_invalid = TRUE(!(0));
774 priv->text_caret_moved_pending = FALSE(0);
775}
776
777static void
778bte_terminal_accessible_finalize(GObject *object)
779{
780 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(object)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((object)), ((_bte_terminal_accessible_get_type
()))))))
;
781 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
782 CtkWidget *widget;
783 gint i;
784
785 _bte_debug_print(BTE_DEBUG_ALLY, "Finalizing accessible peer.\n")do { } while(0);
786
787 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE(accessible)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((ctk_accessible_get_type ()))))))
);
788
789 if (widget != NULL__null) {
790 g_signal_handlers_disconnect_matched(widget,
791 (GSignalMatchType)(G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA),
792 0, 0, NULL__null,
793 (void *)bte_terminal_accessible_text_modified,
794 object);
795 g_signal_handlers_disconnect_matched(widget,
796 (GSignalMatchType)(G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA),
797 0, 0, NULL__null,
798 (void *)bte_terminal_accessible_text_scrolled,
799 object);
800 g_signal_handlers_disconnect_matched(widget,
801 (GSignalMatchType)(G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA),
802 0, 0, NULL__null,
803 (void *)bte_terminal_accessible_invalidate_cursor,
804 object);
805 g_signal_handlers_disconnect_matched(widget,
806 (GSignalMatchType)(G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA),
807 0, 0, NULL__null,
808 (void *)bte_terminal_accessible_title_changed,
809 object);
810 g_signal_handlers_disconnect_matched(widget,
811 (GSignalMatchType)(G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA),
812 0, 0, NULL__null,
813 (void *)bte_terminal_accessible_visibility_notify,
814 object);
815 }
816
817 if (priv->snapshot_text != NULL__null) {
818 g_string_free(priv->snapshot_text, TRUE(!(0)));
819 }
820 if (priv->snapshot_characters != NULL__null) {
821 g_array_free(priv->snapshot_characters, TRUE(!(0)));
822 }
823 if (priv->snapshot_attributes != NULL__null) {
824 g_array_free(priv->snapshot_attributes, TRUE(!(0)));
825 }
826 if (priv->snapshot_linebreaks != NULL__null) {
827 g_array_free(priv->snapshot_linebreaks, TRUE(!(0)));
828 }
829 for (i = 0; i < LAST_ACTION; i++) {
830 g_free (priv->action_descriptions[i]);
831 }
832
833 G_OBJECT_CLASS(_bte_terminal_accessible_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((_bte_terminal_accessible_parent_class)), (((GType) ((20)
<< (2))))))))
->finalize(object);
834}
835
836static gchar *
837bte_terminal_accessible_get_text(AtkText *text,
838 gint start_offset, gint end_offset)
839{
840 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
841 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
842 int start, end;
843 gchar *ret;
844
845 g_assert(BTE_IS_TERMINAL_ACCESSIBLE(accessible))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((accessible)); GType __t = ((_bte_terminal_accessible_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1)) ; else g_assertion_message_expr ("BTE", "../src/bteaccess.cc"
, 845, ((const char*) (__PRETTY_FUNCTION__)), "BTE_IS_TERMINAL_ACCESSIBLE(accessible)"
); } while (0)
;
846
847 /* Swap around if start is greater than end */
848 if (start_offset > end_offset && end_offset != -1) {
849 gint tmp;
850
851 tmp = start_offset;
852 start_offset = end_offset;
853 end_offset = tmp;
854 }
855
856 g_assert((start_offset >= 0) && (end_offset >= -1))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((start_offset >= 0) && (end_offset >= -1)
) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1)) ; else g_assertion_message_expr ("BTE", "../src/bteaccess.cc"
, 856, ((const char*) (__PRETTY_FUNCTION__)), "(start_offset >= 0) && (end_offset >= -1)"
); } while (0)
;
857
858 bte_terminal_accessible_update_private_data_if_needed(accessible,
859 NULL__null, NULL__null);
860
861 _bte_debug_print(BTE_DEBUG_ALLY,do { } while(0)
862 "Getting text from %d to %d of %d.\n",do { } while(0)
863 start_offset, end_offset,do { } while(0)
864 priv->snapshot_characters->len)do { } while(0);
865
866 /* If the requested area is after all of the text, just return an
867 * empty string. */
868 if (start_offset >= (int) priv->snapshot_characters->len) {
869 return g_strdup("");
870 }
871
872 /* Map the offsets to, er, offsets. */
873 start = g_array_index(priv->snapshot_characters, int, start_offset)(((int*) (void *) (priv->snapshot_characters)->data) [(
start_offset)])
;
874 if ((end_offset == -1) || (end_offset >= (int) priv->snapshot_characters->len) ) {
875 /* Get everything up to the end of the buffer. */
876 end = priv->snapshot_text->len;
877 } else {
878 /* Map the stopping point. */
879 end = g_array_index(priv->snapshot_characters, int, end_offset)(((int*) (void *) (priv->snapshot_characters)->data) [(
end_offset)])
;
880 }
881 if (end <= start) {
882 ret = g_strdup ("");
883 } else {
884 ret = (char *)g_malloc(end - start + 1);
885 memcpy(ret, priv->snapshot_text->str + start, end - start);
886 ret[end - start] = '\0';
887 }
888 return ret;
889}
890
891/* Map a subsection of the text with before/at/after char/word/line specs
892 * into a run of Unicode characters. (The interface is specifying characters,
893 * not bytes, plus that saves us from having to deal with parts of multibyte
894 * characters, which are icky.) */
895static gchar *
896bte_terminal_accessible_get_text_somewhere(AtkText *text,
897 gint offset,
898 AtkTextBoundary boundary_type,
899 enum direction direction,
900 gint *start_offset,
901 gint *end_offset)
902{
903 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
904 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
905 gunichar current, prev, next;
906 guint start, end, line;
907
908 bte_terminal_accessible_update_private_data_if_needed(accessible,
909 NULL__null, NULL__null);
910
911 auto impl = IMPL_FROM_ACCESSIBLE(text)(((_bte_terminal_get_impl(((((BteTerminal*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((ctk_accessible_get_widget(((((CtkAccessible
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((text
)), ((ctk_accessible_get_type ()))))))))), ((bte_terminal_get_type
()))))))))))
;
912
913 _bte_debug_print(BTE_DEBUG_ALLY,do { } while(0)
914 "Getting %s %s at %d of %d.\n",do { } while(0)
915 (direction == direction_current) ? "this" :do { } while(0)
916 ((direction == direction_next) ? "next" : "previous"),do { } while(0)
917 (boundary_type == ATK_TEXT_BOUNDARY_CHAR) ? "char" :do { } while(0)
918 ((boundary_type == ATK_TEXT_BOUNDARY_LINE_START) ? "line (start)" :do { } while(0)
919 ((boundary_type == ATK_TEXT_BOUNDARY_LINE_END) ? "line (end)" :do { } while(0)
920 ((boundary_type == ATK_TEXT_BOUNDARY_WORD_START) ? "word (start)" :do { } while(0)
921 ((boundary_type == ATK_TEXT_BOUNDARY_WORD_END) ? "word (end)" :do { } while(0)
922 ((boundary_type == ATK_TEXT_BOUNDARY_SENTENCE_START) ? "sentence (start)" :do { } while(0)
923 ((boundary_type == ATK_TEXT_BOUNDARY_SENTENCE_END) ? "sentence (end)" : "unknown")))))),do { } while(0)
924 offset, priv->snapshot_attributes->len)do { } while(0);
925 g_assert(priv->snapshot_text != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (priv->snapshot_text != __null) _g_boolean_var_ = 1; else
_g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
("BTE", "../src/bteaccess.cc", 925, ((const char*) (__PRETTY_FUNCTION__
)), "priv->snapshot_text != NULL"); } while (0)
;
926 g_assert(priv->snapshot_characters != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (priv->snapshot_characters != __null) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else
g_assertion_message_expr ("BTE", "../src/bteaccess.cc", 926,
((const char*) (__PRETTY_FUNCTION__)), "priv->snapshot_characters != NULL"
); } while (0)
;
927 if (offset >= (int) priv->snapshot_characters->len) {
928 return g_strdup("");
929 }
930 g_assert(offset < (int) priv->snapshot_characters->len)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (offset < (int) priv->snapshot_characters->len)
_g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1)) ; else g_assertion_message_expr ("BTE", "../src/bteaccess.cc"
, 930, ((const char*) (__PRETTY_FUNCTION__)), "offset < (int) priv->snapshot_characters->len"
); } while (0)
;
931 g_assert(offset >= 0)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (offset >= 0) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
("BTE", "../src/bteaccess.cc", 931, ((const char*) (__PRETTY_FUNCTION__
)), "offset >= 0"); } while (0)
;
932
933 switch (boundary_type) {
934 case ATK_TEXT_BOUNDARY_CHAR:
935 /* We're either looking at the character at this
936 * position, the one before it, or the one after it. */
937 offset += direction;
938 start = MAX(offset, 0)(((offset) > (0)) ? (offset) : (0));
939 end = MIN(offset + 1, (int) priv->snapshot_attributes->len)(((offset + 1) < ((int) priv->snapshot_attributes->len
)) ? (offset + 1) : ((int) priv->snapshot_attributes->len
))
;
940 break;
941 case ATK_TEXT_BOUNDARY_WORD_START:
942 /* Back up to the previous non-word-word transition. */
943 while (offset > 0) {
944 prev = bte_terminal_accessible_get_character_at_offset(text, offset - 1);
945 if (impl->is_word_char(prev)) {
946 offset--;
947 } else {
948 break;
949 }
950 }
951 start = offset;
952 /* If we started in a word and we're looking for the
953 * word before this one, keep searching by backing up
954 * to the previous non-word character and then searching
955 * for the word-start before that. */
956 if (direction == direction_previous) {
957 while (offset > 0) {
958 prev = bte_terminal_accessible_get_character_at_offset(text, offset - 1);
959 if (!impl->is_word_char(prev)) {
960 offset--;
961 } else {
962 break;
963 }
964 }
965 while (offset > 0) {
966 prev = bte_terminal_accessible_get_character_at_offset(text, offset - 1);
967 if (impl->is_word_char(prev)) {
968 offset--;
969 } else {
970 break;
971 }
972 }
973 start = offset;
974 }
975 /* If we're looking for the word after this one,
976 * search forward by scanning forward for the next
977 * non-word character, then the next word character
978 * after that. */
979 if (direction == direction_next) {
980 while (offset < (int) priv->snapshot_characters->len) {
981 next = bte_terminal_accessible_get_character_at_offset(text, offset);
982 if (impl->is_word_char(next)) {
983 offset++;
984 } else {
985 break;
986 }
987 }
988 while (offset < (int) priv->snapshot_characters->len) {
989 next = bte_terminal_accessible_get_character_at_offset(text, offset);
990 if (!impl->is_word_char(next)) {
991 offset++;
992 } else {
993 break;
994 }
995 }
996 start = offset;
997 }
998 /* Now find the end of this word. */
999 while (offset < (int) priv->snapshot_characters->len) {
1000 current = bte_terminal_accessible_get_character_at_offset(text, offset);
1001 if (impl->is_word_char(current)) {
1002 offset++;
1003 } else {
1004 break;
1005 }
1006
1007 }
1008 /* Now find the next non-word-word transition */
1009 while (offset < (int) priv->snapshot_characters->len) {
1010 next = bte_terminal_accessible_get_character_at_offset(text, offset);
1011 if (!impl->is_word_char(next)) {
1012 offset++;
1013 } else {
1014 break;
1015 }
1016 }
1017 end = offset;
1018 break;
1019 case ATK_TEXT_BOUNDARY_WORD_END:
1020 /* Back up to the previous word-non-word transition. */
1021 current = bte_terminal_accessible_get_character_at_offset(text, offset);
1022 while (offset > 0) {
1023 prev = bte_terminal_accessible_get_character_at_offset(text, offset - 1);
1024 if (impl->is_word_char(prev) &&
1025 !impl->is_word_char(current)) {
1026 break;
1027 } else {
1028 offset--;
1029 current = prev;
1030 }
1031 }
1032 start = offset;
1033 /* If we're looking for the word end before this one,
1034 * keep searching by backing up to the previous word
1035 * character and then searching for the word-end
1036 * before that. */
1037 if (direction == direction_previous) {
1038 while (offset > 0) {
1039 prev = bte_terminal_accessible_get_character_at_offset(text, offset - 1);
1040 if (impl->is_word_char(prev)) {
1041 offset--;
1042 } else {
1043 break;
1044 }
1045 }
1046 current = bte_terminal_accessible_get_character_at_offset(text, offset);
1047 while (offset > 0) {
1048 prev = bte_terminal_accessible_get_character_at_offset(text, offset - 1);
1049 if (impl->is_word_char(prev) &&
1050 !impl->is_word_char(current)) {
1051 break;
1052 } else {
1053 offset--;
1054 current = prev;
1055 }
1056 }
1057 start = offset;
1058 }
1059 /* If we're looking for the word end after this one,
1060 * search forward by scanning forward for the next
1061 * word character, then the next non-word character
1062 * after that. */
1063 if (direction == direction_next) {
1064 while (offset < (int) priv->snapshot_characters->len) {
1065 current = bte_terminal_accessible_get_character_at_offset(text, offset);
1066 if (!impl->is_word_char(current)) {
1067 offset++;
1068 } else {
1069 break;
1070 }
1071 }
1072 while (offset < (int) priv->snapshot_characters->len) {
1073 current = bte_terminal_accessible_get_character_at_offset(text, offset);
1074 if (impl->is_word_char(current)) {
1075 offset++;
1076 } else {
1077 break;
1078 }
1079 }
1080 start = offset;
1081 }
1082 /* Now find the next word end. */
1083 while (offset < (int) priv->snapshot_characters->len) {
1084 current = bte_terminal_accessible_get_character_at_offset(text, offset);
1085 if (!impl->is_word_char(current)) {
1086 offset++;
1087 } else {
1088 break;
1089 }
1090 }
1091 while (offset < (int) priv->snapshot_characters->len) {
1092 current = bte_terminal_accessible_get_character_at_offset(text, offset);
1093 if (impl->is_word_char(current)) {
1094 offset++;
1095 } else {
1096 break;
1097 }
1098 }
1099 end = offset;
1100 break;
1101 case ATK_TEXT_BOUNDARY_LINE_START:
1102 case ATK_TEXT_BOUNDARY_LINE_END:
1103 /* Figure out which line we're on. If the start of the
1104 * i'th line is before the offset, then i could be the
1105 * line we're looking for. */
1106 line = 0;
1107 for (line = 0;
1108 line < priv->snapshot_linebreaks->len;
1109 line++) {
1110 if (g_array_index(priv->snapshot_linebreaks,(((int*) (void *) (priv->snapshot_linebreaks)->data) [(
line)])
1111 int, line)(((int*) (void *) (priv->snapshot_linebreaks)->data) [(
line)])
> offset) {
1112 line--;
1113 break;
1114 }
1115 }
1116 _bte_debug_print(BTE_DEBUG_ALLY,do { } while(0)
1117 "Character %d is on line %d.\n",do { } while(0)
1118 offset, line)do { } while(0);
1119 /* Perturb the line number to handle before/at/after. */
1120 line += direction;
1121 line = MIN(line, priv->snapshot_linebreaks->len - 1)(((line) < (priv->snapshot_linebreaks->len - 1)) ? (
line) : (priv->snapshot_linebreaks->len - 1))
;
1122 /* Read the offsets for this line. */
1123 start = g_array_index(priv->snapshot_linebreaks,(((int*) (void *) (priv->snapshot_linebreaks)->data) [(
line)])
1124 int, line)(((int*) (void *) (priv->snapshot_linebreaks)->data) [(
line)])
;
1125 line++;
1126 line = MIN(line, priv->snapshot_linebreaks->len - 1)(((line) < (priv->snapshot_linebreaks->len - 1)) ? (
line) : (priv->snapshot_linebreaks->len - 1))
;
1127 end = g_array_index(priv->snapshot_linebreaks,(((int*) (void *) (priv->snapshot_linebreaks)->data) [(
line)])
1128 int, line)(((int*) (void *) (priv->snapshot_linebreaks)->data) [(
line)])
;
1129 _bte_debug_print(BTE_DEBUG_ALLY,do { } while(0)
1130 "Line runs from %d to %d.\n",do { } while(0)
1131 start, end)do { } while(0);
1132 break;
1133 case ATK_TEXT_BOUNDARY_SENTENCE_START:
1134 case ATK_TEXT_BOUNDARY_SENTENCE_END:
1135 /* This doesn't make sense. Fall through. */
1136 default:
1137 start = end = 0;
1138 break;
1139 }
1140 *start_offset = start = MIN(start, priv->snapshot_characters->len - 1)(((start) < (priv->snapshot_characters->len - 1)) ? (
start) : (priv->snapshot_characters->len - 1))
;
1141 *end_offset = end = CLAMP(end, start, priv->snapshot_characters->len)(((end) > (priv->snapshot_characters->len)) ? (priv->
snapshot_characters->len) : (((end) < (start)) ? (start
) : (end)))
;
1142 return bte_terminal_accessible_get_text(text, start, end);
1143}
1144
1145static gchar *
1146bte_terminal_accessible_get_text_before_offset(AtkText *text, gint offset,
1147 AtkTextBoundary boundary_type,
1148 gint *start_offset,
1149 gint *end_offset)
1150{
1151 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1152
1153 bte_terminal_accessible_update_private_data_if_needed(accessible,
1154 NULL__null, NULL__null);
1155 return bte_terminal_accessible_get_text_somewhere(text,
1156 offset,
1157 boundary_type,
1158 direction_previous,
1159 start_offset,
1160 end_offset);
1161}
1162
1163static gchar *
1164bte_terminal_accessible_get_text_after_offset(AtkText *text, gint offset,
1165 AtkTextBoundary boundary_type,
1166 gint *start_offset,
1167 gint *end_offset)
1168{
1169 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1170
1171 bte_terminal_accessible_update_private_data_if_needed(accessible,
1172 NULL__null, NULL__null);
1173 return bte_terminal_accessible_get_text_somewhere(text,
1174 offset,
1175 boundary_type,
1176 direction_next,
1177 start_offset,
1178 end_offset);
1179}
1180
1181static gchar *
1182bte_terminal_accessible_get_text_at_offset(AtkText *text, gint offset,
1183 AtkTextBoundary boundary_type,
1184 gint *start_offset,
1185 gint *end_offset)
1186{
1187 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1188
1189 bte_terminal_accessible_update_private_data_if_needed(accessible,
1190 NULL__null, NULL__null);
1191 return bte_terminal_accessible_get_text_somewhere(text,
1192 offset,
1193 boundary_type,
1194 direction_current,
1195 start_offset,
1196 end_offset);
1197}
1198
1199static gunichar
1200bte_terminal_accessible_get_character_at_offset(AtkText *text, gint offset)
1201{
1202 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1203 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
1204 char *unichar;
1205 gunichar ret;
1206
1207 bte_terminal_accessible_update_private_data_if_needed(accessible,
1208 NULL__null, NULL__null);
1209
1210 g_assert(offset < (int) priv->snapshot_characters->len)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (offset < (int) priv->snapshot_characters->len)
_g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1)) ; else g_assertion_message_expr ("BTE", "../src/bteaccess.cc"
, 1210, ((const char*) (__PRETTY_FUNCTION__)), "offset < (int) priv->snapshot_characters->len"
); } while (0)
;
1211
1212 unichar = bte_terminal_accessible_get_text(text, offset, offset + 1);
1213 ret = g_utf8_get_char(unichar);
1214 g_free(unichar);
1215
1216 return ret;
1217}
1218
1219static gint
1220bte_terminal_accessible_get_caret_offset(AtkText *text)
1221{
1222 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1223 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
1224
1225 bte_terminal_accessible_update_private_data_if_needed(accessible,
1226 NULL__null, NULL__null);
1227
1228 return priv->snapshot_caret;
1229}
1230
1231static AtkAttributeSet *
1232get_attribute_set (struct _BteCharAttributes attr)
1233{
1234 AtkAttributeSet *set = NULL__null;
1235 AtkAttribute *at;
1236
1237 if (attr.underline) {
1238 at = g_new (AtkAttribute, 1)(AtkAttribute *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (AtkAttribute); gpointer __p; if (__s == 1) __p
= g_malloc (__n); else if (__builtin_constant_p (__n) &&
(__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s
)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s
); __p; }))
;
1239 at->name = g_strdup ("underline");
1240 at->value = g_strdup ("true");
1241 set = g_slist_append (set, at);
1242 }
1243 if (attr.strikethrough) {
1244 at = g_new (AtkAttribute, 1)(AtkAttribute *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (AtkAttribute); gpointer __p; if (__s == 1) __p
= g_malloc (__n); else if (__builtin_constant_p (__n) &&
(__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s
)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s
); __p; }))
;
1245 at->name = g_strdup ("strikethrough");
1246 at->value = g_strdup ("true");
1247 set = g_slist_append (set, at);
1248 }
1249 at = g_new (AtkAttribute, 1)(AtkAttribute *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (AtkAttribute); gpointer __p; if (__s == 1) __p
= g_malloc (__n); else if (__builtin_constant_p (__n) &&
(__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s
)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s
); __p; }))
;
1250 at->name = g_strdup ("fg-color");
1251 at->value = g_strdup_printf ("%u,%u,%u",
1252 attr.fore.red, attr.fore.green, attr.fore.blue);
1253 set = g_slist_append (set, at);
1254
1255 at = g_new (AtkAttribute, 1)(AtkAttribute *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (AtkAttribute); gpointer __p; if (__s == 1) __p
= g_malloc (__n); else if (__builtin_constant_p (__n) &&
(__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s
)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s
); __p; }))
;
1256 at->name = g_strdup ("bg-color");
1257 at->value = g_strdup_printf ("%u,%u,%u",
1258 attr.back.red, attr.back.green, attr.back.blue);
1259 set = g_slist_append (set, at);
1260
1261 return set;
1262}
1263
1264static gboolean
1265_pango_color_equal(const PangoColor *a,
1266 const PangoColor *b)
1267{
1268 return a->red == b->red &&
1269 a->green == b->green &&
1270 a->blue == b->blue;
1271}
1272
1273static AtkAttributeSet *
1274bte_terminal_accessible_get_run_attributes(AtkText *text, gint offset,
1275 gint *start_offset, gint *end_offset)
1276{
1277 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1278 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
1279 guint i;
1280 struct _BteCharAttributes cur_attr;
1281 struct _BteCharAttributes attr;
1282
1283 bte_terminal_accessible_update_private_data_if_needed(accessible,
1284 NULL__null, NULL__null);
1285
1286 attr = g_array_index (priv->snapshot_attributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(offset)])
1287 struct _BteCharAttributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(offset)])
1288 offset)(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(offset)])
;
1289 *start_offset = 0;
1290 for (i = offset; i--;) {
1291 cur_attr = g_array_index (priv->snapshot_attributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(i)])
1292 struct _BteCharAttributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(i)])
1293 i)(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(i)])
;
1294 if (!_pango_color_equal (&cur_attr.fore, &attr.fore) ||
1295 !_pango_color_equal (&cur_attr.back, &attr.back) ||
1296 cur_attr.underline != attr.underline ||
1297 cur_attr.strikethrough != attr.strikethrough) {
1298 *start_offset = i + 1;
1299 break;
1300 }
1301 }
1302 *end_offset = priv->snapshot_attributes->len - 1;
1303 for (i = offset + 1; i < priv->snapshot_attributes->len; i++) {
1304 cur_attr = g_array_index (priv->snapshot_attributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(i)])
1305 struct _BteCharAttributes,(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(i)])
1306 i)(((struct _BteCharAttributes*) (void *) (priv->snapshot_attributes
)->data) [(i)])
;
1307 if (!_pango_color_equal (&cur_attr.fore, &attr.fore) ||
1308 !_pango_color_equal (&cur_attr.back, &attr.back) ||
1309 cur_attr.underline != attr.underline ||
1310 cur_attr.strikethrough != attr.strikethrough) {
1311 *end_offset = i - 1;
1312 break;
1313 }
1314 }
1315
1316 return get_attribute_set (attr);
1317}
1318
1319static AtkAttributeSet *
1320bte_terminal_accessible_get_default_attributes(AtkText *text)
1321{
1322 return NULL__null;
1323}
1324
1325static void
1326bte_terminal_accessible_get_character_extents(AtkText *text, gint offset,
1327 gint *x, gint *y,
1328 gint *width, gint *height,
1329 AtkCoordType coords)
1330{
1331 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1332 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
1333 BteTerminal *terminal;
1334 glong cell_width, cell_height;
1335 gint base_x, base_y, w, h;
1336
1337 bte_terminal_accessible_update_private_data_if_needed(accessible,
1338 NULL__null, NULL__null);
1339 terminal = BTE_TERMINAL (ctk_accessible_get_widget (CTK_ACCESSIBLE (text)))((((BteTerminal*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_accessible_get_widget (((((CtkAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((ctk_accessible_get_type ()))))
))))), ((bte_terminal_get_type()))))))
;
1340
1341 atk_component_get_extents (ATK_COMPONENT (text)(((AtkComponent*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((text)), ((atk_component_get_type ())))))
, &base_x, &base_y, &w, &h, coords);
1342 xy_from_offset (priv, offset, x, y);
1343 cell_width = bte_terminal_get_char_width (terminal);
1344 cell_height = bte_terminal_get_char_height (terminal);
1345 *x *= cell_width;
1346 *y *= cell_height;
1347 *width = cell_width;
1348 *height = cell_height;
1349 *x += base_x;
1350 *y += base_y;
1351}
1352
1353static gint
1354bte_terminal_accessible_get_character_count(AtkText *text)
1355{
1356 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1357 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
1358
1359 bte_terminal_accessible_update_private_data_if_needed(accessible,
1360 NULL__null, NULL__null);
1361
1362 return priv->snapshot_attributes->len;
1363}
1364
1365static gint
1366bte_terminal_accessible_get_offset_at_point(AtkText *text,
1367 gint x, gint y,
1368 AtkCoordType coords)
1369{
1370 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1371 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
1372 BteTerminal *terminal;
1373 glong cell_width, cell_height;
1374 gint base_x, base_y, w, h;
1375
1376 bte_terminal_accessible_update_private_data_if_needed(accessible,
1377 NULL__null, NULL__null);
1378 terminal = BTE_TERMINAL (ctk_accessible_get_widget (CTK_ACCESSIBLE (text)))((((BteTerminal*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_accessible_get_widget (((((CtkAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((ctk_accessible_get_type ()))))
))))), ((bte_terminal_get_type()))))))
;
1379
1380 atk_component_get_extents (ATK_COMPONENT (text)(((AtkComponent*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((text)), ((atk_component_get_type ())))))
, &base_x, &base_y, &w, &h, coords);
1381 cell_width = bte_terminal_get_char_width (terminal);
1382 cell_height = bte_terminal_get_char_height (terminal);
1383 x -= base_x;
1384 y -= base_y;
1385 x /= cell_width;
1386 y /= cell_height;
1387 return offset_from_xy (priv, x, y);
1388}
1389
1390static gint
1391bte_terminal_accessible_get_n_selections(AtkText *text)
1392{
1393 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1394 CtkWidget *widget;
1395 BteTerminal *terminal;
1396
1397 bte_terminal_accessible_update_private_data_if_needed(accessible,
1398 NULL__null, NULL__null);
1399 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE(text)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((text)), ((ctk_accessible_get_type ()))))))
);
1400 if (widget == NULL__null) {
1401 /* State is defunct */
1402 return -1;
1403 }
1404
1405 terminal = BTE_TERMINAL (widget)((((BteTerminal*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((bte_terminal_get_type()))))))
;
1406 return (bte_terminal_get_has_selection (terminal)) ? 1 : 0;
1407}
1408
1409static gchar *
1410bte_terminal_accessible_get_selection(AtkText *text, gint selection_number,
1411 gint *start_offset, gint *end_offset)
1412{
1413 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1414 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
1415 CtkWidget *widget;
1416
1417 if (selection_number != 0)
1418 return NULL__null;
1419
1420 bte_terminal_accessible_update_private_data_if_needed(accessible,
1421 NULL__null, NULL__null);
1422 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE(text)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((text)), ((ctk_accessible_get_type ()))))))
);
1423 if (widget == NULL__null) {
1424 /* State is defunct */
1425 return NULL__null;
1426 }
1427
1428 try {
This statement is never executed
1429 auto impl = IMPL_FROM_WIDGET(widget)((_bte_terminal_get_impl(((((BteTerminal*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((widget)), ((bte_terminal_get_type())))))
))))
;
1430 if (impl->m_selection_resolved.empty() || impl->m_selection[BTE_SELECTION_PRIMARY] == nullptr)
1431 return nullptr;
1432
1433 *start_offset = offset_from_xy (priv, impl->m_selection_resolved.start_column(), impl->m_selection_resolved.start_row());
1434 *end_offset = offset_from_xy (priv, impl->m_selection_resolved.end_column(), impl->m_selection_resolved.end_row());
1435
1436 return g_strdup(impl->m_selection[BTE_SELECTION_PRIMARY]->str);
1437 } catch (...) {
1438 return nullptr;
1439 }
1440}
1441
1442static gboolean
1443bte_terminal_accessible_add_selection(AtkText *text,
1444 gint start_offset, gint end_offset)
1445{
1446 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1447 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
1448 CtkWidget *widget;
1449
1450 bte_terminal_accessible_update_private_data_if_needed(accessible,
1451 NULL__null, NULL__null);
1452 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE(text)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((text)), ((ctk_accessible_get_type ()))))))
);
1453 if (widget == NULL__null) {
1454 /* State is defunct */
1455 return FALSE(0);
1456 }
1457
1458 int start_x, start_y, end_x, end_y;
1459 xy_from_offset (priv, start_offset, &start_x, &start_y);
1460 xy_from_offset (priv, end_offset, &end_x, &end_y);
1461 IMPL_FROM_WIDGET(widget)((_bte_terminal_get_impl(((((BteTerminal*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((widget)), ((bte_terminal_get_type())))))
))))
->select_text(start_x, start_y, end_x, end_y);
1462 return TRUE(!(0));
1463}
1464
1465static gboolean
1466bte_terminal_accessible_remove_selection(AtkText *text,
1467 gint selection_number)
1468{
1469 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1470 CtkWidget *widget;
1471 BteTerminal *terminal;
1472
1473 bte_terminal_accessible_update_private_data_if_needed(accessible,
1474 NULL__null, NULL__null);
1475 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE(text)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((text)), ((ctk_accessible_get_type ()))))))
);
1476 if (widget == NULL__null) {
1477 /* State is defunct */
1478 return FALSE(0);
1479 }
1480
1481 terminal = BTE_TERMINAL (widget)((((BteTerminal*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((bte_terminal_get_type()))))))
;
1482 auto impl = IMPL_FROM_WIDGET(widget)((_bte_terminal_get_impl(((((BteTerminal*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((widget)), ((bte_terminal_get_type())))))
))))
;
1483 if (selection_number == 0 && bte_terminal_get_has_selection (terminal)) {
1484 try {
1485 impl->deselect_all();
1486 } catch (...) {
1487 }
1488 return TRUE(!(0));
1489 } else {
1490 return FALSE(0);
1491 }
1492}
1493
1494static gboolean
1495bte_terminal_accessible_set_selection(AtkText *text, gint selection_number,
1496 gint start_offset, gint end_offset)
1497{
1498 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1499 CtkWidget *widget;
1500 BteTerminal *terminal;
1501
1502 bte_terminal_accessible_update_private_data_if_needed(accessible,
1503 NULL__null, NULL__null);
1504 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE(text)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((text)), ((ctk_accessible_get_type ()))))))
);
1505 if (widget == NULL__null) {
1506 /* State is defunct */
1507 return FALSE(0);
1508 }
1509
1510 terminal = BTE_TERMINAL (widget)((((BteTerminal*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((bte_terminal_get_type()))))))
;
1511 auto impl = IMPL_FROM_WIDGET(widget)((_bte_terminal_get_impl(((((BteTerminal*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((widget)), ((bte_terminal_get_type())))))
))))
;
1512 if (selection_number != 0) {
1513 return FALSE(0);
1514 }
1515 if (bte_terminal_get_has_selection (terminal)) {
1516 try {
1517 impl->deselect_all();
1518 } catch (...) {
1519 }
1520 }
1521
1522 return bte_terminal_accessible_add_selection (text, start_offset, end_offset);
1523}
1524
1525static gboolean
1526bte_terminal_accessible_set_caret_offset(AtkText *text, gint offset)
1527{
1528 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(text)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((text)), ((_bte_terminal_accessible_get_type
()))))))
;
1529
1530 bte_terminal_accessible_update_private_data_if_needed(accessible,
1531 NULL__null, NULL__null);
1532 /* Whoa, very not allowed. */
1533 return FALSE(0);
1534}
1535
1536static void
1537bte_terminal_accessible_text_iface_init(AtkTextIface *text)
1538{
1539 text->get_text = bte_terminal_accessible_get_text;
1540 text->get_text_after_offset = bte_terminal_accessible_get_text_after_offset;
1541 text->get_text_at_offset = bte_terminal_accessible_get_text_at_offset;
1542 text->get_character_at_offset = bte_terminal_accessible_get_character_at_offset;
1543 text->get_text_before_offset = bte_terminal_accessible_get_text_before_offset;
1544 text->get_caret_offset = bte_terminal_accessible_get_caret_offset;
1545 text->get_run_attributes = bte_terminal_accessible_get_run_attributes;
1546 text->get_default_attributes = bte_terminal_accessible_get_default_attributes;
1547 text->get_character_extents = bte_terminal_accessible_get_character_extents;
1548 text->get_character_count = bte_terminal_accessible_get_character_count;
1549 text->get_offset_at_point = bte_terminal_accessible_get_offset_at_point;
1550 text->get_n_selections = bte_terminal_accessible_get_n_selections;
1551 text->get_selection = bte_terminal_accessible_get_selection;
1552 text->add_selection = bte_terminal_accessible_add_selection;
1553 text->remove_selection = bte_terminal_accessible_remove_selection;
1554 text->set_selection = bte_terminal_accessible_set_selection;
1555 text->set_caret_offset = bte_terminal_accessible_set_caret_offset;
1556}
1557
1558static gboolean
1559bte_terminal_accessible_set_extents(AtkComponent *component,
1560 gint x, gint y,
1561 gint width, gint height,
1562 AtkCoordType coord_type)
1563{
1564 /* FIXME? We can change the size, but our position is controlled
1565 * by the parent container. */
1566 return FALSE(0);
1567}
1568
1569static gboolean
1570bte_terminal_accessible_set_position(AtkComponent *component,
1571 gint x, gint y,
1572 AtkCoordType coord_type)
1573{
1574 /* Controlled by the parent container, if there is one. */
1575 return FALSE(0);
1576}
1577
1578static gboolean
1579bte_terminal_accessible_set_size(AtkComponent *component,
1580 gint width, gint height)
1581{
1582 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(component)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((component)), ((_bte_terminal_accessible_get_type
()))))))
;
1583 CtkWidget *widget;
1584
1585 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE(accessible)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((ctk_accessible_get_type ()))))))
);
1586 if (widget == NULL__null)
1587 return FALSE(0);
1588
1589 BteTerminal *terminal = BTE_TERMINAL(widget)((((BteTerminal*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((bte_terminal_get_type()))))))
;
1590 auto impl = IMPL(terminal)(_bte_terminal_get_impl(terminal));
1591
1592 /* If the size is an exact multiple of the cell size, use that,
1593 * otherwise round down. */
1594 try {
1595 width -= impl->m_padding.left + impl->m_padding.right;
1596 height -= impl->m_padding.top + impl->m_padding.bottom;
1597
1598 auto columns = width / impl->m_cell_width;
1599 auto rows = height / impl->m_cell_height;
1600 if (columns <= 0 || rows <= 0)
1601 return FALSE(0);
1602
1603 bte_terminal_set_size(terminal, columns, rows);
1604 return (bte_terminal_get_row_count (terminal) == rows) &&
1605 (bte_terminal_get_column_count (terminal) == columns);
1606 } catch (...) {
1607 return false;
1608 }
1609}
1610
1611static AtkObject *
1612bte_terminal_accessible_ref_accessible_at_point(AtkComponent *component,
1613 gint x, gint y,
1614 AtkCoordType coord_type)
1615{
1616 /* There are no children. */
1617 return NULL__null;
1618}
1619
1620static void
1621bte_terminal_accessible_component_iface_init(AtkComponentIface *component)
1622{
1623 component->ref_accessible_at_point = bte_terminal_accessible_ref_accessible_at_point;
1624 component->set_extents = bte_terminal_accessible_set_extents;
1625 component->set_position = bte_terminal_accessible_set_position;
1626 component->set_size = bte_terminal_accessible_set_size;
1627}
1628
1629/* AtkAction interface */
1630
1631static gboolean
1632bte_terminal_accessible_do_action (AtkAction *accessible, int i)
1633{
1634 CtkWidget *widget;
1635 gboolean retval = FALSE(0);
1636
1637 g_return_val_if_fail (i < LAST_ACTION, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (i < LAST_ACTION) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
("BTE", ((const char*) (__PRETTY_FUNCTION__)), "i < LAST_ACTION"
); return ((0)); } } while (0)
;
1638
1639 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE (accessible)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((ctk_accessible_get_type ()))))))
);
1640 if (!widget) {
1641 return FALSE(0);
1642 }
1643
1644 switch (i) {
1645 case ACTION_MENU :
1646 g_signal_emit_by_name (widget, "popup_menu", &retval);
1647 break;
1648 default :
1649 g_warning ("Invalid action passed to BteTerminalAccessible::do_action");
1650 return FALSE(0);
1651 }
1652 return retval;
1653}
1654
1655static int
1656bte_terminal_accessible_get_n_actions (AtkAction *accessible)
1657{
1658 return LAST_ACTION;
1659}
1660
1661static const char *
1662bte_terminal_accessible_action_get_description (AtkAction *action, int i)
1663{
1664 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(action)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((action)), ((_bte_terminal_accessible_get_type
()))))))
;
1665 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
1666
1667 g_return_val_if_fail (i < LAST_ACTION, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (i < LAST_ACTION) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
("BTE", ((const char*) (__PRETTY_FUNCTION__)), "i < LAST_ACTION"
); return (__null); } } while (0)
;
1668
1669 if (priv->action_descriptions[i]) {
1670 return priv->action_descriptions[i];
1671 } else {
1672 return bte_terminal_accessible_action_descriptions[i];
1673 }
1674}
1675
1676static const char *
1677bte_terminal_accessible_action_get_name (AtkAction *accessible, int i)
1678{
1679 g_return_val_if_fail (i < LAST_ACTION, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (i < LAST_ACTION) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
("BTE", ((const char*) (__PRETTY_FUNCTION__)), "i < LAST_ACTION"
); return (__null); } } while (0)
;
1680
1681 return bte_terminal_accessible_action_names[i];
1682}
1683
1684static const char *
1685bte_terminal_accessible_action_get_keybinding (AtkAction *accessible, int i)
1686{
1687 g_return_val_if_fail (i < LAST_ACTION, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (i < LAST_ACTION) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
("BTE", ((const char*) (__PRETTY_FUNCTION__)), "i < LAST_ACTION"
); return (__null); } } while (0)
;
1688
1689 return NULL__null;
1690}
1691
1692static gboolean
1693bte_terminal_accessible_action_set_description (AtkAction *action,
1694 int i,
1695 const char *description)
1696{
1697 BteTerminalAccessible *accessible = BTE_TERMINAL_ACCESSIBLE(action)((((BteTerminalAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((action)), ((_bte_terminal_accessible_get_type
()))))))
;
1698 BteTerminalAccessiblePrivate *priv = (BteTerminalAccessiblePrivate *)_bte_terminal_accessible_get_instance_private(accessible);
1699
1700 g_return_val_if_fail (i < LAST_ACTION, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (i < LAST_ACTION) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
("BTE", ((const char*) (__PRETTY_FUNCTION__)), "i < LAST_ACTION"
); return ((0)); } } while (0)
;
1701
1702 if (priv->action_descriptions[i]) {
1703 g_free (priv->action_descriptions[i]);
1704 }
1705 priv->action_descriptions[i] = g_strdup (description);
1706
1707 return TRUE(!(0));
1708}
1709
1710static void
1711bte_terminal_accessible_action_iface_init(AtkActionIface *action)
1712{
1713 action->do_action = bte_terminal_accessible_do_action;
1714 action->get_n_actions = bte_terminal_accessible_get_n_actions;
1715 action->get_description = bte_terminal_accessible_action_get_description;
1716 action->get_name = bte_terminal_accessible_action_get_name;
1717 action->get_keybinding = bte_terminal_accessible_action_get_keybinding;
1718 action->set_description = bte_terminal_accessible_action_set_description;
1719}
1720
1721static void
1722_bte_terminal_accessible_class_init(BteTerminalAccessibleClass *klass)
1723{
1724 GObjectClass *gobject_class = G_OBJECT_CLASS(klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
1725 AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass)((((AtkObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), ((atk_object_get_type ()))))))
;
1726
1727 gobject_class->finalize = bte_terminal_accessible_finalize;
1728
1729 atk_object_class->initialize = bte_terminal_accessible_initialize;
1730}