Bug Summary

File:ctk/ctkentry.c
Warning:line 9928, column 63
Array access (from variable 'ranges') results in a null pointer dereference

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 ctkentry.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -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 -fhalf-no-semantic-interposition -mframe-pointer=all -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/ctk -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -D G_LOG_DOMAIN="Ctk" -D G_LOG_USE_STRUCTURED=1 -D CTK_VERSION="3.25.5" -D CTK_BINARY_VERSION="3.0.0" -D CTK_COMPILATION -D CTK_PRINT_BACKEND_ENABLE_UNSUPPORTED -D CTK_LIBDIR="/usr/lib" -D CTK_LOCALEDIR="/usr/share/locale" -D CTK_DATADIR="/usr/share" -D CTK_DATA_PREFIX="/usr" -D CTK_SYSCONFDIR="/usr/etc" -D CTK_HOST="x86_64-pc-linux-gnu" -D CTK_PRINT_BACKENDS="file,cups" -D X11_DATA_PREFIX="/usr" -D ISO_CODES_PREFIX="" -I .. -I ../ctk -I .. -I ../cdk -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/atk-1.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -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 -I /usr/include/gio-unix-2.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/pango-1.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/ctk -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -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/2024-09-19-171836-43636-1 -x c ctkentry.c
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* CTK - The GIMP Toolkit
3 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * Copyright (C) 2004-2006 Christian Hammond
5 * Copyright (C) 2008 Cody Russell
6 * Copyright (C) 2008 Red Hat, Inc.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22/*
23 * Modified by the CTK+ Team and others 1997-2000. See the AUTHORS
24 * file for a list of people on the CTK+ Team. See the ChangeLog
25 * files for a list of changes. These files are distributed with
26 * CTK+ at ftp://ftp.ctk.org/pub/ctk/.
27 */
28
29#include "config.h"
30
31#include <string.h>
32
33#include "ctkbindings.h"
34#include "ctkcelleditable.h"
35#include "ctkclipboard.h"
36#include "ctkdebug.h"
37#include "ctkdnd.h"
38#include "ctkdndprivate.h"
39#include "ctkentry.h"
40#include "ctkentrybuffer.h"
41#include "ctkiconhelperprivate.h"
42#include "ctkemojichooser.h"
43#include "ctkemojicompletion.h"
44#include "ctkentrybuffer.h"
45#include "ctkimcontextsimple.h"
46#include "ctkimmulticontext.h"
47#include "ctkintl.h"
48#include "ctklabel.h"
49#include "ctkmain.h"
50#include "ctkmarshalers.h"
51#include "ctkmenu.h"
52#include "ctkmenuitem.h"
53#include "ctkpango.h"
54#include "ctkseparatormenuitem.h"
55#include "ctkselection.h"
56#include "ctksettings.h"
57#include "ctkspinbutton.h"
58#include "ctktextutil.h"
59#include "ctkwindow.h"
60#include "ctktreeview.h"
61#include "ctktreeselection.h"
62#include "ctktypebuiltins.h"
63#include "ctkprivate.h"
64#include "ctkentryprivate.h"
65#include "ctkcelllayout.h"
66#include "ctktooltip.h"
67#include "ctkicontheme.h"
68#include "ctkwidgetprivate.h"
69#include "ctkstylecontextprivate.h"
70#include "ctktexthandleprivate.h"
71#include "ctkpopover.h"
72#include "ctktoolbar.h"
73#include "ctkmagnifierprivate.h"
74#include "ctkcssnodeprivate.h"
75#include "ctkcsscustomgadgetprivate.h"
76#include "ctkprogresstrackerprivate.h"
77#include "ctkemojichooser.h"
78#include "ctkwindow.h"
79
80#include "a11y/ctkentryaccessible.h"
81
82#include "fallback-c89.c"
83
84/**
85 * SECTION:ctkentry
86 * @Short_description: A single line text entry field
87 * @Title: CtkEntry
88 * @See_also: #CtkTextView, #CtkEntryCompletion
89 *
90 * The #CtkEntry widget is a single line text entry
91 * widget. A fairly large set of key bindings are supported
92 * by default. If the entered text is longer than the allocation
93 * of the widget, the widget will scroll so that the cursor
94 * position is visible.
95 *
96 * When using an entry for passwords and other sensitive information,
97 * it can be put into “password mode” using ctk_entry_set_visibility().
98 * In this mode, entered text is displayed using a “invisible” character.
99 * By default, CTK+ picks the best invisible character that is available
100 * in the current font, but it can be changed with
101 * ctk_entry_set_invisible_char(). Since 2.16, CTK+ displays a warning
102 * when Caps Lock or input methods might interfere with entering text in
103 * a password entry. The warning can be turned off with the
104 * #CtkEntry:caps-lock-warning property.
105 *
106 * Since 2.16, CtkEntry has the ability to display progress or activity
107 * information behind the text. To make an entry display such information,
108 * use ctk_entry_set_progress_fraction() or ctk_entry_set_progress_pulse_step().
109 *
110 * Additionally, CtkEntry can show icons at either side of the entry. These
111 * icons can be activatable by clicking, can be set up as drag source and
112 * can have tooltips. To add an icon, use ctk_entry_set_icon_from_gicon() or
113 * one of the various other functions that set an icon from a stock id, an
114 * icon name or a pixbuf. To trigger an action when the user clicks an icon,
115 * connect to the #CtkEntry::icon-press signal. To allow DND operations
116 * from an icon, use ctk_entry_set_icon_drag_source(). To set a tooltip on
117 * an icon, use ctk_entry_set_icon_tooltip_text() or the corresponding function
118 * for markup.
119 *
120 * Note that functionality or information that is only available by clicking
121 * on an icon in an entry may not be accessible at all to users which are not
122 * able to use a mouse or other pointing device. It is therefore recommended
123 * that any such functionality should also be available by other means, e.g.
124 * via the context menu of the entry.
125 *
126 * # CSS nodes
127 *
128 * |[<!-- language="plain" -->
129 * entry[.read-only][.flat][.warning][.error]
130 * ├── image.left
131 * ├── image.right
132 * ├── undershoot.left
133 * ├── undershoot.right
134 * ├── [selection]
135 * ├── [progress[.pulse]]
136 * ╰── [window.popup]
137 * ]|
138 *
139 * CtkEntry has a main node with the name entry. Depending on the properties
140 * of the entry, the style classes .read-only and .flat may appear. The style
141 * classes .warning and .error may also be used with entries.
142 *
143 * When the entry shows icons, it adds subnodes with the name image and the
144 * style class .left or .right, depending on where the icon appears.
145 *
146 * When the entry has a selection, it adds a subnode with the name selection.
147 *
148 * When the entry shows progress, it adds a subnode with the name progress.
149 * The node has the style class .pulse when the shown progress is pulsing.
150 *
151 * The CSS node for a context menu is added as a subnode below entry as well.
152 *
153 * The undershoot nodes are used to draw the underflow indication when content
154 * is scrolled out of view. These nodes get the .left and .right style classes
155 * added depending on where the indication is drawn.
156 *
157 * When touch is used and touch selection handles are shown, they are using
158 * CSS nodes with name cursor-handle. They get the .top or .bottom style class
159 * depending on where they are shown in relation to the selection. If there is
160 * just a single handle for the text cursor, it gets the style class
161 * .insertion-cursor.
162 */
163
164#define MIN_ENTRY_WIDTH150 150
165
166#define MAX_ICONS2 2
167
168#define IS_VALID_ICON_POSITION(pos)((pos) == CTK_ENTRY_ICON_PRIMARY || (pos) == CTK_ENTRY_ICON_SECONDARY
)
\
169 ((pos) == CTK_ENTRY_ICON_PRIMARY || \
170 (pos) == CTK_ENTRY_ICON_SECONDARY)
171
172static GQuark quark_inner_border = 0;
173static GQuark quark_password_hint = 0;
174static GQuark quark_cursor_hadjustment = 0;
175static GQuark quark_capslock_feedback = 0;
176static GQuark quark_ctk_signal = 0;
177static GQuark quark_entry_completion = 0;
178
179typedef struct _EntryIconInfo EntryIconInfo;
180typedef struct _CtkEntryPasswordHint CtkEntryPasswordHint;
181typedef struct _CtkEntryCapslockFeedback CtkEntryCapslockFeedback;
182
183struct _CtkEntryPrivate
184{
185 EntryIconInfo *icons[MAX_ICONS2];
186
187 CtkEntryBuffer *buffer;
188 CtkIMContext *im_context;
189 CtkWidget *popup_menu;
190
191 CdkWindow *text_area;
192 CtkAllocation text_allocation;
193 int text_baseline;
194
195 PangoLayout *cached_layout;
196 PangoAttrList *attrs;
197 PangoTabArray *tabs;
198
199 gchar *im_module;
200
201 gdouble progress_fraction;
202 gdouble progress_pulse_fraction;
203 gdouble progress_pulse_current;
204
205 guint tick_id;
206 CtkProgressTracker tracker;
207 gint64 pulse1;
208 gint64 pulse2;
209 gdouble last_iteration;
210
211 gchar *placeholder_text;
212
213 CtkTextHandle *text_handle;
214 CtkWidget *selection_bubble;
215 guint selection_bubble_timeout_id;
216
217 CtkWidget *magnifier_popover;
218 CtkWidget *magnifier;
219
220 CtkGesture *drag_gesture;
221 CtkGesture *multipress_gesture;
222
223 CtkCssGadget *gadget;
224 CtkCssGadget *progress_gadget;
225 CtkCssNode *selection_node;
226 CtkCssNode *undershoot_node[2];
227
228 gfloat xalign;
229
230 gint ascent; /* font ascent in pango units */
231 gint current_pos;
232 gint descent; /* font descent in pango units */
233 gint dnd_position; /* In chars, -1 == no DND cursor */
234 gint drag_start_x;
235 gint drag_start_y;
236 gint insert_pos;
237 gint selection_bound;
238 gint scroll_offset;
239 gint start_x;
240 gint start_y;
241 gint width_chars;
242 gint max_width_chars;
243
244 gunichar invisible_char;
245
246 guint blink_time; /* time in msec the cursor has blinked since last user event */
247 guint blink_timeout;
248
249 guint16 preedit_length; /* length of preedit string, in bytes */
250 guint16 preedit_cursor; /* offset of cursor within preedit string, in chars */
251
252 gint64 handle_place_time;
253
254 guint shadow_type : 4;
255 guint editable : 1;
256 guint show_emoji_icon : 1;
257 guint enable_emoji_completion : 1;
258 guint in_drag : 1;
259 guint overwrite_mode : 1;
260 guint visible : 1;
261
262 guint activates_default : 1;
263 guint cache_includes_preedit : 1;
264 guint caps_lock_warning : 1;
265 guint caps_lock_warning_shown : 1;
266 guint change_count : 8;
267 guint cursor_visible : 1;
268 guint editing_canceled : 1; /* Only used by CtkCellRendererText */
269 guint in_click : 1; /* Flag so we don't select all when clicking in entry to focus in */
270 guint invisible_char_set : 1;
271 guint mouse_cursor_obscured : 1;
272 guint need_im_reset : 1;
273 guint progress_pulse_mode : 1;
274 guint progress_pulse_way_back : 1;
275 guint real_changed : 1;
276 guint resolved_dir : 4; /* PangoDirection */
277 guint select_words : 1;
278 guint select_lines : 1;
279 guint truncate_multiline : 1;
280 guint cursor_handle_dragged : 1;
281 guint selection_handle_dragged : 1;
282 guint populate_all : 1;
283 guint handling_key_event : 1;
284};
285
286struct _EntryIconInfo
287{
288 CdkWindow *window;
289 gchar *tooltip;
290 guint insensitive : 1;
291 guint nonactivatable : 1;
292 guint prelight : 1;
293 guint in_drag : 1;
294 guint pressed : 1;
295
296 CdkDragAction actions;
297 CtkTargetList *target_list;
298 CtkCssGadget *gadget;
299 CdkEventSequence *current_sequence;
300 CdkDevice *device;
301};
302
303struct _CtkEntryPasswordHint
304{
305 gint position; /* Position (in text) of the last password hint */
306 guint source_id; /* Timeout source id */
307};
308
309struct _CtkEntryCapslockFeedback
310{
311 CtkWidget *entry;
312 CtkWidget *window;
313 CtkWidget *label;
314};
315
316enum {
317 ACTIVATE,
318 POPULATE_POPUP,
319 MOVE_CURSOR,
320 INSERT_AT_CURSOR,
321 DELETE_FROM_CURSOR,
322 BACKSPACE,
323 CUT_CLIPBOARD,
324 COPY_CLIPBOARD,
325 PASTE_CLIPBOARD,
326 TOGGLE_OVERWRITE,
327 ICON_PRESS,
328 ICON_RELEASE,
329 PREEDIT_CHANGED,
330 INSERT_EMOJI,
331 LAST_SIGNAL
332};
333
334enum {
335 PROP_0,
336 PROP_BUFFER,
337 PROP_CURSOR_POSITION,
338 PROP_SELECTION_BOUND,
339 PROP_EDITABLE,
340 PROP_MAX_LENGTH,
341 PROP_VISIBILITY,
342 PROP_HAS_FRAME,
343 PROP_INNER_BORDER,
344 PROP_INVISIBLE_CHAR,
345 PROP_ACTIVATES_DEFAULT,
346 PROP_WIDTH_CHARS,
347 PROP_MAX_WIDTH_CHARS,
348 PROP_SCROLL_OFFSET,
349 PROP_TEXT,
350 PROP_XALIGN,
351 PROP_TRUNCATE_MULTILINE,
352 PROP_SHADOW_TYPE,
353 PROP_OVERWRITE_MODE,
354 PROP_TEXT_LENGTH,
355 PROP_INVISIBLE_CHAR_SET,
356 PROP_CAPS_LOCK_WARNING,
357 PROP_PROGRESS_FRACTION,
358 PROP_PROGRESS_PULSE_STEP,
359 PROP_PIXBUF_PRIMARY,
360 PROP_PIXBUF_SECONDARY,
361 PROP_STOCK_PRIMARY,
362 PROP_STOCK_SECONDARY,
363 PROP_ICON_NAME_PRIMARY,
364 PROP_ICON_NAME_SECONDARY,
365 PROP_GICON_PRIMARY,
366 PROP_GICON_SECONDARY,
367 PROP_STORAGE_TYPE_PRIMARY,
368 PROP_STORAGE_TYPE_SECONDARY,
369 PROP_ACTIVATABLE_PRIMARY,
370 PROP_ACTIVATABLE_SECONDARY,
371 PROP_SENSITIVE_PRIMARY,
372 PROP_SENSITIVE_SECONDARY,
373 PROP_TOOLTIP_TEXT_PRIMARY,
374 PROP_TOOLTIP_TEXT_SECONDARY,
375 PROP_TOOLTIP_MARKUP_PRIMARY,
376 PROP_TOOLTIP_MARKUP_SECONDARY,
377 PROP_IM_MODULE,
378 PROP_PLACEHOLDER_TEXT,
379 PROP_COMPLETION,
380 PROP_INPUT_PURPOSE,
381 PROP_INPUT_HINTS,
382 PROP_ATTRIBUTES,
383 PROP_POPULATE_ALL,
384 PROP_TABS,
385 PROP_SHOW_EMOJI_ICON,
386 PROP_ENABLE_EMOJI_COMPLETION,
387 PROP_EDITING_CANCELED,
388 NUM_PROPERTIES = PROP_EDITING_CANCELED
389};
390
391static GParamSpec *entry_props[NUM_PROPERTIES] = { NULL((void*)0), };
392
393static guint signals[LAST_SIGNAL] = { 0 };
394
395typedef enum {
396 CURSOR_STANDARD,
397 CURSOR_DND
398} CursorType;
399
400typedef enum
401{
402 DISPLAY_NORMAL, /* The entry text is being shown */
403 DISPLAY_INVISIBLE, /* In invisible mode, text replaced by (eg) bullets */
404 DISPLAY_BLANK /* In invisible mode, nothing shown at all */
405} DisplayMode;
406
407/* GObject methods
408 */
409static void ctk_entry_editable_init (CtkEditableInterface *iface);
410static void ctk_entry_cell_editable_init (CtkCellEditableIface *iface);
411static void ctk_entry_set_property (GObject *object,
412 guint prop_id,
413 const GValue *value,
414 GParamSpec *pspec);
415static void ctk_entry_get_property (GObject *object,
416 guint prop_id,
417 GValue *value,
418 GParamSpec *pspec);
419static void ctk_entry_finalize (GObject *object);
420static void ctk_entry_dispose (GObject *object);
421
422/* CtkWidget methods
423 */
424static void ctk_entry_destroy (CtkWidget *widget);
425static void ctk_entry_realize (CtkWidget *widget);
426static void ctk_entry_unrealize (CtkWidget *widget);
427static void ctk_entry_map (CtkWidget *widget);
428static void ctk_entry_unmap (CtkWidget *widget);
429static void ctk_entry_get_preferred_width (CtkWidget *widget,
430 gint *minimum,
431 gint *natural);
432static void ctk_entry_get_preferred_height (CtkWidget *widget,
433 gint *minimum,
434 gint *natural);
435static void ctk_entry_get_preferred_height_and_baseline_for_width (CtkWidget *widget,
436 gint width,
437 gint *minimum_height,
438 gint *natural_height,
439 gint *minimum_baseline,
440 gint *natural_baseline);
441static void ctk_entry_size_allocate (CtkWidget *widget,
442 CtkAllocation *allocation);
443static gint ctk_entry_draw (CtkWidget *widget,
444 cairo_t *cr);
445static gboolean ctk_entry_event (CtkWidget *widget,
446 CdkEvent *event);
447static gint ctk_entry_enter_notify (CtkWidget *widget,
448 CdkEventCrossing *event);
449static gint ctk_entry_leave_notify (CtkWidget *widget,
450 CdkEventCrossing *event);
451static gint ctk_entry_key_press (CtkWidget *widget,
452 CdkEventKey *event);
453static gint ctk_entry_key_release (CtkWidget *widget,
454 CdkEventKey *event);
455static gint ctk_entry_focus_in (CtkWidget *widget,
456 CdkEventFocus *event);
457static gint ctk_entry_focus_out (CtkWidget *widget,
458 CdkEventFocus *event);
459static void ctk_entry_grab_focus (CtkWidget *widget);
460static void ctk_entry_style_updated (CtkWidget *widget);
461static gboolean ctk_entry_query_tooltip (CtkWidget *widget,
462 gint x,
463 gint y,
464 gboolean keyboard_tip,
465 CtkTooltip *tooltip);
466static void ctk_entry_direction_changed (CtkWidget *widget,
467 CtkTextDirection previous_dir);
468static void ctk_entry_state_flags_changed (CtkWidget *widget,
469 CtkStateFlags previous_state);
470static void ctk_entry_screen_changed (CtkWidget *widget,
471 CdkScreen *old_screen);
472
473static gboolean ctk_entry_drag_drop (CtkWidget *widget,
474 CdkDragContext *context,
475 gint x,
476 gint y,
477 guint time);
478static gboolean ctk_entry_drag_motion (CtkWidget *widget,
479 CdkDragContext *context,
480 gint x,
481 gint y,
482 guint time);
483static void ctk_entry_drag_leave (CtkWidget *widget,
484 CdkDragContext *context,
485 guint time);
486static void ctk_entry_drag_data_received (CtkWidget *widget,
487 CdkDragContext *context,
488 gint x,
489 gint y,
490 CtkSelectionData *selection_data,
491 guint info,
492 guint time);
493static void ctk_entry_drag_data_get (CtkWidget *widget,
494 CdkDragContext *context,
495 CtkSelectionData *selection_data,
496 guint info,
497 guint time);
498static void ctk_entry_drag_data_delete (CtkWidget *widget,
499 CdkDragContext *context);
500static void ctk_entry_drag_begin (CtkWidget *widget,
501 CdkDragContext *context);
502static void ctk_entry_drag_end (CtkWidget *widget,
503 CdkDragContext *context);
504
505
506/* CtkEditable method implementations
507 */
508static void ctk_entry_insert_text (CtkEditable *editable,
509 const gchar *new_text,
510 gint new_text_length,
511 gint *position);
512static void ctk_entry_delete_text (CtkEditable *editable,
513 gint start_pos,
514 gint end_pos);
515static gchar * ctk_entry_get_chars (CtkEditable *editable,
516 gint start_pos,
517 gint end_pos);
518static void ctk_entry_real_set_position (CtkEditable *editable,
519 gint position);
520static gint ctk_entry_get_position (CtkEditable *editable);
521static void ctk_entry_set_selection_bounds (CtkEditable *editable,
522 gint start,
523 gint end);
524static gboolean ctk_entry_get_selection_bounds (CtkEditable *editable,
525 gint *start,
526 gint *end);
527
528/* CtkCellEditable method implementations
529 */
530static void ctk_entry_start_editing (CtkCellEditable *cell_editable,
531 CdkEvent *event);
532
533/* Default signal handlers
534 */
535static void ctk_entry_real_insert_text (CtkEditable *editable,
536 const gchar *new_text,
537 gint new_text_length,
538 gint *position);
539static void ctk_entry_real_delete_text (CtkEditable *editable,
540 gint start_pos,
541 gint end_pos);
542static void ctk_entry_move_cursor (CtkEntry *entry,
543 CtkMovementStep step,
544 gint count,
545 gboolean extend_selection);
546static void ctk_entry_insert_at_cursor (CtkEntry *entry,
547 const gchar *str);
548static void ctk_entry_delete_from_cursor (CtkEntry *entry,
549 CtkDeleteType type,
550 gint count);
551static void ctk_entry_backspace (CtkEntry *entry);
552static void ctk_entry_cut_clipboard (CtkEntry *entry);
553static void ctk_entry_copy_clipboard (CtkEntry *entry);
554static void ctk_entry_paste_clipboard (CtkEntry *entry);
555static void ctk_entry_toggle_overwrite (CtkEntry *entry);
556static void ctk_entry_insert_emoji (CtkEntry *entry);
557static void ctk_entry_select_all (CtkEntry *entry);
558static void ctk_entry_real_activate (CtkEntry *entry);
559static gboolean ctk_entry_popup_menu (CtkWidget *widget);
560
561static void keymap_direction_changed (CdkKeymap *keymap,
562 CtkEntry *entry);
563static void keymap_state_changed (CdkKeymap *keymap,
564 CtkEntry *entry);
565static void remove_capslock_feedback (CtkEntry *entry);
566
567/* IM Context Callbacks
568 */
569static void ctk_entry_commit_cb (CtkIMContext *context,
570 const gchar *str,
571 CtkEntry *entry);
572static void ctk_entry_preedit_changed_cb (CtkIMContext *context,
573 CtkEntry *entry);
574static gboolean ctk_entry_retrieve_surrounding_cb (CtkIMContext *context,
575 CtkEntry *entry);
576static gboolean ctk_entry_delete_surrounding_cb (CtkIMContext *context,
577 gint offset,
578 gint n_chars,
579 CtkEntry *entry);
580
581/* Event controller callbacks */
582static void ctk_entry_multipress_gesture_pressed (CtkGestureMultiPress *gesture,
583 gint n_press,
584 gdouble x,
585 gdouble y,
586 CtkEntry *entry);
587static void ctk_entry_drag_gesture_update (CtkGestureDrag *gesture,
588 gdouble offset_x,
589 gdouble offset_y,
590 CtkEntry *entry);
591static void ctk_entry_drag_gesture_end (CtkGestureDrag *gesture,
592 gdouble offset_x,
593 gdouble offset_y,
594 CtkEntry *entry);
595
596/* Internal routines
597 */
598static void ctk_entry_draw_text (CtkEntry *entry,
599 cairo_t *cr);
600static void ctk_entry_draw_cursor (CtkEntry *entry,
601 cairo_t *cr,
602 CursorType type);
603static PangoLayout *ctk_entry_ensure_layout (CtkEntry *entry,
604 gboolean include_preedit);
605static void ctk_entry_reset_layout (CtkEntry *entry);
606static void ctk_entry_recompute (CtkEntry *entry);
607static gint ctk_entry_find_position (CtkEntry *entry,
608 gint x);
609static void ctk_entry_get_cursor_locations (CtkEntry *entry,
610 CursorType type,
611 gint *strong_x,
612 gint *weak_x);
613static void ctk_entry_adjust_scroll (CtkEntry *entry);
614static gint ctk_entry_move_visually (CtkEntry *editable,
615 gint start,
616 gint count);
617static gint ctk_entry_move_logically (CtkEntry *entry,
618 gint start,
619 gint count);
620static gint ctk_entry_move_forward_word (CtkEntry *entry,
621 gint start,
622 gboolean allow_whitespace);
623static gint ctk_entry_move_backward_word (CtkEntry *entry,
624 gint start,
625 gboolean allow_whitespace);
626static void ctk_entry_delete_whitespace (CtkEntry *entry);
627static void ctk_entry_select_word (CtkEntry *entry);
628static void ctk_entry_select_line (CtkEntry *entry);
629static void ctk_entry_paste (CtkEntry *entry,
630 CdkAtom selection);
631static void ctk_entry_update_primary_selection (CtkEntry *entry);
632static void ctk_entry_do_popup (CtkEntry *entry,
633 const CdkEvent *event);
634static gboolean ctk_entry_mnemonic_activate (CtkWidget *widget,
635 gboolean group_cycling);
636static void ctk_entry_grab_notify (CtkWidget *widget,
637 gboolean was_grabbed);
638static void ctk_entry_check_cursor_blink (CtkEntry *entry);
639static void ctk_entry_pend_cursor_blink (CtkEntry *entry);
640static void ctk_entry_reset_blink_time (CtkEntry *entry);
641static void ctk_entry_get_text_area_size (CtkEntry *entry,
642 gint *x,
643 gint *y,
644 gint *width,
645 gint *height);
646static void ctk_entry_get_frame_size (CtkEntry *entry,
647 gint *x,
648 gint *y,
649 gint *width,
650 gint *height);
651static void get_frame_size (CtkEntry *entry,
652 gboolean relative_to_window,
653 gint *x,
654 gint *y,
655 gint *width,
656 gint *height);
657static void ctk_entry_move_adjustments (CtkEntry *entry);
658static void ctk_entry_update_cached_style_values(CtkEntry *entry);
659static gboolean get_middle_click_paste (CtkEntry *entry);
660static void ctk_entry_get_scroll_limits (CtkEntry *entry,
661 gint *min_offset,
662 gint *max_offset);
663
664/* CtkTextHandle handlers */
665static void ctk_entry_handle_drag_started (CtkTextHandle *handle,
666 CtkTextHandlePosition pos,
667 CtkEntry *entry);
668static void ctk_entry_handle_dragged (CtkTextHandle *handle,
669 CtkTextHandlePosition pos,
670 gint x,
671 gint y,
672 CtkEntry *entry);
673static void ctk_entry_handle_drag_finished (CtkTextHandle *handle,
674 CtkTextHandlePosition pos,
675 CtkEntry *entry);
676
677static void ctk_entry_selection_bubble_popup_set (CtkEntry *entry);
678static void ctk_entry_selection_bubble_popup_unset (CtkEntry *entry);
679
680static void begin_change (CtkEntry *entry);
681static void end_change (CtkEntry *entry);
682static void emit_changed (CtkEntry *entry);
683
684static void buffer_inserted_text (CtkEntryBuffer *buffer,
685 guint position,
686 const gchar *chars,
687 guint n_chars,
688 CtkEntry *entry);
689static void buffer_deleted_text (CtkEntryBuffer *buffer,
690 guint position,
691 guint n_chars,
692 CtkEntry *entry);
693static void buffer_notify_text (CtkEntryBuffer *buffer,
694 GParamSpec *spec,
695 CtkEntry *entry);
696static void buffer_notify_length (CtkEntryBuffer *buffer,
697 GParamSpec *spec,
698 CtkEntry *entry);
699static void buffer_notify_max_length (CtkEntryBuffer *buffer,
700 GParamSpec *spec,
701 CtkEntry *entry);
702static void buffer_connect_signals (CtkEntry *entry);
703static void buffer_disconnect_signals (CtkEntry *entry);
704static CtkEntryBuffer *get_buffer (CtkEntry *entry);
705static void set_show_emoji_icon (CtkEntry *entry,
706 gboolean value);
707static void set_enable_emoji_completion (CtkEntry *entry,
708 gboolean value);
709
710static void ctk_entry_measure (CtkCssGadget *gadget,
711 CtkOrientation orientation,
712 int for_size,
713 int *minimum,
714 int *natural,
715 int *minimum_baseline,
716 int *natural_baseline,
717 gpointer data);
718static void ctk_entry_allocate (CtkCssGadget *gadget,
719 const CtkAllocation *allocation,
720 int baseline,
721 CtkAllocation *out_clip,
722 gpointer data);
723static gboolean ctk_entry_render (CtkCssGadget *gadget,
724 cairo_t *cr,
725 int x,
726 int y,
727 int width,
728 int height,
729 gpointer data);
730
731G_DEFINE_TYPE_WITH_CODE (CtkEntry, ctk_entry, CTK_TYPE_WIDGET,static void ctk_entry_init (CtkEntry *self); static void ctk_entry_class_init
(CtkEntryClass *klass); static GType ctk_entry_get_type_once
(void); static gpointer ctk_entry_parent_class = ((void*)0);
static gint CtkEntry_private_offset; static void ctk_entry_class_intern_init
(gpointer klass) { ctk_entry_parent_class = g_type_class_peek_parent
(klass); if (CtkEntry_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CtkEntry_private_offset); ctk_entry_class_init (
(CtkEntryClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer ctk_entry_get_instance_private (CtkEntry *self
) { return (((gpointer) ((guint8*) (self) + (glong) (CtkEntry_private_offset
)))); } GType ctk_entry_get_type (void) { static GType 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) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_entry_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_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_entry_get_type_once (void) {
GType g_define_type_id = g_type_register_static_simple ((ctk_widget_get_type
()), g_intern_static_string ("CtkEntry"), sizeof (CtkEntryClass
), (GClassInitFunc)(void (*)(void)) ctk_entry_class_intern_init
, sizeof (CtkEntry), (GInstanceInitFunc)(void (*)(void)) ctk_entry_init
, (GTypeFlags) 0); { {{ CtkEntry_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkEntryPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_entry_editable_init, ((void*)0), ((void*)0) }; g_type_add_interface_static
(g_define_type_id, (ctk_editable_get_type ()), &g_implement_interface_info
); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_entry_cell_editable_init, ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_cell_editable_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
732 G_ADD_PRIVATE (CtkEntry)static void ctk_entry_init (CtkEntry *self); static void ctk_entry_class_init
(CtkEntryClass *klass); static GType ctk_entry_get_type_once
(void); static gpointer ctk_entry_parent_class = ((void*)0);
static gint CtkEntry_private_offset; static void ctk_entry_class_intern_init
(gpointer klass) { ctk_entry_parent_class = g_type_class_peek_parent
(klass); if (CtkEntry_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CtkEntry_private_offset); ctk_entry_class_init (
(CtkEntryClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer ctk_entry_get_instance_private (CtkEntry *self
) { return (((gpointer) ((guint8*) (self) + (glong) (CtkEntry_private_offset
)))); } GType ctk_entry_get_type (void) { static GType 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) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_entry_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_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_entry_get_type_once (void) {
GType g_define_type_id = g_type_register_static_simple ((ctk_widget_get_type
()), g_intern_static_string ("CtkEntry"), sizeof (CtkEntryClass
), (GClassInitFunc)(void (*)(void)) ctk_entry_class_intern_init
, sizeof (CtkEntry), (GInstanceInitFunc)(void (*)(void)) ctk_entry_init
, (GTypeFlags) 0); { {{ CtkEntry_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkEntryPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_entry_editable_init, ((void*)0), ((void*)0) }; g_type_add_interface_static
(g_define_type_id, (ctk_editable_get_type ()), &g_implement_interface_info
); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_entry_cell_editable_init, ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_cell_editable_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
733 G_IMPLEMENT_INTERFACE (CTK_TYPE_EDITABLE,static void ctk_entry_init (CtkEntry *self); static void ctk_entry_class_init
(CtkEntryClass *klass); static GType ctk_entry_get_type_once
(void); static gpointer ctk_entry_parent_class = ((void*)0);
static gint CtkEntry_private_offset; static void ctk_entry_class_intern_init
(gpointer klass) { ctk_entry_parent_class = g_type_class_peek_parent
(klass); if (CtkEntry_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CtkEntry_private_offset); ctk_entry_class_init (
(CtkEntryClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer ctk_entry_get_instance_private (CtkEntry *self
) { return (((gpointer) ((guint8*) (self) + (glong) (CtkEntry_private_offset
)))); } GType ctk_entry_get_type (void) { static GType 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) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_entry_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_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_entry_get_type_once (void) {
GType g_define_type_id = g_type_register_static_simple ((ctk_widget_get_type
()), g_intern_static_string ("CtkEntry"), sizeof (CtkEntryClass
), (GClassInitFunc)(void (*)(void)) ctk_entry_class_intern_init
, sizeof (CtkEntry), (GInstanceInitFunc)(void (*)(void)) ctk_entry_init
, (GTypeFlags) 0); { {{ CtkEntry_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkEntryPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_entry_editable_init, ((void*)0), ((void*)0) }; g_type_add_interface_static
(g_define_type_id, (ctk_editable_get_type ()), &g_implement_interface_info
); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_entry_cell_editable_init, ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_cell_editable_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
734 ctk_entry_editable_init)static void ctk_entry_init (CtkEntry *self); static void ctk_entry_class_init
(CtkEntryClass *klass); static GType ctk_entry_get_type_once
(void); static gpointer ctk_entry_parent_class = ((void*)0);
static gint CtkEntry_private_offset; static void ctk_entry_class_intern_init
(gpointer klass) { ctk_entry_parent_class = g_type_class_peek_parent
(klass); if (CtkEntry_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CtkEntry_private_offset); ctk_entry_class_init (
(CtkEntryClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer ctk_entry_get_instance_private (CtkEntry *self
) { return (((gpointer) ((guint8*) (self) + (glong) (CtkEntry_private_offset
)))); } GType ctk_entry_get_type (void) { static GType 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) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_entry_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_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_entry_get_type_once (void) {
GType g_define_type_id = g_type_register_static_simple ((ctk_widget_get_type
()), g_intern_static_string ("CtkEntry"), sizeof (CtkEntryClass
), (GClassInitFunc)(void (*)(void)) ctk_entry_class_intern_init
, sizeof (CtkEntry), (GInstanceInitFunc)(void (*)(void)) ctk_entry_init
, (GTypeFlags) 0); { {{ CtkEntry_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkEntryPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_entry_editable_init, ((void*)0), ((void*)0) }; g_type_add_interface_static
(g_define_type_id, (ctk_editable_get_type ()), &g_implement_interface_info
); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_entry_cell_editable_init, ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_cell_editable_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
735 G_IMPLEMENT_INTERFACE (CTK_TYPE_CELL_EDITABLE,static void ctk_entry_init (CtkEntry *self); static void ctk_entry_class_init
(CtkEntryClass *klass); static GType ctk_entry_get_type_once
(void); static gpointer ctk_entry_parent_class = ((void*)0);
static gint CtkEntry_private_offset; static void ctk_entry_class_intern_init
(gpointer klass) { ctk_entry_parent_class = g_type_class_peek_parent
(klass); if (CtkEntry_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CtkEntry_private_offset); ctk_entry_class_init (
(CtkEntryClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer ctk_entry_get_instance_private (CtkEntry *self
) { return (((gpointer) ((guint8*) (self) + (glong) (CtkEntry_private_offset
)))); } GType ctk_entry_get_type (void) { static GType 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) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_entry_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_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_entry_get_type_once (void) {
GType g_define_type_id = g_type_register_static_simple ((ctk_widget_get_type
()), g_intern_static_string ("CtkEntry"), sizeof (CtkEntryClass
), (GClassInitFunc)(void (*)(void)) ctk_entry_class_intern_init
, sizeof (CtkEntry), (GInstanceInitFunc)(void (*)(void)) ctk_entry_init
, (GTypeFlags) 0); { {{ CtkEntry_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkEntryPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_entry_editable_init, ((void*)0), ((void*)0) }; g_type_add_interface_static
(g_define_type_id, (ctk_editable_get_type ()), &g_implement_interface_info
); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_entry_cell_editable_init, ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_cell_editable_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
736 ctk_entry_cell_editable_init))static void ctk_entry_init (CtkEntry *self); static void ctk_entry_class_init
(CtkEntryClass *klass); static GType ctk_entry_get_type_once
(void); static gpointer ctk_entry_parent_class = ((void*)0);
static gint CtkEntry_private_offset; static void ctk_entry_class_intern_init
(gpointer klass) { ctk_entry_parent_class = g_type_class_peek_parent
(klass); if (CtkEntry_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CtkEntry_private_offset); ctk_entry_class_init (
(CtkEntryClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer ctk_entry_get_instance_private (CtkEntry *self
) { return (((gpointer) ((guint8*) (self) + (glong) (CtkEntry_private_offset
)))); } GType ctk_entry_get_type (void) { static GType 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) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_entry_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_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_entry_get_type_once (void) {
GType g_define_type_id = g_type_register_static_simple ((ctk_widget_get_type
()), g_intern_static_string ("CtkEntry"), sizeof (CtkEntryClass
), (GClassInitFunc)(void (*)(void)) ctk_entry_class_intern_init
, sizeof (CtkEntry), (GInstanceInitFunc)(void (*)(void)) ctk_entry_init
, (GTypeFlags) 0); { {{ CtkEntry_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkEntryPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_entry_editable_init, ((void*)0), ((void*)0) }; g_type_add_interface_static
(g_define_type_id, (ctk_editable_get_type ()), &g_implement_interface_info
); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_entry_cell_editable_init, ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_cell_editable_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
737
738static void
739add_move_binding (CtkBindingSet *binding_set,
740 guint keyval,
741 guint modmask,
742 CtkMovementStep step,
743 gint count)
744{
745 g_return_if_fail ((modmask & CDK_SHIFT_MASK) == 0)do { if (((modmask & CDK_SHIFT_MASK) == 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "(modmask & CDK_SHIFT_MASK) == 0"
); return; } } while (0)
;
746
747 ctk_binding_entry_add_signal (binding_set, keyval, modmask,
748 "move-cursor", 3,
749 G_TYPE_ENUM((GType) ((12) << (2))), step,
750 G_TYPE_INT((GType) ((6) << (2))), count,
751 G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0));
752
753 /* Selection-extending version */
754 ctk_binding_entry_add_signal (binding_set, keyval, modmask | CDK_SHIFT_MASK,
755 "move-cursor", 3,
756 G_TYPE_ENUM((GType) ((12) << (2))), step,
757 G_TYPE_INT((GType) ((6) << (2))), count,
758 G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)));
759}
760
761static void
762ctk_entry_class_init (CtkEntryClass *class)
763{
764 GObjectClass *gobject_class = G_OBJECT_CLASS (class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((class)), (((GType) ((20) << (2))))))))
;
765 CtkWidgetClass *widget_class;
766 CtkBindingSet *binding_set;
767
768 widget_class = (CtkWidgetClass*) class;
769
770 gobject_class->dispose = ctk_entry_dispose;
771 gobject_class->finalize = ctk_entry_finalize;
772 gobject_class->set_property = ctk_entry_set_property;
773 gobject_class->get_property = ctk_entry_get_property;
774
775 widget_class->destroy = ctk_entry_destroy;
776 widget_class->map = ctk_entry_map;
777 widget_class->unmap = ctk_entry_unmap;
778 widget_class->realize = ctk_entry_realize;
779 widget_class->unrealize = ctk_entry_unrealize;
780 widget_class->get_preferred_width = ctk_entry_get_preferred_width;
781 widget_class->get_preferred_height = ctk_entry_get_preferred_height;
782 widget_class->get_preferred_height_and_baseline_for_width = ctk_entry_get_preferred_height_and_baseline_for_width;
783 widget_class->size_allocate = ctk_entry_size_allocate;
784 widget_class->draw = ctk_entry_draw;
785 widget_class->enter_notify_event = ctk_entry_enter_notify;
786 widget_class->leave_notify_event = ctk_entry_leave_notify;
787 widget_class->event = ctk_entry_event;
788 widget_class->key_press_event = ctk_entry_key_press;
789 widget_class->key_release_event = ctk_entry_key_release;
790 widget_class->focus_in_event = ctk_entry_focus_in;
791 widget_class->focus_out_event = ctk_entry_focus_out;
792 widget_class->grab_focus = ctk_entry_grab_focus;
793 widget_class->style_updated = ctk_entry_style_updated;
794 widget_class->query_tooltip = ctk_entry_query_tooltip;
795 widget_class->drag_begin = ctk_entry_drag_begin;
796 widget_class->drag_end = ctk_entry_drag_end;
797 widget_class->direction_changed = ctk_entry_direction_changed;
798 widget_class->state_flags_changed = ctk_entry_state_flags_changed;
799 widget_class->screen_changed = ctk_entry_screen_changed;
800 widget_class->mnemonic_activate = ctk_entry_mnemonic_activate;
801 widget_class->grab_notify = ctk_entry_grab_notify;
802
803 widget_class->drag_drop = ctk_entry_drag_drop;
804 widget_class->drag_motion = ctk_entry_drag_motion;
805 widget_class->drag_leave = ctk_entry_drag_leave;
806 widget_class->drag_data_received = ctk_entry_drag_data_received;
807 widget_class->drag_data_get = ctk_entry_drag_data_get;
808 widget_class->drag_data_delete = ctk_entry_drag_data_delete;
809
810 widget_class->popup_menu = ctk_entry_popup_menu;
811
812 class->move_cursor = ctk_entry_move_cursor;
813 class->insert_at_cursor = ctk_entry_insert_at_cursor;
814 class->delete_from_cursor = ctk_entry_delete_from_cursor;
815 class->backspace = ctk_entry_backspace;
816 class->cut_clipboard = ctk_entry_cut_clipboard;
817 class->copy_clipboard = ctk_entry_copy_clipboard;
818 class->paste_clipboard = ctk_entry_paste_clipboard;
819 class->toggle_overwrite = ctk_entry_toggle_overwrite;
820 class->insert_emoji = ctk_entry_insert_emoji;
821 class->activate = ctk_entry_real_activate;
822 class->get_text_area_size = ctk_entry_get_text_area_size;
823 class->get_frame_size = ctk_entry_get_frame_size;
824
825 quark_inner_border = g_quark_from_static_string ("ctk-entry-inner-border");
826 quark_password_hint = g_quark_from_static_string ("ctk-entry-password-hint");
827 quark_cursor_hadjustment = g_quark_from_static_string ("ctk-hadjustment");
828 quark_capslock_feedback = g_quark_from_static_string ("ctk-entry-capslock-feedback");
829 quark_ctk_signal = g_quark_from_static_string ("ctk-signal");
830 quark_entry_completion = g_quark_from_static_string ("ctk-entry-completion-key");
831
832 g_object_class_override_property (gobject_class,
833 PROP_EDITING_CANCELED,
834 "editing-canceled");
835
836 entry_props[PROP_BUFFER] =
837 g_param_spec_object ("buffer",
838 P_("Text Buffer")g_dgettext("ctk30" "-properties","Text Buffer"),
839 P_("Text buffer object which actually stores entry text")g_dgettext("ctk30" "-properties","Text buffer object which actually stores entry text"
)
,
840 CTK_TYPE_ENTRY_BUFFER(ctk_entry_buffer_get_type ()),
841 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_CONSTRUCT|G_PARAM_EXPLICIT_NOTIFY);
842
843 entry_props[PROP_CURSOR_POSITION] =
844 g_param_spec_int ("cursor-position",
845 P_("Cursor Position")g_dgettext("ctk30" "-properties","Cursor Position"),
846 P_("The current position of the insertion cursor in chars")g_dgettext("ctk30" "-properties","The current position of the insertion cursor in chars"
)
,
847 0, CTK_ENTRY_BUFFER_MAX_SIZE(32767 *2 +1),
848 0,
849 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB);
850
851 entry_props[PROP_SELECTION_BOUND] =
852 g_param_spec_int ("selection-bound",
853 P_("Selection Bound")g_dgettext("ctk30" "-properties","Selection Bound"),
854 P_("The position of the opposite end of the selection from the cursor in chars")g_dgettext("ctk30" "-properties","The position of the opposite end of the selection from the cursor in chars"
)
,
855 0, CTK_ENTRY_BUFFER_MAX_SIZE(32767 *2 +1),
856 0,
857 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB);
858
859 entry_props[PROP_EDITABLE] =
860 g_param_spec_boolean ("editable",
861 P_("Editable")g_dgettext("ctk30" "-properties","Editable"),
862 P_("Whether the entry contents can be edited")g_dgettext("ctk30" "-properties","Whether the entry contents can be edited"
)
,
863 TRUE(!(0)),
864 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
865
866 entry_props[PROP_MAX_LENGTH] =
867 g_param_spec_int ("max-length",
868 P_("Maximum length")g_dgettext("ctk30" "-properties","Maximum length"),
869 P_("Maximum number of characters for this entry. Zero if no maximum")g_dgettext("ctk30" "-properties","Maximum number of characters for this entry. Zero if no maximum"
)
,
870 0, CTK_ENTRY_BUFFER_MAX_SIZE(32767 *2 +1),
871 0,
872 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
873
874 entry_props[PROP_VISIBILITY] =
875 g_param_spec_boolean ("visibility",
876 P_("Visibility")g_dgettext("ctk30" "-properties","Visibility"),
877 P_("FALSE displays the \"invisible char\" instead of the actual text (password mode)")g_dgettext("ctk30" "-properties","FALSE displays the \"invisible char\" instead of the actual text (password mode)"
)
,
878 TRUE(!(0)),
879 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
880
881 entry_props[PROP_HAS_FRAME] =
882 g_param_spec_boolean ("has-frame",
883 P_("Has Frame")g_dgettext("ctk30" "-properties","Has Frame"),
884 P_("FALSE removes outside bevel from entry")g_dgettext("ctk30" "-properties","FALSE removes outside bevel from entry"
)
,
885 TRUE(!(0)),
886 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
887
888 /**
889 * CtkEntry:inner-border:
890 *
891 * Sets the text area's border between the text and the frame.
892 *
893 * Deprecated: 3.4: Use the standard border and padding CSS properties
894 * (through objects like #CtkStyleContext and #CtkCssProvider); the value
895 * of this style property is ignored.
896 */
897 entry_props[PROP_INNER_BORDER] =
898 g_param_spec_boxed ("inner-border",
899 P_("Inner Border")g_dgettext("ctk30" "-properties","Inner Border"),
900 P_("Border between text and frame. Overrides the inner-border style property")g_dgettext("ctk30" "-properties","Border between text and frame. Overrides the inner-border style property"
)
,
901 CTK_TYPE_BORDER(ctk_border_get_type ()),
902 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_DEPRECATED);
903
904 entry_props[PROP_INVISIBLE_CHAR] =
905 g_param_spec_unichar ("invisible-char",
906 P_("Invisible character")g_dgettext("ctk30" "-properties","Invisible character"),
907 P_("The character to use when masking entry contents (in \"password mode\")")g_dgettext("ctk30" "-properties","The character to use when masking entry contents (in \"password mode\")"
)
,
908 '*',
909 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
910
911 entry_props[PROP_ACTIVATES_DEFAULT] =
912 g_param_spec_boolean ("activates-default",
913 P_("Activates default")g_dgettext("ctk30" "-properties","Activates default"),
914 P_("Whether to activate the default widget (such as the default button in a dialog) when Enter is pressed")g_dgettext("ctk30" "-properties","Whether to activate the default widget (such as the default button in a dialog) when Enter is pressed"
)
,
915 FALSE(0),
916 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
917
918 entry_props[PROP_WIDTH_CHARS] =
919 g_param_spec_int ("width-chars",
920 P_("Width in chars")g_dgettext("ctk30" "-properties","Width in chars"),
921 P_("Number of characters to leave space for in the entry")g_dgettext("ctk30" "-properties","Number of characters to leave space for in the entry"
)
,
922 -1, G_MAXINT2147483647,
923 -1,
924 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
925
926 /**
927 * CtkEntry:max-width-chars:
928 *
929 * The desired maximum width of the entry, in characters.
930 * If this property is set to -1, the width will be calculated
931 * automatically.
932 *
933 * Since: 3.12
934 */
935 entry_props[PROP_MAX_WIDTH_CHARS] =
936 g_param_spec_int ("max-width-chars",
937 P_("Maximum width in characters")g_dgettext("ctk30" "-properties","Maximum width in characters"
)
,
938 P_("The desired maximum width of the entry, in characters")g_dgettext("ctk30" "-properties","The desired maximum width of the entry, in characters"
)
,
939 -1, G_MAXINT2147483647,
940 -1,
941 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
942
943 entry_props[PROP_SCROLL_OFFSET] =
944 g_param_spec_int ("scroll-offset",
945 P_("Scroll offset")g_dgettext("ctk30" "-properties","Scroll offset"),
946 P_("Number of pixels of the entry scrolled off the screen to the left")g_dgettext("ctk30" "-properties","Number of pixels of the entry scrolled off the screen to the left"
)
,
947 0, G_MAXINT2147483647,
948 0,
949 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
950
951 entry_props[PROP_TEXT] =
952 g_param_spec_string ("text",
953 P_("Text")g_dgettext("ctk30" "-properties","Text"),
954 P_("The contents of the entry")g_dgettext("ctk30" "-properties","The contents of the entry"),
955 "",
956 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
957
958 /**
959 * CtkEntry:xalign:
960 *
961 * The horizontal alignment, from 0 (left) to 1 (right).
962 * Reversed for RTL layouts.
963 *
964 * Since: 2.4
965 */
966 entry_props[PROP_XALIGN] =
967 g_param_spec_float ("xalign",
968 P_("X align")g_dgettext("ctk30" "-properties","X align"),
969 P_("The horizontal alignment, from 0 (left) to 1 (right). Reversed for RTL layouts.")g_dgettext("ctk30" "-properties","The horizontal alignment, from 0 (left) to 1 (right). Reversed for RTL layouts."
)
,
970 0.0, 1.0,
971 0.0,
972 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
973
974 /**
975 * CtkEntry:truncate-multiline:
976 *
977 * When %TRUE, pasted multi-line text is truncated to the first line.
978 *
979 * Since: 2.10
980 */
981 entry_props[PROP_TRUNCATE_MULTILINE] =
982 g_param_spec_boolean ("truncate-multiline",
983 P_("Truncate multiline")g_dgettext("ctk30" "-properties","Truncate multiline"),
984 P_("Whether to truncate multiline pastes to one line.")g_dgettext("ctk30" "-properties","Whether to truncate multiline pastes to one line."
)
,
985 FALSE(0),
986 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
987
988 /**
989 * CtkEntry:shadow-type:
990 *
991 * Which kind of shadow to draw around the entry when
992 * #CtkEntry:has-frame is set to %TRUE.
993 *
994 * Deprecated: 3.20: Use CSS to determine the style of the border;
995 * the value of this style property is ignored.
996 *
997 * Since: 2.12
998 */
999 entry_props[PROP_SHADOW_TYPE] =
1000 g_param_spec_enum ("shadow-type",
1001 P_("Shadow type")g_dgettext("ctk30" "-properties","Shadow type"),
1002 P_("Which kind of shadow to draw around the entry when has-frame is set")g_dgettext("ctk30" "-properties","Which kind of shadow to draw around the entry when has-frame is set"
)
,
1003 CTK_TYPE_SHADOW_TYPE(ctk_shadow_type_get_type ()),
1004 CTK_SHADOW_IN,
1005 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_DEPRECATED);
1006
1007 /**
1008 * CtkEntry:overwrite-mode:
1009 *
1010 * If text is overwritten when typing in the #CtkEntry.
1011 *
1012 * Since: 2.14
1013 */
1014 entry_props[PROP_OVERWRITE_MODE] =
1015 g_param_spec_boolean ("overwrite-mode",
1016 P_("Overwrite mode")g_dgettext("ctk30" "-properties","Overwrite mode"),
1017 P_("Whether new text overwrites existing text")g_dgettext("ctk30" "-properties","Whether new text overwrites existing text"
)
,
1018 FALSE(0),
1019 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1020
1021 /**
1022 * CtkEntry:text-length:
1023 *
1024 * The length of the text in the #CtkEntry.
1025 *
1026 * Since: 2.14
1027 */
1028 entry_props[PROP_TEXT_LENGTH] =
1029 g_param_spec_uint ("text-length",
1030 P_("Text length")g_dgettext("ctk30" "-properties","Text length"),
1031 P_("Length of the text currently in the entry")g_dgettext("ctk30" "-properties","Length of the text currently in the entry"
)
,
1032 0, G_MAXUINT16((guint16) 0xffff),
1033 0,
1034 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB);
1035
1036 /**
1037 * CtkEntry:invisible-char-set:
1038 *
1039 * Whether the invisible char has been set for the #CtkEntry.
1040 *
1041 * Since: 2.16
1042 */
1043 entry_props[PROP_INVISIBLE_CHAR_SET] =
1044 g_param_spec_boolean ("invisible-char-set",
1045 P_("Invisible character set")g_dgettext("ctk30" "-properties","Invisible character set"),
1046 P_("Whether the invisible character has been set")g_dgettext("ctk30" "-properties","Whether the invisible character has been set"
)
,
1047 FALSE(0),
1048 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB);
1049
1050 /**
1051 * CtkEntry:caps-lock-warning:
1052 *
1053 * Whether password entries will show a warning when Caps Lock is on.
1054 *
1055 * Note that the warning is shown using a secondary icon, and thus
1056 * does not work if you are using the secondary icon position for some
1057 * other purpose.
1058 *
1059 * Since: 2.16
1060 */
1061 entry_props[PROP_CAPS_LOCK_WARNING] =
1062 g_param_spec_boolean ("caps-lock-warning",
1063 P_("Caps Lock warning")g_dgettext("ctk30" "-properties","Caps Lock warning"),
1064 P_("Whether password entries will show a warning when Caps Lock is on")g_dgettext("ctk30" "-properties","Whether password entries will show a warning when Caps Lock is on"
)
,
1065 TRUE(!(0)),
1066 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1067
1068 /**
1069 * CtkEntry:progress-fraction:
1070 *
1071 * The current fraction of the task that's been completed.
1072 *
1073 * Since: 2.16
1074 */
1075 entry_props[PROP_PROGRESS_FRACTION] =
1076 g_param_spec_double ("progress-fraction",
1077 P_("Progress Fraction")g_dgettext("ctk30" "-properties","Progress Fraction"),
1078 P_("The current fraction of the task that's been completed")g_dgettext("ctk30" "-properties","The current fraction of the task that's been completed"
)
,
1079 0.0, 1.0,
1080 0.0,
1081 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1082
1083 /**
1084 * CtkEntry:progress-pulse-step:
1085 *
1086 * The fraction of total entry width to move the progress
1087 * bouncing block for each call to ctk_entry_progress_pulse().
1088 *
1089 * Since: 2.16
1090 */
1091 entry_props[PROP_PROGRESS_PULSE_STEP] =
1092 g_param_spec_double ("progress-pulse-step",
1093 P_("Progress Pulse Step")g_dgettext("ctk30" "-properties","Progress Pulse Step"),
1094 P_("The fraction of total entry width to move the progress bouncing block for each call to ctk_entry_progress_pulse()")g_dgettext("ctk30" "-properties","The fraction of total entry width to move the progress bouncing block for each call to ctk_entry_progress_pulse()"
)
,
1095 0.0, 1.0,
1096 0.1,
1097 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1098
1099 /**
1100 * CtkEntry:placeholder-text:
1101 *
1102 * The text that will be displayed in the #CtkEntry when it is empty
1103 * and unfocused.
1104 *
1105 * Since: 3.2
1106 */
1107 entry_props[PROP_PLACEHOLDER_TEXT] =
1108 g_param_spec_string ("placeholder-text",
1109 P_("Placeholder text")g_dgettext("ctk30" "-properties","Placeholder text"),
1110 P_("Show text in the entry when it's empty and unfocused")g_dgettext("ctk30" "-properties","Show text in the entry when it's empty and unfocused"
)
,
1111 NULL((void*)0),
1112 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1113
1114 /**
1115 * CtkEntry:primary-icon-pixbuf:
1116 *
1117 * A pixbuf to use as the primary icon for the entry.
1118 *
1119 * Since: 2.16
1120 */
1121 entry_props[PROP_PIXBUF_PRIMARY] =
1122 g_param_spec_object ("primary-icon-pixbuf",
1123 P_("Primary pixbuf")g_dgettext("ctk30" "-properties","Primary pixbuf"),
1124 P_("Primary pixbuf for the entry")g_dgettext("ctk30" "-properties","Primary pixbuf for the entry"
)
,
1125 GDK_TYPE_PIXBUF(gdk_pixbuf_get_type ()),
1126 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1127
1128 /**
1129 * CtkEntry:secondary-icon-pixbuf:
1130 *
1131 * An pixbuf to use as the secondary icon for the entry.
1132 *
1133 * Since: 2.16
1134 */
1135 entry_props[PROP_PIXBUF_SECONDARY] =
1136 g_param_spec_object ("secondary-icon-pixbuf",
1137 P_("Secondary pixbuf")g_dgettext("ctk30" "-properties","Secondary pixbuf"),
1138 P_("Secondary pixbuf for the entry")g_dgettext("ctk30" "-properties","Secondary pixbuf for the entry"
)
,
1139 GDK_TYPE_PIXBUF(gdk_pixbuf_get_type ()),
1140 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1141
1142 /**
1143 * CtkEntry:primary-icon-stock:
1144 *
1145 * The stock id to use for the primary icon for the entry.
1146 *
1147 * Since: 2.16
1148 *
1149 * Deprecated: 3.10: Use #CtkEntry:primary-icon-name instead.
1150 */
1151 entry_props[PROP_STOCK_PRIMARY] =
1152 g_param_spec_string ("primary-icon-stock",
1153 P_("Primary stock ID")g_dgettext("ctk30" "-properties","Primary stock ID"),
1154 P_("Stock ID for primary icon")g_dgettext("ctk30" "-properties","Stock ID for primary icon"),
1155 NULL((void*)0),
1156 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_DEPRECATED);
1157
1158 /**
1159 * CtkEntry:secondary-icon-stock:
1160 *
1161 * The stock id to use for the secondary icon for the entry.
1162 *
1163 * Since: 2.16
1164 *
1165 * Deprecated: 3.10: Use #CtkEntry:secondary-icon-name instead.
1166 */
1167 entry_props[PROP_STOCK_SECONDARY] =
1168 g_param_spec_string ("secondary-icon-stock",
1169 P_("Secondary stock ID")g_dgettext("ctk30" "-properties","Secondary stock ID"),
1170 P_("Stock ID for secondary icon")g_dgettext("ctk30" "-properties","Stock ID for secondary icon"
)
,
1171 NULL((void*)0),
1172 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_DEPRECATED);
1173
1174 /**
1175 * CtkEntry:primary-icon-name:
1176 *
1177 * The icon name to use for the primary icon for the entry.
1178 *
1179 * Since: 2.16
1180 */
1181 entry_props[PROP_ICON_NAME_PRIMARY] =
1182 g_param_spec_string ("primary-icon-name",
1183 P_("Primary icon name")g_dgettext("ctk30" "-properties","Primary icon name"),
1184 P_("Icon name for primary icon")g_dgettext("ctk30" "-properties","Icon name for primary icon"
)
,
1185 NULL((void*)0),
1186 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1187
1188 /**
1189 * CtkEntry:secondary-icon-name:
1190 *
1191 * The icon name to use for the secondary icon for the entry.
1192 *
1193 * Since: 2.16
1194 */
1195 entry_props[PROP_ICON_NAME_SECONDARY] =
1196 g_param_spec_string ("secondary-icon-name",
1197 P_("Secondary icon name")g_dgettext("ctk30" "-properties","Secondary icon name"),
1198 P_("Icon name for secondary icon")g_dgettext("ctk30" "-properties","Icon name for secondary icon"
)
,
1199 NULL((void*)0),
1200 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1201
1202 /**
1203 * CtkEntry:primary-icon-gicon:
1204 *
1205 * The #GIcon to use for the primary icon for the entry.
1206 *
1207 * Since: 2.16
1208 */
1209 entry_props[PROP_GICON_PRIMARY] =
1210 g_param_spec_object ("primary-icon-gicon",
1211 P_("Primary GIcon")g_dgettext("ctk30" "-properties","Primary GIcon"),
1212 P_("GIcon for primary icon")g_dgettext("ctk30" "-properties","GIcon for primary icon"),
1213 G_TYPE_ICON(g_icon_get_type ()),
1214 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1215
1216 /**
1217 * CtkEntry:secondary-icon-gicon:
1218 *
1219 * The #GIcon to use for the secondary icon for the entry.
1220 *
1221 * Since: 2.16
1222 */
1223 entry_props[PROP_GICON_SECONDARY] =
1224 g_param_spec_object ("secondary-icon-gicon",
1225 P_("Secondary GIcon")g_dgettext("ctk30" "-properties","Secondary GIcon"),
1226 P_("GIcon for secondary icon")g_dgettext("ctk30" "-properties","GIcon for secondary icon"),
1227 G_TYPE_ICON(g_icon_get_type ()),
1228 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1229
1230 /**
1231 * CtkEntry:primary-icon-storage-type:
1232 *
1233 * The representation which is used for the primary icon of the entry.
1234 *
1235 * Since: 2.16
1236 */
1237 entry_props[PROP_STORAGE_TYPE_PRIMARY] =
1238 g_param_spec_enum ("primary-icon-storage-type",
1239 P_("Primary storage type")g_dgettext("ctk30" "-properties","Primary storage type"),
1240 P_("The representation being used for primary icon")g_dgettext("ctk30" "-properties","The representation being used for primary icon"
)
,
1241 CTK_TYPE_IMAGE_TYPE(ctk_image_type_get_type ()),
1242 CTK_IMAGE_EMPTY,
1243 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB);
1244
1245 /**
1246 * CtkEntry:secondary-icon-storage-type:
1247 *
1248 * The representation which is used for the secondary icon of the entry.
1249 *
1250 * Since: 2.16
1251 */
1252 entry_props[PROP_STORAGE_TYPE_SECONDARY] =
1253 g_param_spec_enum ("secondary-icon-storage-type",
1254 P_("Secondary storage type")g_dgettext("ctk30" "-properties","Secondary storage type"),
1255 P_("The representation being used for secondary icon")g_dgettext("ctk30" "-properties","The representation being used for secondary icon"
)
,
1256 CTK_TYPE_IMAGE_TYPE(ctk_image_type_get_type ()),
1257 CTK_IMAGE_EMPTY,
1258 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB);
1259
1260 /**
1261 * CtkEntry:primary-icon-activatable:
1262 *
1263 * Whether the primary icon is activatable.
1264 *
1265 * CTK+ emits the #CtkEntry::icon-press and #CtkEntry::icon-release
1266 * signals only on sensitive, activatable icons.
1267 *
1268 * Sensitive, but non-activatable icons can be used for purely
1269 * informational purposes.
1270 *
1271 * Since: 2.16
1272 */
1273 entry_props[PROP_ACTIVATABLE_PRIMARY] =
1274 g_param_spec_boolean ("primary-icon-activatable",
1275 P_("Primary icon activatable")g_dgettext("ctk30" "-properties","Primary icon activatable"),
1276 P_("Whether the primary icon is activatable")g_dgettext("ctk30" "-properties","Whether the primary icon is activatable"
)
,
1277 TRUE(!(0)),
1278 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1279
1280 /**
1281 * CtkEntry:secondary-icon-activatable:
1282 *
1283 * Whether the secondary icon is activatable.
1284 *
1285 * CTK+ emits the #CtkEntry::icon-press and #CtkEntry::icon-release
1286 * signals only on sensitive, activatable icons.
1287 *
1288 * Sensitive, but non-activatable icons can be used for purely
1289 * informational purposes.
1290 *
1291 * Since: 2.16
1292 */
1293 entry_props[PROP_ACTIVATABLE_SECONDARY] =
1294 g_param_spec_boolean ("secondary-icon-activatable",
1295 P_("Secondary icon activatable")g_dgettext("ctk30" "-properties","Secondary icon activatable"
)
,
1296 P_("Whether the secondary icon is activatable")g_dgettext("ctk30" "-properties","Whether the secondary icon is activatable"
)
,
1297 TRUE(!(0)),
1298 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1299
1300 /**
1301 * CtkEntry:primary-icon-sensitive:
1302 *
1303 * Whether the primary icon is sensitive.
1304 *
1305 * An insensitive icon appears grayed out. CTK+ does not emit the
1306 * #CtkEntry::icon-press and #CtkEntry::icon-release signals and
1307 * does not allow DND from insensitive icons.
1308 *
1309 * An icon should be set insensitive if the action that would trigger
1310 * when clicked is currently not available.
1311 *
1312 * Since: 2.16
1313 */
1314 entry_props[PROP_SENSITIVE_PRIMARY] =
1315 g_param_spec_boolean ("primary-icon-sensitive",
1316 P_("Primary icon sensitive")g_dgettext("ctk30" "-properties","Primary icon sensitive"),
1317 P_("Whether the primary icon is sensitive")g_dgettext("ctk30" "-properties","Whether the primary icon is sensitive"
)
,
1318 TRUE(!(0)),
1319 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1320
1321 /**
1322 * CtkEntry:secondary-icon-sensitive:
1323 *
1324 * Whether the secondary icon is sensitive.
1325 *
1326 * An insensitive icon appears grayed out. CTK+ does not emit the
1327 * #CtkEntry::icon-press and #CtkEntry::icon-release signals and
1328 * does not allow DND from insensitive icons.
1329 *
1330 * An icon should be set insensitive if the action that would trigger
1331 * when clicked is currently not available.
1332 *
1333 * Since: 2.16
1334 */
1335 entry_props[PROP_SENSITIVE_SECONDARY] =
1336 g_param_spec_boolean ("secondary-icon-sensitive",
1337 P_("Secondary icon sensitive")g_dgettext("ctk30" "-properties","Secondary icon sensitive"),
1338 P_("Whether the secondary icon is sensitive")g_dgettext("ctk30" "-properties","Whether the secondary icon is sensitive"
)
,
1339 TRUE(!(0)),
1340 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1341
1342 /**
1343 * CtkEntry:primary-icon-tooltip-text:
1344 *
1345 * The contents of the tooltip on the primary icon.
1346 *
1347 * Also see ctk_entry_set_icon_tooltip_text().
1348 *
1349 * Since: 2.16
1350 */
1351 entry_props[PROP_TOOLTIP_TEXT_PRIMARY] =
1352 g_param_spec_string ("primary-icon-tooltip-text",
1353 P_("Primary icon tooltip text")g_dgettext("ctk30" "-properties","Primary icon tooltip text"),
1354 P_("The contents of the tooltip on the primary icon")g_dgettext("ctk30" "-properties","The contents of the tooltip on the primary icon"
)
,
1355 NULL((void*)0),
1356 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1357
1358 /**
1359 * CtkEntry:secondary-icon-tooltip-text:
1360 *
1361 * The contents of the tooltip on the secondary icon.
1362 *
1363 * Also see ctk_entry_set_icon_tooltip_text().
1364 *
1365 * Since: 2.16
1366 */
1367 entry_props[PROP_TOOLTIP_TEXT_SECONDARY] =
1368 g_param_spec_string ("secondary-icon-tooltip-text",
1369 P_("Secondary icon tooltip text")g_dgettext("ctk30" "-properties","Secondary icon tooltip text"
)
,
1370 P_("The contents of the tooltip on the secondary icon")g_dgettext("ctk30" "-properties","The contents of the tooltip on the secondary icon"
)
,
1371 NULL((void*)0),
1372 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1373
1374 /**
1375 * CtkEntry:primary-icon-tooltip-markup:
1376 *
1377 * The contents of the tooltip on the primary icon, which is marked up
1378 * with the [Pango text markup language][PangoMarkupFormat].
1379 *
1380 * Also see ctk_entry_set_icon_tooltip_markup().
1381 *
1382 * Since: 2.16
1383 */
1384 entry_props[PROP_TOOLTIP_MARKUP_PRIMARY] =
1385 g_param_spec_string ("primary-icon-tooltip-markup",
1386 P_("Primary icon tooltip markup")g_dgettext("ctk30" "-properties","Primary icon tooltip markup"
)
,
1387 P_("The contents of the tooltip on the primary icon")g_dgettext("ctk30" "-properties","The contents of the tooltip on the primary icon"
)
,
1388 NULL((void*)0),
1389 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1390
1391 /**
1392 * CtkEntry:secondary-icon-tooltip-markup:
1393 *
1394 * The contents of the tooltip on the secondary icon, which is marked up
1395 * with the [Pango text markup language][PangoMarkupFormat].
1396 *
1397 * Also see ctk_entry_set_icon_tooltip_markup().
1398 *
1399 * Since: 2.16
1400 */
1401 entry_props[PROP_TOOLTIP_MARKUP_SECONDARY] =
1402 g_param_spec_string ("secondary-icon-tooltip-markup",
1403 P_("Secondary icon tooltip markup")g_dgettext("ctk30" "-properties","Secondary icon tooltip markup"
)
,
1404 P_("The contents of the tooltip on the secondary icon")g_dgettext("ctk30" "-properties","The contents of the tooltip on the secondary icon"
)
,
1405 NULL((void*)0),
1406 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1407
1408 /**
1409 * CtkEntry:im-module:
1410 *
1411 * Which IM (input method) module should be used for this entry.
1412 * See #CtkIMContext.
1413 *
1414 * Setting this to a non-%NULL value overrides the
1415 * system-wide IM module setting. See the CtkSettings
1416 * #CtkSettings:ctk-im-module property.
1417 *
1418 * Since: 2.16
1419 */
1420 entry_props[PROP_IM_MODULE] =
1421 g_param_spec_string ("im-module",
1422 P_("IM module")g_dgettext("ctk30" "-properties","IM module"),
1423 P_("Which IM module should be used")g_dgettext("ctk30" "-properties","Which IM module should be used"
)
,
1424 NULL((void*)0),
1425 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1426
1427 /**
1428 * CtkEntry:completion:
1429 *
1430 * The auxiliary completion object to use with the entry.
1431 *
1432 * Since: 3.2
1433 */
1434 entry_props[PROP_COMPLETION] =
1435 g_param_spec_object ("completion",
1436 P_("Completion")g_dgettext("ctk30" "-properties","Completion"),
1437 P_("The auxiliary completion object")g_dgettext("ctk30" "-properties","The auxiliary completion object"
)
,
1438 CTK_TYPE_ENTRY_COMPLETION(ctk_entry_completion_get_type ()),
1439 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1440
1441 /**
1442 * CtkEntry:input-purpose:
1443 *
1444 * The purpose of this text field.
1445 *
1446 * This property can be used by on-screen keyboards and other input
1447 * methods to adjust their behaviour.
1448 *
1449 * Note that setting the purpose to %CTK_INPUT_PURPOSE_PASSWORD or
1450 * %CTK_INPUT_PURPOSE_PIN is independent from setting
1451 * #CtkEntry:visibility.
1452 *
1453 * Since: 3.6
1454 */
1455 entry_props[PROP_INPUT_PURPOSE] =
1456 g_param_spec_enum ("input-purpose",
1457 P_("Purpose")g_dgettext("ctk30" "-properties","Purpose"),
1458 P_("Purpose of the text field")g_dgettext("ctk30" "-properties","Purpose of the text field"),
1459 CTK_TYPE_INPUT_PURPOSE(ctk_input_purpose_get_type ()),
1460 CTK_INPUT_PURPOSE_FREE_FORM,
1461 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1462
1463 /**
1464 * CtkEntry:input-hints:
1465 *
1466 * Additional hints (beyond #CtkEntry:input-purpose) that
1467 * allow input methods to fine-tune their behaviour.
1468 *
1469 * Since: 3.6
1470 */
1471 entry_props[PROP_INPUT_HINTS] =
1472 g_param_spec_flags ("input-hints",
1473 P_("hints")g_dgettext("ctk30" "-properties","hints"),
1474 P_("Hints for the text field behaviour")g_dgettext("ctk30" "-properties","Hints for the text field behaviour"
)
,
1475 CTK_TYPE_INPUT_HINTS(ctk_input_hints_get_type ()),
1476 CTK_INPUT_HINT_NONE,
1477 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1478
1479 /**
1480 * CtkEntry:attributes:
1481 *
1482 * A list of Pango attributes to apply to the text of the entry.
1483 *
1484 * This is mainly useful to change the size or weight of the text.
1485 *
1486 * The #PangoAttribute's @start_index and @end_index must refer to the
1487 * #CtkEntryBuffer text, i.e. without the preedit string.
1488 *
1489 * Since: 3.6
1490 */
1491 entry_props[PROP_ATTRIBUTES] =
1492 g_param_spec_boxed ("attributes",
1493 P_("Attributes")g_dgettext("ctk30" "-properties","Attributes"),
1494 P_("A list of style attributes to apply to the text of the label")g_dgettext("ctk30" "-properties","A list of style attributes to apply to the text of the label"
)
,
1495 PANGO_TYPE_ATTR_LISTpango_attr_list_get_type (),
1496 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1497
1498 /**
1499 * CtkEntry:populate-all:
1500 *
1501 * If :populate-all is %TRUE, the #CtkEntry::populate-popup
1502 * signal is also emitted for touch popups.
1503 *
1504 * Since: 3.8
1505 */
1506 entry_props[PROP_POPULATE_ALL] =
1507 g_param_spec_boolean ("populate-all",
1508 P_("Populate all")g_dgettext("ctk30" "-properties","Populate all"),
1509 P_("Whether to emit ::populate-popup for touch popups")g_dgettext("ctk30" "-properties","Whether to emit ::populate-popup for touch popups"
)
,
1510 FALSE(0),
1511 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1512
1513 /**
1514 * CtkEntry::tabs:
1515 *
1516 * A list of tabstops to apply to the text of the entry.
1517 *
1518 * Since: 3.8
1519 */
1520 entry_props[PROP_TABS] =
1521 g_param_spec_boxed ("tabs",
1522 P_("Tabs")g_dgettext("ctk30" "-properties","Tabs"),
1523 P_("A list of tabstop locations to apply to the text of the entry")g_dgettext("ctk30" "-properties","A list of tabstop locations to apply to the text of the entry"
)
,
1524 PANGO_TYPE_TAB_ARRAY(pango_tab_array_get_type ()),
1525 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1526
1527 /**
1528 * CtkEntry::show-emoji-icon:
1529 *
1530 * When this is %TRUE, the entry will show an emoji icon in the secondary
1531 * icon position that brings up the Emoji chooser when clicked.
1532 *
1533 * Since: 3.22.19
1534 */
1535 entry_props[PROP_SHOW_EMOJI_ICON] =
1536 g_param_spec_boolean ("show-emoji-icon",
1537 P_("Emoji icon")g_dgettext("ctk30" "-properties","Emoji icon"),
1538 P_("Whether to show an icon for Emoji")g_dgettext("ctk30" "-properties","Whether to show an icon for Emoji"
)
,
1539 FALSE(0),
1540 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1541
1542 entry_props[PROP_ENABLE_EMOJI_COMPLETION] =
1543 g_param_spec_boolean ("enable-emoji-completion",
1544 P_("Enable Emoji completion")g_dgettext("ctk30" "-properties","Enable Emoji completion"),
1545 P_("Whether to suggest Emoji replacements")g_dgettext("ctk30" "-properties","Whether to suggest Emoji replacements"
)
,
1546 FALSE(0),
1547 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1548
1549 g_object_class_install_properties (gobject_class, NUM_PROPERTIES, entry_props);
1550
1551 /**
1552 * CtkEntry:icon-prelight:
1553 *
1554 * The prelight style property determines whether activatable
1555 * icons prelight on mouseover.
1556 *
1557 * Since: 2.16
1558 *
1559 * Deprecated: 3.20: Use CSS to control the appearance of prelighted icons;
1560 * the value of this style property is ignored.
1561 */
1562 ctk_widget_class_install_style_property (widget_class,
1563 g_param_spec_boolean ("icon-prelight",
1564 P_("Icon Prelight")g_dgettext("ctk30" "-properties","Icon Prelight"),
1565 P_("Whether activatable icons should prelight when hovered")g_dgettext("ctk30" "-properties","Whether activatable icons should prelight when hovered"
)
,
1566 TRUE(!(0)),
1567 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_DEPRECATED));
1568
1569 /**
1570 * CtkEntry:progress-border:
1571 *
1572 * The border around the progress bar in the entry.
1573 *
1574 * Since: 2.16
1575 *
1576 * Deprecated: 3.4: Use the standard margin CSS property (through objects
1577 * like #CtkStyleContext and #CtkCssProvider); the value of this style
1578 * property is ignored.
1579 */
1580 ctk_widget_class_install_style_property (widget_class,
1581 g_param_spec_boxed ("progress-border",
1582 P_("Progress Border")g_dgettext("ctk30" "-properties","Progress Border"),
1583 P_("Border around the progress bar")g_dgettext("ctk30" "-properties","Border around the progress bar"
)
,
1584 CTK_TYPE_BORDER(ctk_border_get_type ()),
1585 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_DEPRECATED));
1586
1587 /**
1588 * CtkEntry:invisible-char:
1589 *
1590 * The invisible character is used when masking entry contents (in
1591 * \"password mode\")"). When it is not explicitly set with the
1592 * #CtkEntry:invisible-char property, CTK+ determines the character
1593 * to use from a list of possible candidates, depending on availability
1594 * in the current font.
1595 *
1596 * This style property allows the theme to prepend a character
1597 * to the list of candidates.
1598 *
1599 * Since: 2.18
1600 */
1601 ctk_widget_class_install_style_property (widget_class,
1602 g_param_spec_unichar ("invisible-char",
1603 P_("Invisible character")g_dgettext("ctk30" "-properties","Invisible character"),
1604 P_("The character to use when masking entry contents (in \"password mode\")")g_dgettext("ctk30" "-properties","The character to use when masking entry contents (in \"password mode\")"
)
,
1605 0,
1606 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
1607
1608 /**
1609 * CtkEntry::populate-popup:
1610 * @entry: The entry on which the signal is emitted
1611 * @widget: the container that is being populated
1612 *
1613 * The ::populate-popup signal gets emitted before showing the
1614 * context menu of the entry.
1615 *
1616 * If you need to add items to the context menu, connect
1617 * to this signal and append your items to the @widget, which
1618 * will be a #CtkMenu in this case.
1619 *
1620 * If #CtkEntry:populate-all is %TRUE, this signal will
1621 * also be emitted to populate touch popups. In this case,
1622 * @widget will be a different container, e.g. a #CtkToolbar.
1623 * The signal handler should not make assumptions about the
1624 * type of @widget.
1625 */
1626 signals[POPULATE_POPUP] =
1627 g_signal_new (I_("populate-popup")g_intern_static_string ("populate-popup"),
1628 G_OBJECT_CLASS_TYPE (gobject_class)((((GTypeClass*) (gobject_class))->g_type)),
1629 G_SIGNAL_RUN_LAST,
1630 G_STRUCT_OFFSET (CtkEntryClass, populate_popup)((glong) __builtin_offsetof(CtkEntryClass, populate_popup)),
1631 NULL((void*)0), NULL((void*)0),
1632 NULL((void*)0),
1633 G_TYPE_NONE((GType) ((1) << (2))), 1,
1634 CTK_TYPE_WIDGET(ctk_widget_get_type ()));
1635
1636 /* Action signals */
1637
1638 /**
1639 * CtkEntry::activate:
1640 * @entry: The entry on which the signal is emitted
1641 *
1642 * The ::activate signal is emitted when the user hits
1643 * the Enter key.
1644 *
1645 * While this signal is used as a
1646 * [keybinding signal][CtkBindingSignal],
1647 * it is also commonly used by applications to intercept
1648 * activation of entries.
1649 *
1650 * The default bindings for this signal are all forms of the Enter key.
1651 */
1652 signals[ACTIVATE] =
1653 g_signal_new (I_("activate")g_intern_static_string ("activate"),
1654 G_OBJECT_CLASS_TYPE (gobject_class)((((GTypeClass*) (gobject_class))->g_type)),
1655 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1656 G_STRUCT_OFFSET (CtkEntryClass, activate)((glong) __builtin_offsetof(CtkEntryClass, activate)),
1657 NULL((void*)0), NULL((void*)0),
1658 NULL((void*)0),
1659 G_TYPE_NONE((GType) ((1) << (2))), 0);
1660 widget_class->activate_signal = signals[ACTIVATE];
1661
1662 /**
1663 * CtkEntry::move-cursor:
1664 * @entry: the object which received the signal
1665 * @step: the granularity of the move, as a #CtkMovementStep
1666 * @count: the number of @step units to move
1667 * @extend_selection: %TRUE if the move should extend the selection
1668 *
1669 * The ::move-cursor signal is a
1670 * [keybinding signal][CtkBindingSignal]
1671 * which gets emitted when the user initiates a cursor movement.
1672 * If the cursor is not visible in @entry, this signal causes
1673 * the viewport to be moved instead.
1674 *
1675 * Applications should not connect to it, but may emit it with
1676 * g_signal_emit_by_name() if they need to control the cursor
1677 * programmatically.
1678 *
1679 * The default bindings for this signal come in two variants,
1680 * the variant with the Shift modifier extends the selection,
1681 * the variant without the Shift modifer does not.
1682 * There are too many key combinations to list them all here.
1683 * - Arrow keys move by individual characters/lines
1684 * - Ctrl-arrow key combinations move by words/paragraphs
1685 * - Home/End keys move to the ends of the buffer
1686 */
1687 signals[MOVE_CURSOR] =
1688 g_signal_new (I_("move-cursor")g_intern_static_string ("move-cursor"),
1689 G_OBJECT_CLASS_TYPE (gobject_class)((((GTypeClass*) (gobject_class))->g_type)),
1690 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1691 G_STRUCT_OFFSET (CtkEntryClass, move_cursor)((glong) __builtin_offsetof(CtkEntryClass, move_cursor)),
1692 NULL((void*)0), NULL((void*)0),
1693 _ctk_marshal_VOID__ENUM_INT_BOOLEAN,
1694 G_TYPE_NONE((GType) ((1) << (2))), 3,
1695 CTK_TYPE_MOVEMENT_STEP(ctk_movement_step_get_type ()),
1696 G_TYPE_INT((GType) ((6) << (2))),
1697 G_TYPE_BOOLEAN((GType) ((5) << (2))));
1698
1699 /**
1700 * CtkEntry::insert-at-cursor:
1701 * @entry: the object which received the signal
1702 * @string: the string to insert
1703 *
1704 * The ::insert-at-cursor signal is a
1705 * [keybinding signal][CtkBindingSignal]
1706 * which gets emitted when the user initiates the insertion of a
1707 * fixed string at the cursor.
1708 *
1709 * This signal has no default bindings.
1710 */
1711 signals[INSERT_AT_CURSOR] =
1712 g_signal_new (I_("insert-at-cursor")g_intern_static_string ("insert-at-cursor"),
1713 G_OBJECT_CLASS_TYPE (gobject_class)((((GTypeClass*) (gobject_class))->g_type)),
1714 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1715 G_STRUCT_OFFSET (CtkEntryClass, insert_at_cursor)((glong) __builtin_offsetof(CtkEntryClass, insert_at_cursor)),
1716 NULL((void*)0), NULL((void*)0),
1717 NULL((void*)0),
1718 G_TYPE_NONE((GType) ((1) << (2))), 1,
1719 G_TYPE_STRING((GType) ((16) << (2))));
1720
1721 /**
1722 * CtkEntry::delete-from-cursor:
1723 * @entry: the object which received the signal
1724 * @type: the granularity of the deletion, as a #CtkDeleteType
1725 * @count: the number of @type units to delete
1726 *
1727 * The ::delete-from-cursor signal is a
1728 * [keybinding signal][CtkBindingSignal]
1729 * which gets emitted when the user initiates a text deletion.
1730 *
1731 * If the @type is %CTK_DELETE_CHARS, CTK+ deletes the selection
1732 * if there is one, otherwise it deletes the requested number
1733 * of characters.
1734 *
1735 * The default bindings for this signal are
1736 * Delete for deleting a character and Ctrl-Delete for
1737 * deleting a word.
1738 */
1739 signals[DELETE_FROM_CURSOR] =
1740 g_signal_new (I_("delete-from-cursor")g_intern_static_string ("delete-from-cursor"),
1741 G_OBJECT_CLASS_TYPE (gobject_class)((((GTypeClass*) (gobject_class))->g_type)),
1742 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1743 G_STRUCT_OFFSET (CtkEntryClass, delete_from_cursor)((glong) __builtin_offsetof(CtkEntryClass, delete_from_cursor
))
,
1744 NULL((void*)0), NULL((void*)0),
1745 _ctk_marshal_VOID__ENUM_INT,
1746 G_TYPE_NONE((GType) ((1) << (2))), 2,
1747 CTK_TYPE_DELETE_TYPE(ctk_delete_type_get_type ()),
1748 G_TYPE_INT((GType) ((6) << (2))));
1749
1750 /**
1751 * CtkEntry::backspace:
1752 * @entry: the object which received the signal
1753 *
1754 * The ::backspace signal is a
1755 * [keybinding signal][CtkBindingSignal]
1756 * which gets emitted when the user asks for it.
1757 *
1758 * The default bindings for this signal are
1759 * Backspace and Shift-Backspace.
1760 */
1761 signals[BACKSPACE] =
1762 g_signal_new (I_("backspace")g_intern_static_string ("backspace"),
1763 G_OBJECT_CLASS_TYPE (gobject_class)((((GTypeClass*) (gobject_class))->g_type)),
1764 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1765 G_STRUCT_OFFSET (CtkEntryClass, backspace)((glong) __builtin_offsetof(CtkEntryClass, backspace)),
1766 NULL((void*)0), NULL((void*)0),
1767 NULL((void*)0),
1768 G_TYPE_NONE((GType) ((1) << (2))), 0);
1769
1770 /**
1771 * CtkEntry::cut-clipboard:
1772 * @entry: the object which received the signal
1773 *
1774 * The ::cut-clipboard signal is a
1775 * [keybinding signal][CtkBindingSignal]
1776 * which gets emitted to cut the selection to the clipboard.
1777 *
1778 * The default bindings for this signal are
1779 * Ctrl-x and Shift-Delete.
1780 */
1781 signals[CUT_CLIPBOARD] =
1782 g_signal_new (I_("cut-clipboard")g_intern_static_string ("cut-clipboard"),
1783 G_OBJECT_CLASS_TYPE (gobject_class)((((GTypeClass*) (gobject_class))->g_type)),
1784 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1785 G_STRUCT_OFFSET (CtkEntryClass, cut_clipboard)((glong) __builtin_offsetof(CtkEntryClass, cut_clipboard)),
1786 NULL((void*)0), NULL((void*)0),
1787 NULL((void*)0),
1788 G_TYPE_NONE((GType) ((1) << (2))), 0);
1789
1790 /**
1791 * CtkEntry::copy-clipboard:
1792 * @entry: the object which received the signal
1793 *
1794 * The ::copy-clipboard signal is a
1795 * [keybinding signal][CtkBindingSignal]
1796 * which gets emitted to copy the selection to the clipboard.
1797 *
1798 * The default bindings for this signal are
1799 * Ctrl-c and Ctrl-Insert.
1800 */
1801 signals[COPY_CLIPBOARD] =
1802 g_signal_new (I_("copy-clipboard")g_intern_static_string ("copy-clipboard"),
1803 G_OBJECT_CLASS_TYPE (gobject_class)((((GTypeClass*) (gobject_class))->g_type)),
1804 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1805 G_STRUCT_OFFSET (CtkEntryClass, copy_clipboard)((glong) __builtin_offsetof(CtkEntryClass, copy_clipboard)),
1806 NULL((void*)0), NULL((void*)0),
1807 NULL((void*)0),
1808 G_TYPE_NONE((GType) ((1) << (2))), 0);
1809
1810 /**
1811 * CtkEntry::paste-clipboard:
1812 * @entry: the object which received the signal
1813 *
1814 * The ::paste-clipboard signal is a
1815 * [keybinding signal][CtkBindingSignal]
1816 * which gets emitted to paste the contents of the clipboard
1817 * into the text view.
1818 *
1819 * The default bindings for this signal are
1820 * Ctrl-v and Shift-Insert.
1821 */
1822 signals[PASTE_CLIPBOARD] =
1823 g_signal_new (I_("paste-clipboard")g_intern_static_string ("paste-clipboard"),
1824 G_OBJECT_CLASS_TYPE (gobject_class)((((GTypeClass*) (gobject_class))->g_type)),
1825 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1826 G_STRUCT_OFFSET (CtkEntryClass, paste_clipboard)((glong) __builtin_offsetof(CtkEntryClass, paste_clipboard)),
1827 NULL((void*)0), NULL((void*)0),
1828 NULL((void*)0),
1829 G_TYPE_NONE((GType) ((1) << (2))), 0);
1830
1831 /**
1832 * CtkEntry::toggle-overwrite:
1833 * @entry: the object which received the signal
1834 *
1835 * The ::toggle-overwrite signal is a
1836 * [keybinding signal][CtkBindingSignal]
1837 * which gets emitted to toggle the overwrite mode of the entry.
1838 *
1839 * The default bindings for this signal is Insert.
1840 */
1841 signals[TOGGLE_OVERWRITE] =
1842 g_signal_new (I_("toggle-overwrite")g_intern_static_string ("toggle-overwrite"),
1843 G_OBJECT_CLASS_TYPE (gobject_class)((((GTypeClass*) (gobject_class))->g_type)),
1844 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1845 G_STRUCT_OFFSET (CtkEntryClass, toggle_overwrite)((glong) __builtin_offsetof(CtkEntryClass, toggle_overwrite)),
1846 NULL((void*)0), NULL((void*)0),
1847 NULL((void*)0),
1848 G_TYPE_NONE((GType) ((1) << (2))), 0);
1849
1850 /**
1851 * CtkEntry::icon-press:
1852 * @entry: The entry on which the signal is emitted
1853 * @icon_pos: The position of the clicked icon
1854 * @event: the button press event
1855 *
1856 * The ::icon-press signal is emitted when an activatable icon
1857 * is clicked.
1858 *
1859 * Since: 2.16
1860 */
1861 signals[ICON_PRESS] =
1862 g_signal_new (I_("icon-press")g_intern_static_string ("icon-press"),
1863 G_TYPE_FROM_CLASS (gobject_class)(((GTypeClass*) (gobject_class))->g_type),
1864 G_SIGNAL_RUN_LAST,
1865 0,
1866 NULL((void*)0), NULL((void*)0),
1867 _ctk_marshal_VOID__ENUM_BOXED,
1868 G_TYPE_NONE((GType) ((1) << (2))), 2,
1869 CTK_TYPE_ENTRY_ICON_POSITION(ctk_entry_icon_position_get_type ()),
1870 CDK_TYPE_EVENT(cdk_event_get_type ()) | G_SIGNAL_TYPE_STATIC_SCOPE(((GType) (1 << 0))));
1871
1872 /**
1873 * CtkEntry::icon-release:
1874 * @entry: The entry on which the signal is emitted
1875 * @icon_pos: The position of the clicked icon
1876 * @event: the button release event
1877 *
1878 * The ::icon-release signal is emitted on the button release from a
1879 * mouse click over an activatable icon.
1880 *
1881 * Since: 2.16
1882 */
1883 signals[ICON_RELEASE] =
1884 g_signal_new (I_("icon-release")g_intern_static_string ("icon-release"),
1885 G_TYPE_FROM_CLASS (gobject_class)(((GTypeClass*) (gobject_class))->g_type),
1886 G_SIGNAL_RUN_LAST,
1887 0,
1888 NULL((void*)0), NULL((void*)0),
1889 _ctk_marshal_VOID__ENUM_BOXED,
1890 G_TYPE_NONE((GType) ((1) << (2))), 2,
1891 CTK_TYPE_ENTRY_ICON_POSITION(ctk_entry_icon_position_get_type ()),
1892 CDK_TYPE_EVENT(cdk_event_get_type ()) | G_SIGNAL_TYPE_STATIC_SCOPE(((GType) (1 << 0))));
1893
1894 /**
1895 * CtkEntry::preedit-changed:
1896 * @entry: the object which received the signal
1897 * @preedit: the current preedit string
1898 *
1899 * If an input method is used, the typed text will not immediately
1900 * be committed to the buffer. So if you are interested in the text,
1901 * connect to this signal.
1902 *
1903 * Since: 2.20
1904 */
1905 signals[PREEDIT_CHANGED] =
1906 g_signal_new_class_handler (I_("preedit-changed")g_intern_static_string ("preedit-changed"),
1907 G_OBJECT_CLASS_TYPE (gobject_class)((((GTypeClass*) (gobject_class))->g_type)),
1908 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1909 NULL((void*)0),
1910 NULL((void*)0), NULL((void*)0),
1911 NULL((void*)0),
1912 G_TYPE_NONE((GType) ((1) << (2))), 1,
1913 G_TYPE_STRING((GType) ((16) << (2))));
1914
1915
1916 /**
1917 * CtkEntry::insert-emoji:
1918 * @entry: the object which received the signal
1919 *
1920 * The ::insert-emoji signal is a
1921 * [keybinding signal][CtkBindingSignal]
1922 * which gets emitted to present the Emoji chooser for the @entry.
1923 *
1924 * The default bindings for this signal are Ctrl-. and Ctrl-;
1925 *
1926 * Since: 3.22.27
1927 */
1928 signals[INSERT_EMOJI] =
1929 g_signal_new (I_("insert-emoji")g_intern_static_string ("insert-emoji"),
1930 G_OBJECT_CLASS_TYPE (gobject_class)((((GTypeClass*) (gobject_class))->g_type)),
1931 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1932 G_STRUCT_OFFSET (CtkEntryClass, insert_emoji)((glong) __builtin_offsetof(CtkEntryClass, insert_emoji)),
1933 NULL((void*)0), NULL((void*)0),
1934 NULL((void*)0),
1935 G_TYPE_NONE((GType) ((1) << (2))), 0);
1936
1937 /*
1938 * Key bindings
1939 */
1940
1941 binding_set = ctk_binding_set_by_class (class);
1942
1943 /* Moving the insertion point */
1944 add_move_binding (binding_set, CDK_KEY_Right0xff53, 0,
1945 CTK_MOVEMENT_VISUAL_POSITIONS, 1);
1946
1947 add_move_binding (binding_set, CDK_KEY_Left0xff51, 0,
1948 CTK_MOVEMENT_VISUAL_POSITIONS, -1);
1949
1950 add_move_binding (binding_set, CDK_KEY_KP_Right0xff98, 0,
1951 CTK_MOVEMENT_VISUAL_POSITIONS, 1);
1952
1953 add_move_binding (binding_set, CDK_KEY_KP_Left0xff96, 0,
1954 CTK_MOVEMENT_VISUAL_POSITIONS, -1);
1955
1956 add_move_binding (binding_set, CDK_KEY_Right0xff53, CDK_CONTROL_MASK,
1957 CTK_MOVEMENT_WORDS, 1);
1958
1959 add_move_binding (binding_set, CDK_KEY_Left0xff51, CDK_CONTROL_MASK,
1960 CTK_MOVEMENT_WORDS, -1);
1961
1962 add_move_binding (binding_set, CDK_KEY_KP_Right0xff98, CDK_CONTROL_MASK,
1963 CTK_MOVEMENT_WORDS, 1);
1964
1965 add_move_binding (binding_set, CDK_KEY_KP_Left0xff96, CDK_CONTROL_MASK,
1966 CTK_MOVEMENT_WORDS, -1);
1967
1968 add_move_binding (binding_set, CDK_KEY_Home0xff50, 0,
1969 CTK_MOVEMENT_DISPLAY_LINE_ENDS, -1);
1970
1971 add_move_binding (binding_set, CDK_KEY_End0xff57, 0,
1972 CTK_MOVEMENT_DISPLAY_LINE_ENDS, 1);
1973
1974 add_move_binding (binding_set, CDK_KEY_KP_Home0xff95, 0,
1975 CTK_MOVEMENT_DISPLAY_LINE_ENDS, -1);
1976
1977 add_move_binding (binding_set, CDK_KEY_KP_End0xff9c, 0,
1978 CTK_MOVEMENT_DISPLAY_LINE_ENDS, 1);
1979
1980 add_move_binding (binding_set, CDK_KEY_Home0xff50, CDK_CONTROL_MASK,
1981 CTK_MOVEMENT_BUFFER_ENDS, -1);
1982
1983 add_move_binding (binding_set, CDK_KEY_End0xff57, CDK_CONTROL_MASK,
1984 CTK_MOVEMENT_BUFFER_ENDS, 1);
1985
1986 add_move_binding (binding_set, CDK_KEY_KP_Home0xff95, CDK_CONTROL_MASK,
1987 CTK_MOVEMENT_BUFFER_ENDS, -1);
1988
1989 add_move_binding (binding_set, CDK_KEY_KP_End0xff9c, CDK_CONTROL_MASK,
1990 CTK_MOVEMENT_BUFFER_ENDS, 1);
1991
1992 /* Select all
1993 */
1994 ctk_binding_entry_add_signal (binding_set, CDK_KEY_a0x061, CDK_CONTROL_MASK,
1995 "move-cursor", 3,
1996 CTK_TYPE_MOVEMENT_STEP(ctk_movement_step_get_type ()), CTK_MOVEMENT_BUFFER_ENDS,
1997 G_TYPE_INT((GType) ((6) << (2))), -1,
1998 G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0));
1999 ctk_binding_entry_add_signal (binding_set, CDK_KEY_a0x061, CDK_CONTROL_MASK,
2000 "move-cursor", 3,
2001 CTK_TYPE_MOVEMENT_STEP(ctk_movement_step_get_type ()), CTK_MOVEMENT_BUFFER_ENDS,
2002 G_TYPE_INT((GType) ((6) << (2))), 1,
2003 G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)));
2004
2005 ctk_binding_entry_add_signal (binding_set, CDK_KEY_slash0x02f, CDK_CONTROL_MASK,
2006 "move-cursor", 3,
2007 CTK_TYPE_MOVEMENT_STEP(ctk_movement_step_get_type ()), CTK_MOVEMENT_BUFFER_ENDS,
2008 G_TYPE_INT((GType) ((6) << (2))), -1,
2009 G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0));
2010 ctk_binding_entry_add_signal (binding_set, CDK_KEY_slash0x02f, CDK_CONTROL_MASK,
2011 "move-cursor", 3,
2012 CTK_TYPE_MOVEMENT_STEP(ctk_movement_step_get_type ()), CTK_MOVEMENT_BUFFER_ENDS,
2013 G_TYPE_INT((GType) ((6) << (2))), 1,
2014 G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)));
2015 /* Unselect all
2016 */
2017 ctk_binding_entry_add_signal (binding_set, CDK_KEY_backslash0x05c, CDK_CONTROL_MASK,
2018 "move-cursor", 3,
2019 CTK_TYPE_MOVEMENT_STEP(ctk_movement_step_get_type ()), CTK_MOVEMENT_VISUAL_POSITIONS,
2020 G_TYPE_INT((GType) ((6) << (2))), 0,
2021 G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0));
2022 ctk_binding_entry_add_signal (binding_set, CDK_KEY_a0x061, CDK_SHIFT_MASK | CDK_CONTROL_MASK,
2023 "move-cursor", 3,
2024 CTK_TYPE_MOVEMENT_STEP(ctk_movement_step_get_type ()), CTK_MOVEMENT_VISUAL_POSITIONS,
2025 G_TYPE_INT((GType) ((6) << (2))), 0,
2026 G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0));
2027
2028 /* Activate
2029 */
2030 ctk_binding_entry_add_signal (binding_set, CDK_KEY_Return0xff0d, 0,
2031 "activate", 0);
2032 ctk_binding_entry_add_signal (binding_set, CDK_KEY_ISO_Enter0xfe34, 0,
2033 "activate", 0);
2034 ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Enter0xff8d, 0,
2035 "activate", 0);
2036
2037 /* Deleting text */
2038 ctk_binding_entry_add_signal (binding_set, CDK_KEY_Delete0xffff, 0,
2039 "delete-from-cursor", 2,
2040 G_TYPE_ENUM((GType) ((12) << (2))), CTK_DELETE_CHARS,
2041 G_TYPE_INT((GType) ((6) << (2))), 1);
2042
2043 ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Delete0xff9f, 0,
2044 "delete-from-cursor", 2,
2045 G_TYPE_ENUM((GType) ((12) << (2))), CTK_DELETE_CHARS,
2046 G_TYPE_INT((GType) ((6) << (2))), 1);
2047
2048 ctk_binding_entry_add_signal (binding_set, CDK_KEY_BackSpace0xff08, 0,
2049 "backspace", 0);
2050
2051 ctk_binding_entry_add_signal (binding_set, CDK_KEY_u0x075, CDK_CONTROL_MASK,
2052 "delete-from-cursor", 2,
2053 G_TYPE_ENUM((GType) ((12) << (2))), CTK_DELETE_PARAGRAPH_ENDS,
2054 G_TYPE_INT((GType) ((6) << (2))), -1);
2055
2056 /* Make this do the same as Backspace, to help with mis-typing */
2057 ctk_binding_entry_add_signal (binding_set, CDK_KEY_BackSpace0xff08, CDK_SHIFT_MASK,
2058 "backspace", 0);
2059
2060 ctk_binding_entry_add_signal (binding_set, CDK_KEY_Delete0xffff, CDK_CONTROL_MASK,
2061 "delete-from-cursor", 2,
2062 G_TYPE_ENUM((GType) ((12) << (2))), CTK_DELETE_WORD_ENDS,
2063 G_TYPE_INT((GType) ((6) << (2))), 1);
2064
2065 ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Delete0xff9f, CDK_CONTROL_MASK,
2066 "delete-from-cursor", 2,
2067 G_TYPE_ENUM((GType) ((12) << (2))), CTK_DELETE_WORD_ENDS,
2068 G_TYPE_INT((GType) ((6) << (2))), 1);
2069
2070 ctk_binding_entry_add_signal (binding_set, CDK_KEY_BackSpace0xff08, CDK_CONTROL_MASK,
2071 "delete-from-cursor", 2,
2072 G_TYPE_ENUM((GType) ((12) << (2))), CTK_DELETE_WORD_ENDS,
2073 G_TYPE_INT((GType) ((6) << (2))), -1);
2074
2075 /* Cut/copy/paste */
2076
2077 ctk_binding_entry_add_signal (binding_set, CDK_KEY_x0x078, CDK_CONTROL_MASK,
2078 "cut-clipboard", 0);
2079 ctk_binding_entry_add_signal (binding_set, CDK_KEY_c0x063, CDK_CONTROL_MASK,
2080 "copy-clipboard", 0);
2081 ctk_binding_entry_add_signal (binding_set, CDK_KEY_v0x076, CDK_CONTROL_MASK,
2082 "paste-clipboard", 0);
2083
2084 ctk_binding_entry_add_signal (binding_set, CDK_KEY_Delete0xffff, CDK_SHIFT_MASK,
2085 "cut-clipboard", 0);
2086 ctk_binding_entry_add_signal (binding_set, CDK_KEY_Insert0xff63, CDK_CONTROL_MASK,
2087 "copy-clipboard", 0);
2088 ctk_binding_entry_add_signal (binding_set, CDK_KEY_Insert0xff63, CDK_SHIFT_MASK,
2089 "paste-clipboard", 0);
2090
2091 ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Delete0xff9f, CDK_SHIFT_MASK,
2092 "cut-clipboard", 0);
2093 ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Insert0xff9e, CDK_CONTROL_MASK,
2094 "copy-clipboard", 0);
2095 ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Insert0xff9e, CDK_SHIFT_MASK,
2096 "paste-clipboard", 0);
2097
2098 /* Overwrite */
2099 ctk_binding_entry_add_signal (binding_set, CDK_KEY_Insert0xff63, 0,
2100 "toggle-overwrite", 0);
2101 ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Insert0xff9e, 0,
2102 "toggle-overwrite", 0);
2103
2104 /**
2105 * CtkEntry:inner-border:
2106 *
2107 * Sets the text area's border between the text and the frame.
2108 *
2109 * Since: 2.10
2110 *
2111 * Deprecated: 3.4: Use the standard border and padding CSS properties
2112 * (through objects like #CtkStyleContext and #CtkCssProvider); the value
2113 * of this style property is ignored.
2114 */
2115 ctk_widget_class_install_style_property (widget_class,
2116 g_param_spec_boxed ("inner-border",
2117 P_("Inner Border")g_dgettext("ctk30" "-properties","Inner Border"),
2118 P_("Border between text and frame.")g_dgettext("ctk30" "-properties","Border between text and frame."
)
,
2119 CTK_TYPE_BORDER(ctk_border_get_type ()),
2120 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB |
2121 G_PARAM_DEPRECATED));
2122 /* Emoji */
2123 ctk_binding_entry_add_signal (binding_set, CDK_KEY_period0x02e, CDK_CONTROL_MASK,
2124 "insert-emoji", 0);
2125 ctk_binding_entry_add_signal (binding_set, CDK_KEY_semicolon0x03b, CDK_CONTROL_MASK,
2126 "insert-emoji", 0);
2127
2128 ctk_widget_class_set_accessible_type (widget_class, CTK_TYPE_ENTRY_ACCESSIBLE(ctk_entry_accessible_get_type ()));
2129 ctk_widget_class_set_css_name (widget_class, "entry");
2130}
2131
2132static void
2133ctk_entry_editable_init (CtkEditableInterface *iface)
2134{
2135 iface->do_insert_text = ctk_entry_insert_text;
2136 iface->do_delete_text = ctk_entry_delete_text;
2137 iface->insert_text = ctk_entry_real_insert_text;
2138 iface->delete_text = ctk_entry_real_delete_text;
2139 iface->get_chars = ctk_entry_get_chars;
2140 iface->set_selection_bounds = ctk_entry_set_selection_bounds;
2141 iface->get_selection_bounds = ctk_entry_get_selection_bounds;
2142 iface->set_position = ctk_entry_real_set_position;
2143 iface->get_position = ctk_entry_get_position;
2144}
2145
2146static void
2147ctk_entry_cell_editable_init (CtkCellEditableIface *iface)
2148{
2149 iface->start_editing = ctk_entry_start_editing;
2150}
2151
2152/* for deprecated properties */
2153static void
2154ctk_entry_do_set_inner_border (CtkEntry *entry,
2155 const CtkBorder *border)
2156{
2157 if (border)
2158 g_object_set_qdata_full (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, quark_inner_border,
2159 ctk_border_copy (border),
2160 (GDestroyNotify) ctk_border_free);
2161 else
2162 g_object_set_qdata (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, quark_inner_border, NULL((void*)0));
2163
2164 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_INNER_BORDER]);
2165}
2166
2167static const CtkBorder *
2168ctk_entry_do_get_inner_border (CtkEntry *entry)
2169{
2170 return g_object_get_qdata (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, quark_inner_border);
2171}
2172
2173static void
2174ctk_entry_set_property (GObject *object,
2175 guint prop_id,
2176 const GValue *value,
2177 GParamSpec *pspec)
2178{
2179 CtkEntry *entry = CTK_ENTRY (object)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_entry_get_type ()))))))
;
2180 CtkEntryPrivate *priv = entry->priv;
2181
2182 switch (prop_id)
2183 {
2184 case PROP_BUFFER:
2185 ctk_entry_set_buffer (entry, g_value_get_object (value));
2186 break;
2187
2188 case PROP_EDITABLE:
2189 {
2190 gboolean new_value = g_value_get_boolean (value);
2191 CtkStyleContext *context = ctk_widget_get_style_context (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
2192
2193 if (new_value != priv->editable)
2194 {
2195 CtkWidget *widget = CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
;
2196
2197 if (!new_value)
2198 {
2199 ctk_entry_reset_im_context (entry);
2200 if (ctk_widget_has_focus (widget))
2201 ctk_im_context_focus_out (priv->im_context);
2202
2203 priv->preedit_length = 0;
2204 priv->preedit_cursor = 0;
2205
2206 ctk_style_context_remove_class (context, CTK_STYLE_CLASS_READ_ONLY"read-only");
2207 }
2208 else
2209 {
2210 ctk_style_context_add_class (context, CTK_STYLE_CLASS_READ_ONLY"read-only");
2211 }
2212
2213 priv->editable = new_value;
2214
2215 if (new_value && ctk_widget_has_focus (widget))
2216 ctk_im_context_focus_in (priv->im_context);
2217
2218 g_object_notify_by_pspec (object, pspec);
2219 ctk_widget_queue_draw (widget);
2220 }
2221 }
2222 break;
2223
2224 case PROP_MAX_LENGTH:
2225 ctk_entry_set_max_length (entry, g_value_get_int (value));
2226 break;
2227
2228 case PROP_VISIBILITY:
2229 ctk_entry_set_visibility (entry, g_value_get_boolean (value));
2230 break;
2231
2232 case PROP_HAS_FRAME:
2233 ctk_entry_set_has_frame (entry, g_value_get_boolean (value));
2234 break;
2235
2236 case PROP_INNER_BORDER:
2237 ctk_entry_do_set_inner_border (entry, g_value_get_boxed (value));
2238 break;
2239
2240 case PROP_INVISIBLE_CHAR:
2241 ctk_entry_set_invisible_char (entry, g_value_get_uint (value));
2242 break;
2243
2244 case PROP_ACTIVATES_DEFAULT:
2245 ctk_entry_set_activates_default (entry, g_value_get_boolean (value));
2246 break;
2247
2248 case PROP_WIDTH_CHARS:
2249 ctk_entry_set_width_chars (entry, g_value_get_int (value));
2250 break;
2251
2252 case PROP_MAX_WIDTH_CHARS:
2253 ctk_entry_set_max_width_chars (entry, g_value_get_int (value));
2254 break;
2255
2256 case PROP_TEXT:
2257 ctk_entry_set_text (entry, g_value_get_string (value));
2258 break;
2259
2260 case PROP_XALIGN:
2261 ctk_entry_set_alignment (entry, g_value_get_float (value));
2262 break;
2263
2264 case PROP_TRUNCATE_MULTILINE:
2265 if (priv->truncate_multiline != g_value_get_boolean (value))
2266 {
2267 priv->truncate_multiline = g_value_get_boolean (value);
2268 g_object_notify_by_pspec (object, pspec);
2269 }
2270 break;
2271
2272 case PROP_SHADOW_TYPE:
2273 if (priv->shadow_type != g_value_get_enum (value))
2274 {
2275 priv->shadow_type = g_value_get_enum (value);
2276 g_object_notify_by_pspec (object, pspec);
2277 }
2278 break;
2279
2280 case PROP_OVERWRITE_MODE:
2281 ctk_entry_set_overwrite_mode (entry, g_value_get_boolean (value));
2282 break;
2283
2284 case PROP_INVISIBLE_CHAR_SET:
2285 if (g_value_get_boolean (value))
2286 priv->invisible_char_set = TRUE(!(0));
2287 else
2288 ctk_entry_unset_invisible_char (entry);
2289 break;
2290
2291 case PROP_CAPS_LOCK_WARNING:
2292 if (priv->caps_lock_warning != g_value_get_boolean (value))
2293 {
2294 priv->caps_lock_warning = g_value_get_boolean (value);
2295 g_object_notify_by_pspec (object, pspec);
2296 }
2297 break;
2298
2299 case PROP_PROGRESS_FRACTION:
2300 ctk_entry_set_progress_fraction (entry, g_value_get_double (value));
2301 break;
2302
2303 case PROP_PROGRESS_PULSE_STEP:
2304 ctk_entry_set_progress_pulse_step (entry, g_value_get_double (value));
2305 break;
2306
2307 case PROP_PLACEHOLDER_TEXT:
2308 ctk_entry_set_placeholder_text (entry, g_value_get_string (value));
2309 break;
2310
2311 case PROP_PIXBUF_PRIMARY:
2312 ctk_entry_set_icon_from_pixbuf (entry,
2313 CTK_ENTRY_ICON_PRIMARY,
2314 g_value_get_object (value));
2315 break;
2316
2317 case PROP_PIXBUF_SECONDARY:
2318 ctk_entry_set_icon_from_pixbuf (entry,
2319 CTK_ENTRY_ICON_SECONDARY,
2320 g_value_get_object (value));
2321 break;
2322
2323 case PROP_STOCK_PRIMARY:
2324 G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push clang diagnostic ignored "-Wdeprecated-declarations"
;
2325 ctk_entry_set_icon_from_stock (entry,
2326 CTK_ENTRY_ICON_PRIMARY,
2327 g_value_get_string (value));
2328 G_GNUC_END_IGNORE_DEPRECATIONSclang diagnostic pop ;
2329 break;
2330
2331 case PROP_STOCK_SECONDARY:
2332 G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push clang diagnostic ignored "-Wdeprecated-declarations"
;
2333 ctk_entry_set_icon_from_stock (entry,
2334 CTK_ENTRY_ICON_SECONDARY,
2335 g_value_get_string (value));
2336 G_GNUC_END_IGNORE_DEPRECATIONSclang diagnostic pop ;
2337 break;
2338
2339 case PROP_ICON_NAME_PRIMARY:
2340 ctk_entry_set_icon_from_icon_name (entry,
2341 CTK_ENTRY_ICON_PRIMARY,
2342 g_value_get_string (value));
2343 break;
2344
2345 case PROP_ICON_NAME_SECONDARY:
2346 ctk_entry_set_icon_from_icon_name (entry,
2347 CTK_ENTRY_ICON_SECONDARY,
2348 g_value_get_string (value));
2349 break;
2350
2351 case PROP_GICON_PRIMARY:
2352 ctk_entry_set_icon_from_gicon (entry,
2353 CTK_ENTRY_ICON_PRIMARY,
2354 g_value_get_object (value));
2355 break;
2356
2357 case PROP_GICON_SECONDARY:
2358 ctk_entry_set_icon_from_gicon (entry,
2359 CTK_ENTRY_ICON_SECONDARY,
2360 g_value_get_object (value));
2361 break;
2362
2363 case PROP_ACTIVATABLE_PRIMARY:
2364 ctk_entry_set_icon_activatable (entry,
2365 CTK_ENTRY_ICON_PRIMARY,
2366 g_value_get_boolean (value));
2367 break;
2368
2369 case PROP_ACTIVATABLE_SECONDARY:
2370 ctk_entry_set_icon_activatable (entry,
2371 CTK_ENTRY_ICON_SECONDARY,
2372 g_value_get_boolean (value));
2373 break;
2374
2375 case PROP_SENSITIVE_PRIMARY:
2376 ctk_entry_set_icon_sensitive (entry,
2377 CTK_ENTRY_ICON_PRIMARY,
2378 g_value_get_boolean (value));
2379 break;
2380
2381 case PROP_SENSITIVE_SECONDARY:
2382 ctk_entry_set_icon_sensitive (entry,
2383 CTK_ENTRY_ICON_SECONDARY,
2384 g_value_get_boolean (value));
2385 break;
2386
2387 case PROP_TOOLTIP_TEXT_PRIMARY:
2388 ctk_entry_set_icon_tooltip_text (entry,
2389 CTK_ENTRY_ICON_PRIMARY,
2390 g_value_get_string (value));
2391 break;
2392
2393 case PROP_TOOLTIP_TEXT_SECONDARY:
2394 ctk_entry_set_icon_tooltip_text (entry,
2395 CTK_ENTRY_ICON_SECONDARY,
2396 g_value_get_string (value));
2397 break;
2398
2399 case PROP_TOOLTIP_MARKUP_PRIMARY:
2400 ctk_entry_set_icon_tooltip_markup (entry,
2401 CTK_ENTRY_ICON_PRIMARY,
2402 g_value_get_string (value));
2403 break;
2404
2405 case PROP_TOOLTIP_MARKUP_SECONDARY:
2406 ctk_entry_set_icon_tooltip_markup (entry,
2407 CTK_ENTRY_ICON_SECONDARY,
2408 g_value_get_string (value));
2409 break;
2410
2411 case PROP_IM_MODULE:
2412 g_free (priv->im_module);
2413 priv->im_module = g_value_dup_string (value);
2414 if (CTK_IS_IM_MULTICONTEXT (priv->im_context)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(priv->im_context)); GType __t = ((ctk_im_multicontext_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; }))))
)
2415 ctk_im_multicontext_set_context_id (CTK_IM_MULTICONTEXT (priv->im_context)((((CtkIMMulticontext*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((priv->im_context)), ((ctk_im_multicontext_get_type
()))))))
, priv->im_module);
2416 g_object_notify_by_pspec (object, pspec);
2417 break;
2418
2419 case PROP_EDITING_CANCELED:
2420 if (priv->editing_canceled != g_value_get_boolean (value))
2421 {
2422 priv->editing_canceled = g_value_get_boolean (value);
2423 g_object_notify (object, "editing-canceled");
2424 }
2425 break;
2426
2427 case PROP_COMPLETION:
2428 ctk_entry_set_completion (entry, CTK_ENTRY_COMPLETION (g_value_get_object (value))((((CtkEntryCompletion*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((g_value_get_object (value))), ((ctk_entry_completion_get_type
()))))))
);
2429 break;
2430
2431 case PROP_INPUT_PURPOSE:
2432 ctk_entry_set_input_purpose (entry, g_value_get_enum (value));
2433 break;
2434
2435 case PROP_INPUT_HINTS:
2436 ctk_entry_set_input_hints (entry, g_value_get_flags (value));
2437 break;
2438
2439 case PROP_ATTRIBUTES:
2440 ctk_entry_set_attributes (entry, g_value_get_boxed (value));
2441 break;
2442
2443 case PROP_POPULATE_ALL:
2444 if (entry->priv->populate_all != g_value_get_boolean (value))
2445 {
2446 entry->priv->populate_all = g_value_get_boolean (value);
2447 g_object_notify_by_pspec (object, pspec);
2448 }
2449 break;
2450
2451 case PROP_TABS:
2452 ctk_entry_set_tabs (entry, g_value_get_boxed (value));
2453 break;
2454
2455 case PROP_SHOW_EMOJI_ICON:
2456 set_show_emoji_icon (entry, g_value_get_boolean (value));
2457 break;
2458
2459 case PROP_ENABLE_EMOJI_COMPLETION:
2460 set_enable_emoji_completion (entry, g_value_get_boolean (value));
2461 break;
2462
2463 case PROP_SCROLL_OFFSET:
2464 case PROP_CURSOR_POSITION:
2465 default:
2466 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "ctkentry.c", 2466, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
2467 break;
2468 }
2469}
2470
2471static void
2472ctk_entry_get_property (GObject *object,
2473 guint prop_id,
2474 GValue *value,
2475 GParamSpec *pspec)
2476{
2477 CtkEntry *entry = CTK_ENTRY (object)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_entry_get_type ()))))))
;
2478 CtkEntryPrivate *priv = entry->priv;
2479
2480 switch (prop_id)
2481 {
2482 case PROP_BUFFER:
2483 g_value_set_object (value, ctk_entry_get_buffer (entry));
2484 break;
2485
2486 case PROP_CURSOR_POSITION:
2487 g_value_set_int (value, priv->current_pos);
2488 break;
2489
2490 case PROP_SELECTION_BOUND:
2491 g_value_set_int (value, priv->selection_bound);
2492 break;
2493
2494 case PROP_EDITABLE:
2495 g_value_set_boolean (value, priv->editable);
2496 break;
2497
2498 case PROP_MAX_LENGTH:
2499 g_value_set_int (value, ctk_entry_buffer_get_max_length (get_buffer (entry)));
2500 break;
2501
2502 case PROP_VISIBILITY:
2503 g_value_set_boolean (value, priv->visible);
2504 break;
2505
2506 case PROP_HAS_FRAME:
2507 g_value_set_boolean (value, ctk_entry_get_has_frame (entry));
2508 break;
2509
2510 case PROP_INNER_BORDER:
2511 g_value_set_boxed (value, ctk_entry_do_get_inner_border (entry));
2512 break;
2513
2514 case PROP_INVISIBLE_CHAR:
2515 g_value_set_uint (value, priv->invisible_char);
2516 break;
2517
2518 case PROP_ACTIVATES_DEFAULT:
2519 g_value_set_boolean (value, priv->activates_default);
2520 break;
2521
2522 case PROP_WIDTH_CHARS:
2523 g_value_set_int (value, priv->width_chars);
2524 break;
2525
2526 case PROP_MAX_WIDTH_CHARS:
2527 g_value_set_int (value, priv->max_width_chars);
2528 break;
2529
2530 case PROP_SCROLL_OFFSET:
2531 g_value_set_int (value, priv->scroll_offset);
2532 break;
2533
2534 case PROP_TEXT:
2535 g_value_set_string (value, ctk_entry_get_text (entry));
2536 break;
2537
2538 case PROP_XALIGN:
2539 g_value_set_float (value, ctk_entry_get_alignment (entry));
2540 break;
2541
2542 case PROP_TRUNCATE_MULTILINE:
2543 g_value_set_boolean (value, priv->truncate_multiline);
2544 break;
2545
2546 case PROP_SHADOW_TYPE:
2547 g_value_set_enum (value, priv->shadow_type);
2548 break;
2549
2550 case PROP_OVERWRITE_MODE:
2551 g_value_set_boolean (value, priv->overwrite_mode);
2552 break;
2553
2554 case PROP_TEXT_LENGTH:
2555 g_value_set_uint (value, ctk_entry_buffer_get_length (get_buffer (entry)));
2556 break;
2557
2558 case PROP_INVISIBLE_CHAR_SET:
2559 g_value_set_boolean (value, priv->invisible_char_set);
2560 break;
2561
2562 case PROP_IM_MODULE:
2563 g_value_set_string (value, priv->im_module);
2564 break;
2565
2566 case PROP_CAPS_LOCK_WARNING:
2567 g_value_set_boolean (value, priv->caps_lock_warning);
2568 break;
2569
2570 case PROP_PROGRESS_FRACTION:
2571 g_value_set_double (value, priv->progress_fraction);
2572 break;
2573
2574 case PROP_PROGRESS_PULSE_STEP:
2575 g_value_set_double (value, priv->progress_pulse_fraction);
2576 break;
2577
2578 case PROP_PLACEHOLDER_TEXT:
2579 g_value_set_string (value, ctk_entry_get_placeholder_text (entry));
2580 break;
2581
2582 case PROP_PIXBUF_PRIMARY:
2583 g_value_set_object (value,
2584 ctk_entry_get_icon_pixbuf (entry,
2585 CTK_ENTRY_ICON_PRIMARY));
2586 break;
2587
2588 case PROP_PIXBUF_SECONDARY:
2589 g_value_set_object (value,
2590 ctk_entry_get_icon_pixbuf (entry,
2591 CTK_ENTRY_ICON_SECONDARY));
2592 break;
2593
2594 case PROP_STOCK_PRIMARY:
2595 G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push clang diagnostic ignored "-Wdeprecated-declarations"
;
2596 g_value_set_string (value,
2597 ctk_entry_get_icon_stock (entry,
2598 CTK_ENTRY_ICON_PRIMARY));
2599 G_GNUC_END_IGNORE_DEPRECATIONSclang diagnostic pop ;
2600 break;
2601
2602 case PROP_STOCK_SECONDARY:
2603 G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push clang diagnostic ignored "-Wdeprecated-declarations"
;
2604 g_value_set_string (value,
2605 ctk_entry_get_icon_stock (entry,
2606 CTK_ENTRY_ICON_SECONDARY));
2607 G_GNUC_END_IGNORE_DEPRECATIONSclang diagnostic pop ;
2608 break;
2609
2610 case PROP_ICON_NAME_PRIMARY:
2611 g_value_set_string (value,
2612 ctk_entry_get_icon_name (entry,
2613 CTK_ENTRY_ICON_PRIMARY));
2614 break;
2615
2616 case PROP_ICON_NAME_SECONDARY:
2617 g_value_set_string (value,
2618 ctk_entry_get_icon_name (entry,
2619 CTK_ENTRY_ICON_SECONDARY));
2620 break;
2621
2622 case PROP_GICON_PRIMARY:
2623 g_value_set_object (value,
2624 ctk_entry_get_icon_gicon (entry,
2625 CTK_ENTRY_ICON_PRIMARY));
2626 break;
2627
2628 case PROP_GICON_SECONDARY:
2629 g_value_set_object (value,
2630 ctk_entry_get_icon_gicon (entry,
2631 CTK_ENTRY_ICON_SECONDARY));
2632 break;
2633
2634 case PROP_STORAGE_TYPE_PRIMARY:
2635 g_value_set_enum (value,
2636 ctk_entry_get_icon_storage_type (entry,
2637 CTK_ENTRY_ICON_PRIMARY));
2638 break;
2639
2640 case PROP_STORAGE_TYPE_SECONDARY:
2641 g_value_set_enum (value,
2642 ctk_entry_get_icon_storage_type (entry,
2643 CTK_ENTRY_ICON_SECONDARY));
2644 break;
2645
2646 case PROP_ACTIVATABLE_PRIMARY:
2647 g_value_set_boolean (value,
2648 ctk_entry_get_icon_activatable (entry, CTK_ENTRY_ICON_PRIMARY));
2649 break;
2650
2651 case PROP_ACTIVATABLE_SECONDARY:
2652 g_value_set_boolean (value,
2653 ctk_entry_get_icon_activatable (entry, CTK_ENTRY_ICON_SECONDARY));
2654 break;
2655
2656 case PROP_SENSITIVE_PRIMARY:
2657 g_value_set_boolean (value,
2658 ctk_entry_get_icon_sensitive (entry, CTK_ENTRY_ICON_PRIMARY));
2659 break;
2660
2661 case PROP_SENSITIVE_SECONDARY:
2662 g_value_set_boolean (value,
2663 ctk_entry_get_icon_sensitive (entry, CTK_ENTRY_ICON_SECONDARY));
2664 break;
2665
2666 case PROP_TOOLTIP_TEXT_PRIMARY:
2667 g_value_take_string (value,
2668 ctk_entry_get_icon_tooltip_text (entry, CTK_ENTRY_ICON_PRIMARY));
2669 break;
2670
2671 case PROP_TOOLTIP_TEXT_SECONDARY:
2672 g_value_take_string (value,
2673 ctk_entry_get_icon_tooltip_text (entry, CTK_ENTRY_ICON_SECONDARY));
2674 break;
2675
2676 case PROP_TOOLTIP_MARKUP_PRIMARY:
2677 g_value_take_string (value,
2678 ctk_entry_get_icon_tooltip_markup (entry, CTK_ENTRY_ICON_PRIMARY));
2679 break;
2680
2681 case PROP_TOOLTIP_MARKUP_SECONDARY:
2682 g_value_take_string (value,
2683 ctk_entry_get_icon_tooltip_markup (entry, CTK_ENTRY_ICON_SECONDARY));
2684 break;
2685
2686 case PROP_EDITING_CANCELED:
2687 g_value_set_boolean (value,
2688 priv->editing_canceled);
2689 break;
2690
2691 case PROP_COMPLETION:
2692 g_value_set_object (value, G_OBJECT (ctk_entry_get_completion (entry))((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_entry_get_completion (entry))), (((GType) ((20) <<
(2))))))))
);
2693 break;
2694
2695 case PROP_INPUT_PURPOSE:
2696 g_value_set_enum (value, ctk_entry_get_input_purpose (entry));
2697 break;
2698
2699 case PROP_INPUT_HINTS:
2700 g_value_set_flags (value, ctk_entry_get_input_hints (entry));
2701 break;
2702
2703 case PROP_ATTRIBUTES:
2704 g_value_set_boxed (value, priv->attrs);
2705 break;
2706
2707 case PROP_POPULATE_ALL:
2708 g_value_set_boolean (value, priv->populate_all);
2709 break;
2710
2711 case PROP_TABS:
2712 g_value_set_boxed (value, priv->tabs);
2713 break;
2714
2715 case PROP_SHOW_EMOJI_ICON:
2716 g_value_set_boolean (value, priv->show_emoji_icon);
2717 break;
2718
2719 case PROP_ENABLE_EMOJI_COMPLETION:
2720 g_value_set_boolean (value, priv->enable_emoji_completion);
2721 break;
2722
2723 default:
2724 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "ctkentry.c", 2724, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
2725 break;
2726 }
2727}
2728
2729static gunichar
2730find_invisible_char (CtkWidget *widget)
2731{
2732 PangoLayout *layout;
2733 PangoAttrList *attr_list;
2734 gint i;
2735 gunichar invisible_chars [] = {
2736 0,
2737 0x25cf, /* BLACK CIRCLE */
2738 0x2022, /* BULLET */
2739 0x2731, /* HEAVY ASTERISK */
2740 0x273a /* SIXTEEN POINTED ASTERISK */
2741 };
2742
2743 ctk_widget_style_get (widget,
2744 "invisible-char", &invisible_chars[0],
2745 NULL((void*)0));
2746
2747 layout = ctk_widget_create_pango_layout (widget, NULL((void*)0));
2748
2749 attr_list = pango_attr_list_new ();
2750 pango_attr_list_insert (attr_list, pango_attr_fallback_new (FALSE(0)));
2751
2752 pango_layout_set_attributes (layout, attr_list);
2753 pango_attr_list_unref (attr_list);
2754
2755 for (i = (invisible_chars[0] != 0 ? 0 : 1); i < G_N_ELEMENTS (invisible_chars)(sizeof (invisible_chars) / sizeof ((invisible_chars)[0])); i++)
2756 {
2757 gchar text[7] = { 0, };
2758 gint len, count;
2759
2760 len = g_unichar_to_utf8 (invisible_chars[i], text);
2761 pango_layout_set_text (layout, text, len);
2762
2763 count = pango_layout_get_unknown_glyphs_count (layout);
2764
2765 if (count == 0)
2766 {
2767 g_object_unref (layout);
2768 return invisible_chars[i];
2769 }
2770 }
2771
2772 g_object_unref (layout);
2773
2774 return '*';
2775}
2776
2777static void
2778ctk_entry_init (CtkEntry *entry)
2779{
2780 CtkEntryPrivate *priv;
2781 CtkCssNode *widget_node;
2782 gint i;
2783
2784 entry->priv = ctk_entry_get_instance_private (entry);
2785 priv = entry->priv;
2786
2787 ctk_widget_set_can_focus (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, TRUE(!(0)));
2788 ctk_widget_set_has_window (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, FALSE(0));
2789
2790 priv->editable = TRUE(!(0));
2791 priv->visible = TRUE(!(0));
2792 priv->dnd_position = -1;
2793 priv->width_chars = -1;
2794 priv->max_width_chars = -1;
2795 priv->editing_canceled = FALSE(0);
2796 priv->truncate_multiline = FALSE(0);
2797 priv->shadow_type = CTK_SHADOW_IN;
2798 priv->xalign = 0.0;
2799 priv->caps_lock_warning = TRUE(!(0));
2800 priv->caps_lock_warning_shown = FALSE(0);
2801 priv->progress_fraction = 0.0;
2802 priv->progress_pulse_fraction = 0.1;
2803
2804 ctk_drag_dest_set (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, 0, NULL((void*)0), 0,
2805 CDK_ACTION_COPY | CDK_ACTION_MOVE);
2806 ctk_drag_dest_add_text_targets (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
2807
2808 /* This object is completely private. No external entity can gain a reference
2809 * to it; so we create it here and destroy it in finalize().
2810 */
2811 priv->im_context = ctk_im_multicontext_new ();
2812
2813 g_signal_connect (priv->im_context, "commit",g_signal_connect_data ((priv->im_context), ("commit"), (((
GCallback) (ctk_entry_commit_cb))), (entry), ((void*)0), (GConnectFlags
) 0)
2814 G_CALLBACK (ctk_entry_commit_cb), entry)g_signal_connect_data ((priv->im_context), ("commit"), (((
GCallback) (ctk_entry_commit_cb))), (entry), ((void*)0), (GConnectFlags
) 0)
;
2815 g_signal_connect (priv->im_context, "preedit-changed",g_signal_connect_data ((priv->im_context), ("preedit-changed"
), (((GCallback) (ctk_entry_preedit_changed_cb))), (entry), (
(void*)0), (GConnectFlags) 0)
2816 G_CALLBACK (ctk_entry_preedit_changed_cb), entry)g_signal_connect_data ((priv->im_context), ("preedit-changed"
), (((GCallback) (ctk_entry_preedit_changed_cb))), (entry), (
(void*)0), (GConnectFlags) 0)
;
2817 g_signal_connect (priv->im_context, "retrieve-surrounding",g_signal_connect_data ((priv->im_context), ("retrieve-surrounding"
), (((GCallback) (ctk_entry_retrieve_surrounding_cb))), (entry
), ((void*)0), (GConnectFlags) 0)
2818 G_CALLBACK (ctk_entry_retrieve_surrounding_cb), entry)g_signal_connect_data ((priv->im_context), ("retrieve-surrounding"
), (((GCallback) (ctk_entry_retrieve_surrounding_cb))), (entry
), ((void*)0), (GConnectFlags) 0)
;
2819 g_signal_connect (priv->im_context, "delete-surrounding",g_signal_connect_data ((priv->im_context), ("delete-surrounding"
), (((GCallback) (ctk_entry_delete_surrounding_cb))), (entry)
, ((void*)0), (GConnectFlags) 0)
2820 G_CALLBACK (ctk_entry_delete_surrounding_cb), entry)g_signal_connect_data ((priv->im_context), ("delete-surrounding"
), (((GCallback) (ctk_entry_delete_surrounding_cb))), (entry)
, ((void*)0), (GConnectFlags) 0)
;
2821
2822 ctk_entry_update_cached_style_values (entry);
2823
2824 priv->drag_gesture = ctk_gesture_drag_new (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
2825 g_signal_connect (priv->drag_gesture, "drag-update",g_signal_connect_data ((priv->drag_gesture), ("drag-update"
), (((GCallback) (ctk_entry_drag_gesture_update))), (entry), (
(void*)0), (GConnectFlags) 0)
2826 G_CALLBACK (ctk_entry_drag_gesture_update), entry)g_signal_connect_data ((priv->drag_gesture), ("drag-update"
), (((GCallback) (ctk_entry_drag_gesture_update))), (entry), (
(void*)0), (GConnectFlags) 0)
;
2827 g_signal_connect (priv->drag_gesture, "drag-end",g_signal_connect_data ((priv->drag_gesture), ("drag-end"),
(((GCallback) (ctk_entry_drag_gesture_end))), (entry), ((void
*)0), (GConnectFlags) 0)
2828 G_CALLBACK (ctk_entry_drag_gesture_end), entry)g_signal_connect_data ((priv->drag_gesture), ("drag-end"),
(((GCallback) (ctk_entry_drag_gesture_end))), (entry), ((void
*)0), (GConnectFlags) 0)
;
2829 ctk_gesture_single_set_button (CTK_GESTURE_SINGLE (priv->drag_gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((priv->drag_gesture)), ((ctk_gesture_single_get_type
()))))))
, 0);
2830 ctk_gesture_single_set_exclusive (CTK_GESTURE_SINGLE (priv->drag_gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((priv->drag_gesture)), ((ctk_gesture_single_get_type
()))))))
, TRUE(!(0)));
2831
2832 priv->multipress_gesture = ctk_gesture_multi_press_new (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
2833 g_signal_connect (priv->multipress_gesture, "pressed",g_signal_connect_data ((priv->multipress_gesture), ("pressed"
), (((GCallback) (ctk_entry_multipress_gesture_pressed))), (entry
), ((void*)0), (GConnectFlags) 0)
2834 G_CALLBACK (ctk_entry_multipress_gesture_pressed), entry)g_signal_connect_data ((priv->multipress_gesture), ("pressed"
), (((GCallback) (ctk_entry_multipress_gesture_pressed))), (entry
), ((void*)0), (GConnectFlags) 0)
;
2835 ctk_gesture_single_set_button (CTK_GESTURE_SINGLE (priv->multipress_gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((priv->multipress_gesture)), ((ctk_gesture_single_get_type
()))))))
, 0);
2836 ctk_gesture_single_set_exclusive (CTK_GESTURE_SINGLE (priv->multipress_gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((priv->multipress_gesture)), ((ctk_gesture_single_get_type
()))))))
, TRUE(!(0)));
2837
2838 widget_node = ctk_widget_get_css_node (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
2839 priv->gadget = ctk_css_custom_gadget_new_for_node (widget_node,
2840 CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
,
2841 ctk_entry_measure,
2842 ctk_entry_allocate,
2843 ctk_entry_render,
2844 NULL((void*)0),
2845 NULL((void*)0));
2846
2847 for (i = 0; i < 2; i++)
2848 {
2849 priv->undershoot_node[i] = ctk_css_node_new ();
2850 ctk_css_node_set_name (priv->undershoot_node[i], I_("undershoot")g_intern_static_string ("undershoot"));
2851 ctk_css_node_add_class (priv->undershoot_node[i], g_quark_from_static_string (i == 0 ? CTK_STYLE_CLASS_LEFT"left" : CTK_STYLE_CLASS_RIGHT"right"));
2852 ctk_css_node_set_parent (priv->undershoot_node[i], widget_node);
2853 ctk_css_node_set_state (priv->undershoot_node[i], ctk_css_node_get_state (widget_node) & ~CTK_STATE_FLAG_DROP_ACTIVE);
2854 g_object_unref (priv->undershoot_node[i]);
2855 }
2856}
2857
2858static void
2859ctk_entry_ensure_magnifier (CtkEntry *entry)
2860{
2861 CtkEntryPrivate *priv = entry->priv;
2862
2863 if (priv->magnifier_popover)
2864 return;
2865
2866 priv->magnifier = _ctk_magnifier_new (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
2867 ctk_widget_set_size_request (priv->magnifier, 100, 60);
2868 _ctk_magnifier_set_magnification (CTK_MAGNIFIER (priv->magnifier)((((CtkMagnifier*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->magnifier)), ((_ctk_magnifier_get_type ()))))))
, 2.0);
2869 priv->magnifier_popover = ctk_popover_new (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
2870 ctk_style_context_add_class (ctk_widget_get_style_context (priv->magnifier_popover),
2871 "magnifier");
2872 ctk_popover_set_modal (CTK_POPOVER (priv->magnifier_popover)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->magnifier_popover)), ((ctk_popover_get_type ())
)))))
, FALSE(0));
2873 ctk_container_add (CTK_CONTAINER (priv->magnifier_popover)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->magnifier_popover)), ((ctk_container_get_type (
)))))))
,
2874 priv->magnifier);
2875 ctk_container_set_border_width (CTK_CONTAINER (priv->magnifier_popover)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->magnifier_popover)), ((ctk_container_get_type (
)))))))
, 4);
2876 ctk_widget_show (priv->magnifier);
2877}
2878
2879static void
2880ctk_entry_ensure_text_handles (CtkEntry *entry)
2881{
2882 CtkEntryPrivate *priv = entry->priv;
2883
2884 if (priv->text_handle)
2885 return;
2886
2887 priv->text_handle = _ctk_text_handle_new (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
2888 g_signal_connect (priv->text_handle, "drag-started",g_signal_connect_data ((priv->text_handle), ("drag-started"
), (((GCallback) (ctk_entry_handle_drag_started))), (entry), (
(void*)0), (GConnectFlags) 0)
2889 G_CALLBACK (ctk_entry_handle_drag_started), entry)g_signal_connect_data ((priv->text_handle), ("drag-started"
), (((GCallback) (ctk_entry_handle_drag_started))), (entry), (
(void*)0), (GConnectFlags) 0)
;
2890 g_signal_connect (priv->text_handle, "handle-dragged",g_signal_connect_data ((priv->text_handle), ("handle-dragged"
), (((GCallback) (ctk_entry_handle_dragged))), (entry), ((void
*)0), (GConnectFlags) 0)
2891 G_CALLBACK (ctk_entry_handle_dragged), entry)g_signal_connect_data ((priv->text_handle), ("handle-dragged"
), (((GCallback) (ctk_entry_handle_dragged))), (entry), ((void
*)0), (GConnectFlags) 0)
;
2892 g_signal_connect (priv->text_handle, "drag-finished",g_signal_connect_data ((priv->text_handle), ("drag-finished"
), (((GCallback) (ctk_entry_handle_drag_finished))), (entry),
((void*)0), (GConnectFlags) 0)
2893 G_CALLBACK (ctk_entry_handle_drag_finished), entry)g_signal_connect_data ((priv->text_handle), ("drag-finished"
), (((GCallback) (ctk_entry_handle_drag_finished))), (entry),
((void*)0), (GConnectFlags) 0)
;
2894}
2895
2896static gint
2897get_icon_width (CtkEntry *entry,
2898 CtkEntryIconPosition icon_pos)
2899{
2900 EntryIconInfo *icon_info = entry->priv->icons[icon_pos];
2901 gint width;
2902
2903 if (!icon_info)
2904 return 0;
2905
2906 ctk_css_gadget_get_preferred_size (icon_info->gadget,
2907 CTK_ORIENTATION_HORIZONTAL,
2908 -1,
2909 &width, NULL((void*)0),
2910 NULL((void*)0), NULL((void*)0));
2911
2912 return width;
2913}
2914
2915static void
2916begin_change (CtkEntry *entry)
2917{
2918 CtkEntryPrivate *priv = entry->priv;
2919
2920 priv->change_count++;
2921
2922 g_object_freeze_notify (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
2923}
2924
2925static void
2926end_change (CtkEntry *entry)
2927{
2928 CtkEditable *editable = CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
;
2929 CtkEntryPrivate *priv = entry->priv;
2930
2931 g_return_if_fail (priv->change_count > 0)do { if ((priv->change_count > 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "priv->change_count > 0"
); return; } } while (0)
;
2932
2933 g_object_thaw_notify (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
2934
2935 priv->change_count--;
2936
2937 if (priv->change_count == 0)
2938 {
2939 if (priv->real_changed)
2940 {
2941 g_signal_emit_by_name (editable, "changed");
2942 priv->real_changed = FALSE(0);
2943 }
2944 }
2945}
2946
2947static void
2948emit_changed (CtkEntry *entry)
2949{
2950 CtkEditable *editable = CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
;
2951 CtkEntryPrivate *priv = entry->priv;
2952
2953 if (priv->change_count == 0)
2954 g_signal_emit_by_name (editable, "changed");
2955 else
2956 priv->real_changed = TRUE(!(0));
2957}
2958
2959static void
2960ctk_entry_destroy (CtkWidget *widget)
2961{
2962 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
2963 CtkEntryPrivate *priv = entry->priv;
2964
2965 priv->current_pos = priv->selection_bound = 0;
2966 ctk_entry_reset_im_context (entry);
2967 ctk_entry_reset_layout (entry);
2968
2969 if (priv->blink_timeout)
2970 {
2971 g_source_remove (priv->blink_timeout);
2972 priv->blink_timeout = 0;
2973 }
2974
2975 if (priv->magnifier)
2976 _ctk_magnifier_set_inspected (CTK_MAGNIFIER (priv->magnifier)((((CtkMagnifier*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->magnifier)), ((_ctk_magnifier_get_type ()))))))
, NULL((void*)0));
2977
2978 CTK_WIDGET_CLASS (ctk_entry_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_entry_parent_class)), ((ctk_widget_get_type ()))))))
->destroy (widget);
2979}
2980
2981static void
2982ctk_entry_dispose (GObject *object)
2983{
2984 CtkEntry *entry = CTK_ENTRY (object)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_entry_get_type ()))))))
;
2985 CtkEntryPrivate *priv = entry->priv;
2986 CdkKeymap *keymap;
2987
2988 ctk_entry_set_icon_from_pixbuf (entry, CTK_ENTRY_ICON_PRIMARY, NULL((void*)0));
2989 ctk_entry_set_icon_tooltip_markup (entry, CTK_ENTRY_ICON_PRIMARY, NULL((void*)0));
2990 ctk_entry_set_icon_from_pixbuf (entry, CTK_ENTRY_ICON_SECONDARY, NULL((void*)0));
2991 ctk_entry_set_icon_tooltip_markup (entry, CTK_ENTRY_ICON_SECONDARY, NULL((void*)0));
2992 ctk_entry_set_completion (entry, NULL((void*)0));
2993
2994 priv->current_pos = 0;
2995
2996 if (priv->buffer)
2997 {
2998 buffer_disconnect_signals (entry);
2999 g_object_unref (priv->buffer);
3000 priv->buffer = NULL((void*)0);
3001 }
3002
3003 keymap = cdk_keymap_get_for_display (ctk_widget_get_display (CTK_WIDGET (object)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_widget_get_type ()))))))
));
3004 g_signal_handlers_disconnect_by_func (keymap, keymap_state_changed, entry)g_signal_handlers_disconnect_matched ((keymap), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (keymap_state_changed), (entry))
;
3005 g_signal_handlers_disconnect_by_func (keymap, keymap_direction_changed, entry)g_signal_handlers_disconnect_matched ((keymap), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (keymap_direction_changed), (entry))
;
3006 G_OBJECT_CLASS (ctk_entry_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_entry_parent_class)), (((GType) ((20) << (2)))
)))))
->dispose (object);
3007}
3008
3009static void
3010ctk_entry_finalize (GObject *object)
3011{
3012 CtkEntry *entry = CTK_ENTRY (object)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_entry_get_type ()))))))
;
3013 CtkEntryPrivate *priv = entry->priv;
3014 EntryIconInfo *icon_info = NULL((void*)0);
3015 gint i;
3016
3017 if (priv->tick_id)
3018 ctk_widget_remove_tick_callback (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, priv->tick_id);
3019
3020 for (i = 0; i < MAX_ICONS2; i++)
3021 {
3022 icon_info = priv->icons[i];
3023 if (icon_info == NULL((void*)0))
3024 continue;
3025
3026 if (icon_info->target_list != NULL((void*)0))
3027 ctk_target_list_unref (icon_info->target_list);
3028
3029 g_clear_object (&icon_info->gadget)do { _Static_assert (sizeof *((&icon_info->gadget)) ==
sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&icon_info->gadget))) _pp = ((&icon_info->gadget
)); __typeof__ (*((&icon_info->gadget))) _ptr = *_pp; *
_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while (
0)
;
3030
3031 g_slice_free (EntryIconInfo, icon_info)do { if (1) g_slice_free1 (sizeof (EntryIconInfo), (icon_info
)); else (void) ((EntryIconInfo*) 0 == (icon_info)); } while (
0)
;
3032 }
3033
3034 if (priv->cached_layout)
3035 g_object_unref (priv->cached_layout);
3036
3037 g_object_unref (priv->im_context);
3038
3039 if (priv->blink_timeout)
3040 g_source_remove (priv->blink_timeout);
3041
3042 if (priv->selection_bubble)
3043 ctk_widget_destroy (priv->selection_bubble);
3044
3045 if (priv->magnifier_popover)
3046 ctk_widget_destroy (priv->magnifier_popover);
3047
3048 if (priv->text_handle)
3049 g_object_unref (priv->text_handle);
3050 g_free (priv->placeholder_text);
3051 g_free (priv->im_module);
3052
3053 g_clear_object (&priv->drag_gesture)do { _Static_assert (sizeof *((&priv->drag_gesture)) ==
sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&priv->drag_gesture))) _pp = ((&priv->drag_gesture
)); __typeof__ (*((&priv->drag_gesture))) _ptr = *_pp;
*_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while
(0)
;
3054 g_clear_object (&priv->multipress_gesture)do { _Static_assert (sizeof *((&priv->multipress_gesture
)) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&priv->multipress_gesture))) _pp = ((&priv->
multipress_gesture)); __typeof__ (*((&priv->multipress_gesture
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
3055
3056 if (priv->tabs)
3057 pango_tab_array_free (priv->tabs);
3058
3059 if (priv->attrs)
3060 pango_attr_list_unref (priv->attrs);
3061
3062 g_clear_object (&priv->progress_gadget)do { _Static_assert (sizeof *((&priv->progress_gadget)
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&priv->progress_gadget))) _pp = ((&priv->progress_gadget
)); __typeof__ (*((&priv->progress_gadget))) _ptr = *_pp
; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while
(0)
;
3063 g_clear_object (&priv->gadget)do { _Static_assert (sizeof *((&priv->gadget)) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ (((
&priv->gadget))) _pp = ((&priv->gadget)); __typeof__
(*((&priv->gadget))) _ptr = *_pp; *_pp = ((void*)0); if
(_ptr) (g_object_unref) (_ptr); } while (0)
;
3064
3065 G_OBJECT_CLASS (ctk_entry_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_entry_parent_class)), (((GType) ((20) << (2)))
)))))
->finalize (object);
3066}
3067
3068static DisplayMode
3069ctk_entry_get_display_mode (CtkEntry *entry)
3070{
3071 CtkEntryPrivate *priv = entry->priv;
3072
3073 if (priv->visible)
3074 return DISPLAY_NORMAL;
3075
3076 if (priv->invisible_char == 0 && priv->invisible_char_set)
3077 return DISPLAY_BLANK;
3078
3079 return DISPLAY_INVISIBLE;
3080}
3081
3082gchar*
3083_ctk_entry_get_display_text (CtkEntry *entry,
3084 gint start_pos,
3085 gint end_pos)
3086{
3087 CtkEntryPasswordHint *password_hint;
3088 CtkEntryPrivate *priv;
3089 gunichar invisible_char;
3090 const gchar *start;
3091 const gchar *end;
3092 const gchar *text;
3093 gchar char_str[7];
3094 gint char_len;
3095 GString *str;
3096 guint length;
3097 gint i;
3098
3099 priv = entry->priv;
3100 text = ctk_entry_buffer_get_text (get_buffer (entry));
3101 length = ctk_entry_buffer_get_length (get_buffer (entry));
3102
3103 if (end_pos < 0 || end_pos > length)
3104 end_pos = length;
3105 if (start_pos > length)
3106 start_pos = length;
3107
3108 if (end_pos <= start_pos)
3109 return g_strdup ("")g_strdup_inline ("");
3110 else if (priv->visible)
3111 {
3112 start = g_utf8_offset_to_pointer (text, start_pos);
3113 end = g_utf8_offset_to_pointer (start, end_pos - start_pos);
3114 return g_strndup (start, end - start);
3115 }
3116 else
3117 {
3118 str = g_string_sized_new (length * 2);
3119
3120 /* Figure out what our invisible char is and encode it */
3121 if (!priv->invisible_char)
3122 invisible_char = priv->invisible_char_set ? ' ' : '*';
3123 else
3124 invisible_char = priv->invisible_char;
3125 char_len = g_unichar_to_utf8 (invisible_char, char_str);
3126
3127 /*
3128 * Add hidden characters for each character in the text
3129 * buffer. If there is a password hint, then keep that
3130 * character visible.
3131 */
3132
3133 password_hint = g_object_get_qdata (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, quark_password_hint);
3134 for (i = start_pos; i < end_pos; ++i)
3135 {
3136 if (password_hint && i == password_hint->position)
3137 {
3138 start = g_utf8_offset_to_pointer (text, i);
3139 g_string_append_len (str, start, g_utf8_next_char (start) - start)g_string_append_len_inline (str, start, ((start) + g_utf8_skip
[*(const guchar *)(start)]) - start)
;
3140 }
3141 else
3142 {
3143 g_string_append_len (str, char_str, char_len)g_string_append_len_inline (str, char_str, char_len);
3144 }
3145 }
3146
3147 return g_string_free (str, FALSE)(__builtin_constant_p ((0)) ? (((0)) ? (g_string_free) ((str)
, ((0))) : g_string_free_and_steal (str)) : (g_string_free) (
(str), ((0))))
;
3148 }
3149}
3150
3151static void
3152update_cursors (CtkWidget *widget)
3153{
3154 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
3155 CtkEntryPrivate *priv = entry->priv;
3156 EntryIconInfo *icon_info = NULL((void*)0);
3157 CdkDisplay *display;
3158 CdkCursor *cursor;
3159 gint i;
3160
3161 for (i = 0; i < MAX_ICONS2; i++)
3162 {
3163 if ((icon_info = priv->icons[i]) != NULL((void*)0))
3164 {
3165 if (!_ctk_icon_helper_get_is_empty (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
) &&
3166 icon_info->window != NULL((void*)0))
3167 cdk_window_show_unraised (icon_info->window);
3168
3169 /* The icon windows are not children of the visible entry window,
3170 * thus we can't just inherit the xterm cursor. Slight complication
3171 * here is that for the entry, insensitive => arrow cursor, but for
3172 * an icon in a sensitive entry, insensitive => xterm cursor.
3173 */
3174 if (ctk_widget_is_sensitive (widget) &&
3175 (icon_info->insensitive ||
3176 (icon_info->nonactivatable && icon_info->target_list == NULL((void*)0))))
3177 {
3178 display = ctk_widget_get_display (widget);
3179 cursor = cdk_cursor_new_from_name (display, "text");
3180 cdk_window_set_cursor (icon_info->window, cursor);
3181 g_clear_object (&cursor)do { _Static_assert (sizeof *((&cursor)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&cursor
))) _pp = ((&cursor)); __typeof__ (*((&cursor))) _ptr
= *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr)
; } while (0)
;
3182 }
3183 else
3184 {
3185 cdk_window_set_cursor (icon_info->window, NULL((void*)0));
3186 }
3187 }
3188 }
3189}
3190
3191static void
3192realize_icon_info (CtkWidget *widget,
3193 CtkEntryIconPosition icon_pos)
3194{
3195 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
3196 CtkEntryPrivate *priv = entry->priv;
3197 EntryIconInfo *icon_info = priv->icons[icon_pos];
3198 CdkWindowAttr attributes;
3199 gint attributes_mask;
3200
3201 g_return_if_fail (icon_info != NULL)do { if ((icon_info != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "icon_info != NULL"); return
; } } while (0)
;
3202
3203 attributes.x = 0;
3204 attributes.y = 0;
3205 attributes.width = 1;
3206 attributes.height = 1;
3207 attributes.window_type = CDK_WINDOW_CHILD;
3208 attributes.wclass = CDK_INPUT_ONLY;
3209 attributes.event_mask = ctk_widget_get_events (widget);
3210 attributes.event_mask |= (CDK_BUTTON_PRESS_MASK |
3211 CDK_BUTTON_RELEASE_MASK |
3212 CDK_BUTTON1_MOTION_MASK |
3213 CDK_BUTTON3_MOTION_MASK |
3214 CDK_POINTER_MOTION_MASK |
3215 CDK_ENTER_NOTIFY_MASK |
3216 CDK_LEAVE_NOTIFY_MASK);
3217 attributes_mask = CDK_WA_X | CDK_WA_Y;
3218
3219 icon_info->window = cdk_window_new (ctk_widget_get_window (widget),
3220 &attributes,
3221 attributes_mask);
3222 ctk_widget_register_window (widget, icon_info->window);
3223
3224 ctk_widget_queue_resize (widget);
3225}
3226
3227static void
3228update_icon_style (CtkWidget *widget,
3229 CtkEntryIconPosition icon_pos)
3230{
3231 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
3232 CtkEntryPrivate *priv = entry->priv;
3233 EntryIconInfo *icon_info = priv->icons[icon_pos];
3234 const gchar *sides[2] = { CTK_STYLE_CLASS_LEFT"left", CTK_STYLE_CLASS_RIGHT"right" };
3235
3236 if (icon_info == NULL((void*)0))
3237 return;
3238
3239 if (ctk_widget_get_direction (widget) == CTK_TEXT_DIR_RTL)
3240 icon_pos = 1 - icon_pos;
3241
3242 ctk_css_gadget_add_class (icon_info->gadget, sides[icon_pos]);
3243 ctk_css_gadget_remove_class (icon_info->gadget, sides[1 - icon_pos]);
3244}
3245
3246static void
3247update_icon_state (CtkWidget *widget,
3248 CtkEntryIconPosition icon_pos)
3249{
3250 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
3251 CtkEntryPrivate *priv = entry->priv;
3252 EntryIconInfo *icon_info = priv->icons[icon_pos];
3253 CtkStateFlags state;
3254
3255 if (icon_info == NULL((void*)0))
3256 return;
3257
3258 state = ctk_widget_get_state_flags (widget);
3259 state &= ~(CTK_STATE_FLAG_PRELIGHT | CTK_STATE_FLAG_DROP_ACTIVE);
3260
3261 if ((state & CTK_STATE_FLAG_INSENSITIVE) || icon_info->insensitive)
3262 state |= CTK_STATE_FLAG_INSENSITIVE;
3263 else if (icon_info->prelight)
3264 state |= CTK_STATE_FLAG_PRELIGHT;
3265
3266 ctk_css_gadget_set_state (icon_info->gadget, state);
3267}
3268
3269static void
3270update_node_state (CtkEntry *entry)
3271{
3272 CtkEntryPrivate *priv = entry->priv;
3273 CtkStateFlags state;
3274
3275 state = ctk_widget_get_state_flags (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
3276 state &= ~CTK_STATE_FLAG_DROP_ACTIVE;
3277
3278 if (priv->progress_gadget)
3279 ctk_css_gadget_set_state (priv->progress_gadget, state);
3280 if (priv->selection_node)
3281 ctk_css_node_set_state (priv->selection_node, state);
3282
3283 ctk_css_node_set_state (priv->undershoot_node[0], state);
3284 ctk_css_node_set_state (priv->undershoot_node[1], state);
3285}
3286
3287static void
3288update_node_ordering (CtkEntry *entry)
3289{
3290 CtkEntryPrivate *priv = entry->priv;
3291 EntryIconInfo *icon_info;
3292 CtkEntryIconPosition icon_pos;
3293 CtkCssNode *sibling, *parent;
3294
3295 if (priv->progress_gadget)
3296 {
3297 ctk_css_node_insert_before (ctk_css_gadget_get_node (priv->gadget),
3298 ctk_css_gadget_get_node (priv->progress_gadget),
3299 NULL((void*)0));
3300 }
3301
3302 if (ctk_widget_get_direction (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
) == CTK_TEXT_DIR_RTL)
3303 icon_pos = CTK_ENTRY_ICON_SECONDARY;
3304 else
3305 icon_pos = CTK_ENTRY_ICON_PRIMARY;
3306
3307 icon_info = priv->icons[icon_pos];
3308 if (icon_info)
3309 {
3310 CtkCssNode *node;
3311
3312 node = ctk_css_gadget_get_node (icon_info->gadget);
3313 parent = ctk_css_node_get_parent (node);
3314 sibling = ctk_css_node_get_first_child (parent);
3315 if (node != sibling)
3316 ctk_css_node_insert_before (parent, node, sibling);
3317 }
3318}
3319
3320static EntryIconInfo*
3321construct_icon_info (CtkWidget *widget,
3322 CtkEntryIconPosition icon_pos)
3323{
3324 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
3325 CtkEntryPrivate *priv = entry->priv;
3326 EntryIconInfo *icon_info;
3327 CtkCssNode *widget_node;
3328
3329 g_return_val_if_fail (priv->icons[icon_pos] == NULL, NULL)do { if ((priv->icons[icon_pos] == ((void*)0))) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"priv->icons[icon_pos] == NULL"); return (((void*)0)); } }
while (0)
;
3330
3331 icon_info = g_slice_new0 (EntryIconInfo)((EntryIconInfo*) g_slice_alloc0 (sizeof (EntryIconInfo)));
3332 priv->icons[icon_pos] = icon_info;
3333
3334 widget_node = ctk_css_gadget_get_node (priv->gadget);
3335 icon_info->gadget = ctk_icon_helper_new_named ("image", widget);
3336 _ctk_icon_helper_set_force_scale_pixbuf (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
, TRUE(!(0)));
3337 ctk_css_node_set_parent (ctk_css_gadget_get_node (icon_info->gadget), widget_node);
3338
3339 update_icon_state (widget, icon_pos);
3340 update_icon_style (widget, icon_pos);
3341 update_node_ordering (entry);
3342
3343 if (ctk_widget_get_realized (widget))
3344 realize_icon_info (widget, icon_pos);
3345
3346 return icon_info;
3347}
3348
3349static void
3350ctk_entry_map (CtkWidget *widget)
3351{
3352 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
3353 CtkEntryPrivate *priv = entry->priv;
3354 EntryIconInfo *icon_info = NULL((void*)0);
3355 gint i;
3356
3357 CTK_WIDGET_CLASS (ctk_entry_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_entry_parent_class)), ((ctk_widget_get_type ()))))))
->map (widget);
3358
3359 cdk_window_show (priv->text_area);
3360
3361 for (i = 0; i < MAX_ICONS2; i++)
3362 {
3363 if ((icon_info = priv->icons[i]) != NULL((void*)0))
3364 {
3365 if (!_ctk_icon_helper_get_is_empty (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
) &&
3366 icon_info->window != NULL((void*)0))
3367 cdk_window_show (icon_info->window);
3368 }
3369 }
3370
3371 update_cursors (widget);
3372}
3373
3374static void
3375ctk_entry_unmap (CtkWidget *widget)
3376{
3377 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
3378 CtkEntryPrivate *priv = entry->priv;
3379 EntryIconInfo *icon_info = NULL((void*)0);
3380 gint i;
3381
3382 if (priv->text_handle)
3383 _ctk_text_handle_set_mode (priv->text_handle,
3384 CTK_TEXT_HANDLE_MODE_NONE);
3385
3386 for (i = 0; i < MAX_ICONS2; i++)
3387 {
3388 if ((icon_info = priv->icons[i]) != NULL((void*)0))
3389 {
3390 if (!_ctk_icon_helper_get_is_empty (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
) &&
3391 icon_info->window != NULL((void*)0))
3392 cdk_window_hide (icon_info->window);
3393 }
3394 }
3395
3396 cdk_window_hide (priv->text_area);
3397
3398 CTK_WIDGET_CLASS (ctk_entry_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_entry_parent_class)), ((ctk_widget_get_type ()))))))
->unmap (widget);
3399}
3400
3401static void
3402ctk_entry_realize (CtkWidget *widget)
3403{
3404 CtkEntry *entry;
3405 CtkEntryPrivate *priv;
3406 EntryIconInfo *icon_info;
3407 CdkWindowAttr attributes;
3408 gint attributes_mask;
3409 int i;
3410
3411 CTK_WIDGET_CLASS (ctk_entry_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_entry_parent_class)), ((ctk_widget_get_type ()))))))
->realize (widget);
3412
3413 entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
3414 priv = entry->priv;
3415
3416 attributes.window_type = CDK_WINDOW_CHILD;
3417 attributes.wclass = CDK_INPUT_ONLY;
3418 attributes.event_mask = ctk_widget_get_events (widget);
3419 attributes.event_mask |= (CDK_BUTTON_PRESS_MASK |
3420 CDK_BUTTON_RELEASE_MASK |
3421 CDK_BUTTON1_MOTION_MASK |
3422 CDK_BUTTON3_MOTION_MASK |
3423 CDK_POINTER_MOTION_MASK |
3424 CDK_ENTER_NOTIFY_MASK |
3425 CDK_LEAVE_NOTIFY_MASK);
3426 attributes_mask = CDK_WA_X | CDK_WA_Y;
3427
3428 attributes.x = priv->text_allocation.x;
3429 attributes.y = priv->text_allocation.y;
3430 attributes.width = priv->text_allocation.width;
3431 attributes.height = priv->text_allocation.height;
3432
3433 if (ctk_widget_is_sensitive (widget))
3434 {
3435 attributes.cursor = cdk_cursor_new_from_name (ctk_widget_get_display (widget), "text");
3436 attributes_mask |= CDK_WA_CURSOR;
3437 }
3438
3439 priv->text_area = cdk_window_new (ctk_widget_get_window (widget),
3440 &attributes,
3441 attributes_mask);
3442
3443 ctk_widget_register_window (widget, priv->text_area);
3444
3445 if (attributes_mask & CDK_WA_CURSOR)
3446 g_clear_object (&attributes.cursor)do { _Static_assert (sizeof *((&attributes.cursor)) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ (((
&attributes.cursor))) _pp = ((&attributes.cursor)); __typeof__
(*((&attributes.cursor))) _ptr = *_pp; *_pp = ((void*)0)
; if (_ptr) (g_object_unref) (_ptr); } while (0)
;
3447
3448 ctk_im_context_set_client_window (priv->im_context, priv->text_area);
3449
3450 ctk_entry_adjust_scroll (entry);
3451 ctk_entry_update_primary_selection (entry);
3452
3453 /* If the icon positions are already setup, create their windows.
3454 * Otherwise if they don't exist yet, then construct_icon_info()
3455 * will create the windows once the widget is already realized.
3456 */
3457 for (i = 0; i < MAX_ICONS2; i++)
3458 {
3459 if ((icon_info = priv->icons[i]) != NULL((void*)0))
3460 {
3461 if (icon_info->window == NULL((void*)0))
3462 realize_icon_info (widget, i);
3463 }
3464 }
3465}
3466
3467static void
3468ctk_entry_unrealize (CtkWidget *widget)
3469{
3470 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
3471 CtkEntryPrivate *priv = entry->priv;
3472 CtkClipboard *clipboard;
3473 EntryIconInfo *icon_info;
3474 gint i;
3475
3476 ctk_entry_reset_layout (entry);
3477
3478 ctk_im_context_set_client_window (priv->im_context, NULL((void*)0));
3479
3480 clipboard = ctk_widget_get_clipboard (widget, CDK_SELECTION_PRIMARY((CdkAtom)((gpointer) (gulong) (1))));
3481 if (ctk_clipboard_get_owner (clipboard) == G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
)
3482 ctk_clipboard_clear (clipboard);
3483
3484 if (priv->text_area)
3485 {
3486 ctk_widget_unregister_window (widget, priv->text_area);
3487 cdk_window_destroy (priv->text_area);
3488 priv->text_area = NULL((void*)0);
3489 }
3490
3491 if (priv->popup_menu)
3492 {
3493 ctk_widget_destroy (priv->popup_menu);
3494 priv->popup_menu = NULL((void*)0);
3495 }
3496
3497 CTK_WIDGET_CLASS (ctk_entry_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_entry_parent_class)), ((ctk_widget_get_type ()))))))
->unrealize (widget);
3498
3499 for (i = 0; i < MAX_ICONS2; i++)
3500 {
3501 if ((icon_info = priv->icons[i]) != NULL((void*)0))
3502 {
3503 if (icon_info->window != NULL((void*)0))
3504 {
3505 ctk_widget_unregister_window (widget, icon_info->window);
3506 cdk_window_destroy (icon_info->window);
3507 icon_info->window = NULL((void*)0);
3508 }
3509 }
3510 }
3511}
3512
3513static void
3514ctk_entry_get_preferred_width (CtkWidget *widget,
3515 gint *minimum,
3516 gint *natural)
3517{
3518 ctk_css_gadget_get_preferred_size (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
->priv->gadget,
3519 CTK_ORIENTATION_HORIZONTAL,
3520 -1,
3521 minimum, natural,
3522 NULL((void*)0), NULL((void*)0));
3523}
3524
3525static void
3526ctk_entry_get_preferred_height (CtkWidget *widget,
3527 gint *minimum,
3528 gint *natural)
3529{
3530 ctk_css_gadget_get_preferred_size (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
->priv->gadget,
3531 CTK_ORIENTATION_VERTICAL,
3532 -1,
3533 minimum, natural,
3534 NULL((void*)0), NULL((void*)0));
3535}
3536
3537static void
3538ctk_entry_get_preferred_height_and_baseline_for_width (CtkWidget *widget,
3539 gint width,
3540 gint *minimum,
3541 gint *natural,
3542 gint *minimum_baseline,
3543 gint *natural_baseline)
3544{
3545 ctk_css_gadget_get_preferred_size (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
->priv->gadget,
3546 CTK_ORIENTATION_VERTICAL,
3547 width,
3548 minimum, natural,
3549 minimum_baseline, natural_baseline);
3550}
3551
3552static void
3553ctk_entry_measure (CtkCssGadget *gadget,
3554 CtkOrientation orientation,
3555 int for_size,
3556 int *minimum,
3557 int *natural,
3558 int *minimum_baseline,
3559 int *natural_baseline,
3560 gpointer unused G_GNUC_UNUSED__attribute__ ((__unused__)))
3561{
3562 CtkWidget *widget;
3563 CtkEntry *entry;
3564 CtkEntryPrivate *priv;
3565 PangoContext *context;
3566 PangoFontMetrics *metrics;
3567
3568 widget = ctk_css_gadget_get_owner (gadget);
3569 entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
3570 priv = entry->priv;
3571
3572 context = ctk_widget_get_pango_context (widget);
3573 metrics = pango_context_get_metrics (context,
3574 pango_context_get_font_description (context),
3575 pango_context_get_language (context));
3576
3577 if (orientation == CTK_ORIENTATION_HORIZONTAL)
3578 {
3579 gint icon_width, i;
3580 gint min, nat;
3581 gint char_width;
3582 gint digit_width;
3583 gint char_pixels;
3584
3585 char_width = pango_font_metrics_get_approximate_char_width (metrics);
3586 digit_width = pango_font_metrics_get_approximate_digit_width (metrics);
3587 char_pixels = (MAX (char_width, digit_width)(((char_width) > (digit_width)) ? (char_width) : (digit_width
))
+ PANGO_SCALE1024 - 1) / PANGO_SCALE1024;
3588
3589 if (priv->width_chars < 0)
3590 {
3591 if (CTK_IS_SPIN_BUTTON (entry)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(entry)); GType __t = ((ctk_spin_button_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; }))))
)
3592 min = ctk_spin_button_get_text_width (CTK_SPIN_BUTTON (entry)((((CtkSpinButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_spin_button_get_type ()))))))
);
3593 else
3594 min = MIN_ENTRY_WIDTH150;
3595 }
3596 else
3597 {
3598 min = char_pixels * priv->width_chars;
3599 }
3600
3601 if (priv->max_width_chars < 0)
3602 nat = min;
3603 else
3604 nat = char_pixels * priv->max_width_chars;
3605
3606 icon_width = 0;
3607 for (i = 0; i < MAX_ICONS2; i++)
3608 icon_width += get_icon_width (entry, i);
3609
3610 min = MAX (min, icon_width)(((min) > (icon_width)) ? (min) : (icon_width));
3611 nat = MAX (min, nat)(((min) > (nat)) ? (min) : (nat));
3612
3613 *minimum = min;
3614 *natural = nat;
3615 }
3616 else
3617 {
3618 gint height, baseline;
3619 gint icon_height, i;
3620 PangoLayout *layout;
3621
3622 layout = ctk_entry_ensure_layout (entry, TRUE(!(0)));
3623
3624 priv->ascent = pango_font_metrics_get_ascent (metrics);
3625 priv->descent = pango_font_metrics_get_descent (metrics);
3626
3627 pango_layout_get_pixel_size (layout, NULL((void*)0), &height);
3628
3629 height = MAX (height, PANGO_PIXELS (priv->ascent + priv->descent))(((height) > ((((int)(priv->ascent + priv->descent) +
512) >> 10))) ? (height) : ((((int)(priv->ascent + priv
->descent) + 512) >> 10)))
;
3630
3631 baseline = pango_layout_get_baseline (layout) / PANGO_SCALE1024;
3632
3633 icon_height = 0;
3634 for (i = 0; i < MAX_ICONS2; i++)
3635 {
3636 EntryIconInfo *icon_info = priv->icons[i];
3637 gint h;
3638
3639 if (!icon_info)
3640 continue;
3641
3642 ctk_css_gadget_get_preferred_size (icon_info->gadget,
3643 CTK_ORIENTATION_VERTICAL,
3644 -1,
3645 NULL((void*)0), &h,
3646 NULL((void*)0), NULL((void*)0));
3647 icon_height = MAX (icon_height, h)(((icon_height) > (h)) ? (icon_height) : (h));
3648 }
3649
3650 *minimum = MAX (height, icon_height)(((height) > (icon_height)) ? (height) : (icon_height));
3651 *natural = MAX (height, icon_height)(((height) > (icon_height)) ? (height) : (icon_height));
3652
3653 if (icon_height > height)
3654 baseline += (icon_height - height) / 2;
3655
3656 if (minimum_baseline)
3657 *minimum_baseline = baseline;
3658 if (natural_baseline)
3659 *natural_baseline = baseline;
3660 }
3661
3662 pango_font_metrics_unref (metrics);
3663
3664 if (priv->progress_gadget && ctk_css_gadget_get_visible (priv->progress_gadget))
3665 {
3666 int prog_min, prog_nat;
3667
3668 ctk_css_gadget_get_preferred_size (priv->progress_gadget,
3669 orientation,
3670 for_size,
3671 &prog_min, &prog_nat,
3672 NULL((void*)0), NULL((void*)0));
3673
3674 *minimum = MAX (*minimum, prog_min)(((*minimum) > (prog_min)) ? (*minimum) : (prog_min));
3675 *natural = MAX (*natural, prog_nat)(((*natural) > (prog_nat)) ? (*natural) : (prog_nat));
3676 }
3677}
3678
3679static void
3680place_windows (CtkEntry *entry)
3681{
3682 CtkEntryPrivate *priv = entry->priv;
3683 EntryIconInfo *icon_info;
3684
3685 icon_info = priv->icons[CTK_ENTRY_ICON_PRIMARY];
3686 if (icon_info)
3687 {
3688 CtkAllocation primary;
3689
3690 ctk_css_gadget_get_border_allocation (icon_info->gadget, &primary, NULL((void*)0));
3691 cdk_window_move_resize (icon_info->window,
3692 primary.x, primary.y,
3693 primary.width, primary.height);
3694 }
3695
3696 icon_info = priv->icons[CTK_ENTRY_ICON_SECONDARY];
3697 if (icon_info)
3698 {
3699 CtkAllocation secondary;
3700
3701 ctk_css_gadget_get_border_allocation (icon_info->gadget, &secondary, NULL((void*)0));
3702 cdk_window_move_resize (icon_info->window,
3703 secondary.x, secondary.y,
3704 secondary.width, secondary.height);
3705 }
3706
3707 cdk_window_move_resize (priv->text_area,
3708 priv->text_allocation.x, priv->text_allocation.y,
3709 priv->text_allocation.width, priv->text_allocation.height);
3710}
3711
3712static void
3713ctk_entry_get_text_area_size (CtkEntry *entry,
3714 gint *x,
3715 gint *y,
3716 gint *width,
3717 gint *height)
3718{
3719 CtkEntryPrivate *priv = entry->priv;
3720 CtkAllocation allocation, widget_allocation;
3721 int baseline;
3722
3723 ctk_css_gadget_get_content_allocation (priv->gadget, &allocation, &baseline);
3724 ctk_widget_get_allocation (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, &widget_allocation);
3725
3726 if (x)
3727 *x = allocation.x - widget_allocation.x;
3728
3729 if (y)
3730 *y = allocation.y - widget_allocation.y;
3731
3732 if (width)
3733 *width = allocation.width;
3734
3735 if (height)
3736 *height = allocation.height;
3737
3738 priv->text_baseline = baseline;
3739}
3740
3741static void
3742ctk_entry_get_frame_size (CtkEntry *entry,
3743 gint *x,
3744 gint *y,
3745 gint *width,
3746 gint *height)
3747{
3748 CtkAllocation allocation;
3749
3750 ctk_css_gadget_get_content_allocation (entry->priv->gadget, &allocation, NULL((void*)0));
3751
3752 if (x)
3753 *x = allocation.x;
3754
3755 if (y)
3756 *y = allocation.y;
3757
3758 if (width)
3759 *width = allocation.width;
3760
3761 if (height)
3762 *height = allocation.height;
3763}
3764
3765static G_GNUC_UNUSED__attribute__ ((__unused__)) void
3766get_frame_size (CtkEntry *entry,
3767 gboolean relative_to_window,
3768 gint *x,
3769 gint *y,
3770 gint *width,
3771 gint *height)
3772{
3773 CtkEntryClass *class = CTK_ENTRY_GET_CLASS (entry)((((CtkEntryClass*) (((GTypeInstance*) ((entry)))->g_class
))))
;
3774
3775 g_assert (class->get_frame_size != NULL)do { if (class->get_frame_size != ((void*)0)) ; else g_assertion_message_expr
("Ctk", "ctkentry.c", 3775, ((const char*) (__func__)), "class->get_frame_size != NULL"
); } while (0)
;
3776 class->get_frame_size (entry, x, y, width, height);
3777
3778 if (!relative_to_window)
3779 {
3780 CtkAllocation allocation;
3781
3782 ctk_widget_get_allocation (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, &allocation);
3783
3784 if (x)
3785 *x -= allocation.x;
3786 if (y)
3787 *y -= allocation.y;
3788 }
3789}
3790
3791static void
3792ctk_entry_size_allocate (CtkWidget *widget,
3793 CtkAllocation *allocation)
3794{
3795 CdkRectangle clip;
3796
3797 ctk_widget_set_allocation (widget, allocation);
3798
3799 ctk_css_gadget_allocate (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
->priv->gadget,
3800 allocation,
3801 ctk_widget_get_allocated_baseline (widget),
3802 &clip);
3803
3804 ctk_widget_set_clip (widget, &clip);
3805}
3806
3807static void
3808ctk_entry_allocate (CtkCssGadget *gadget,
3809 const CtkAllocation *allocation,
3810 int baseline,
3811 CtkAllocation *out_clip,
3812 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
3813{
3814 CtkEntry *entry;
3815 CtkWidget *widget;
3816 CtkEntryPrivate *priv;
3817 CtkAllocation widget_allocation;
3818 gint i;
3819
3820 widget = ctk_css_gadget_get_owner (gadget);
3821 entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
3822 priv = entry->priv;
3823
3824 priv->text_baseline = -1;
3825 CTK_ENTRY_GET_CLASS (entry)((((CtkEntryClass*) (((GTypeInstance*) ((entry)))->g_class
))))
->get_text_area_size (entry,
3826 &priv->text_allocation.x,
3827 &priv->text_allocation.y,
3828 &priv->text_allocation.width,
3829 &priv->text_allocation.height);
3830 ctk_widget_get_allocation (widget, &widget_allocation);
3831 priv->text_allocation.x += widget_allocation.x;
3832 priv->text_allocation.y += widget_allocation.y;
3833
3834 out_clip->x = 0;
3835 out_clip->y = 0;
3836 out_clip->width = 0;
3837 out_clip->height = 0;
3838
3839 for (i = 0; i < MAX_ICONS2; i++)
3840 {
3841 EntryIconInfo *icon_info = priv->icons[i];
3842 CtkAllocation icon_alloc;
3843 CdkRectangle clip;
3844 gint dummy, width, height;
3845
3846 if (!icon_info)
3847 continue;
3848
3849 ctk_css_gadget_get_preferred_size (icon_info->gadget,
3850 CTK_ORIENTATION_HORIZONTAL,
3851 -1,
3852 &dummy, &width,
3853 NULL((void*)0), NULL((void*)0));
3854 ctk_css_gadget_get_preferred_size (icon_info->gadget,
3855 CTK_ORIENTATION_VERTICAL,
3856 -1,
3857 &dummy, &height,
3858 NULL((void*)0), NULL((void*)0));
3859
3860 if ((ctk_widget_get_direction (widget) == CTK_TEXT_DIR_RTL && i == CTK_ENTRY_ICON_PRIMARY) ||
3861 (ctk_widget_get_direction (widget) == CTK_TEXT_DIR_LTR && i == CTK_ENTRY_ICON_SECONDARY))
3862 {
3863 icon_alloc.x = priv->text_allocation.x + priv->text_allocation.width - width;
3864 }
3865 else
3866 {
3867 icon_alloc.x = priv->text_allocation.x;
3868 priv->text_allocation.x += width;
3869 }
3870 icon_alloc.y = priv->text_allocation.y + (priv->text_allocation.height - height) / 2;
3871 icon_alloc.width = width;
3872 icon_alloc.height = height;
3873 priv->text_allocation.width -= width;
3874
3875 ctk_css_gadget_allocate (icon_info->gadget,
3876 &icon_alloc,
3877 baseline,
3878 &clip);
3879
3880 cdk_rectangle_union (out_clip, &clip, out_clip);
3881 }
3882
3883 if (priv->progress_gadget && ctk_css_gadget_get_visible (priv->progress_gadget))
3884 {
3885 int extra_width, req_width;
3886 CtkAllocation progress_alloc;
3887 CdkRectangle clip;
3888
3889 ctk_css_gadget_get_preferred_size (priv->progress_gadget,
3890 CTK_ORIENTATION_HORIZONTAL,
3891 allocation->height,
3892 &req_width, NULL((void*)0),
3893 NULL((void*)0), NULL((void*)0));
3894 extra_width = allocation->width - req_width;
3895
3896 progress_alloc = *allocation;
3897
3898 if (priv->progress_pulse_mode)
3899 {
3900 gdouble value = priv->progress_pulse_current;
3901
3902 progress_alloc.x += (gint) floor (value * extra_width);
3903 progress_alloc.width = req_width + (gint) ceil (priv->progress_pulse_fraction * extra_width);
3904 }
3905 else
3906 {
3907 gdouble value = priv->progress_fraction;
3908
3909 progress_alloc.width = req_width + (gint) nearbyint (value * extra_width);
3910 if (ctk_widget_get_direction (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
) == CTK_TEXT_DIR_RTL)
3911 progress_alloc.x += allocation->width - progress_alloc.width;
3912 }
3913
3914 ctk_css_gadget_allocate (priv->progress_gadget, &progress_alloc, baseline, &clip);
3915
3916 cdk_rectangle_union (out_clip, &clip, out_clip);
3917 }
3918
3919 /* Do this here instead of ctk_entry_size_allocate() so it works
3920 * inside spinbuttons, which don't chain up.
3921 */
3922 if (ctk_widget_get_realized (widget))
3923 {
3924 CtkEntryCompletion *completion;
3925
3926 place_windows (entry);
3927 ctk_entry_recompute (entry);
3928
3929 completion = ctk_entry_get_completion (entry);
3930 if (completion)
3931 _ctk_entry_completion_resize_popup (completion);
3932 }
3933}
3934
3935static gboolean
3936should_prelight (CtkEntry *entry,
3937 CtkEntryIconPosition icon_pos)
3938{
3939 CtkEntryPrivate *priv = entry->priv;
3940 EntryIconInfo *icon_info = priv->icons[icon_pos];
3941
3942 if (!icon_info)
3943 return FALSE(0);
3944
3945 if (icon_info->nonactivatable && icon_info->target_list == NULL((void*)0))
3946 return FALSE(0);
3947
3948 if (icon_info->pressed)
3949 return FALSE(0);
3950
3951 return TRUE(!(0));
3952}
3953
3954static gboolean
3955ctk_entry_draw (CtkWidget *widget,
3956 cairo_t *cr)
3957{
3958 ctk_css_gadget_draw (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
->priv->gadget, cr);
3959
3960 return CDK_EVENT_PROPAGATE((0));
3961}
3962
3963#define UNDERSHOOT_SIZE20 20
3964
3965static void
3966ctk_entry_draw_undershoot (CtkEntry *entry,
3967 cairo_t *cr)
3968{
3969 CtkEntryPrivate *priv = entry->priv;
3970 CtkStyleContext *context;
3971 gint min_offset, max_offset;
3972 CtkAllocation allocation;
3973 CdkRectangle rect;
3974 gboolean rtl;
3975
3976 context = ctk_widget_get_style_context (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
3977 rtl = ctk_widget_get_direction (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
) == CTK_TEXT_DIR_RTL;
3978
3979 ctk_entry_get_scroll_limits (entry, &min_offset, &max_offset);
3980
3981 ctk_css_gadget_get_content_allocation (priv->gadget, &rect, NULL((void*)0));
3982 ctk_widget_get_allocation (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, &allocation);
3983 rect.x -= allocation.x;
3984 rect.y -= allocation.y;
3985
3986 if (priv->scroll_offset > min_offset)
3987 {
3988 int icon_width = 0;
3989 int icon_idx = rtl ? 1 : 0;
3990 if (priv->icons[icon_idx] != NULL((void*)0))
3991 {
3992 ctk_css_gadget_get_preferred_size (priv->icons[icon_idx]->gadget,
3993 CTK_ORIENTATION_HORIZONTAL,
3994 -1,
3995 &icon_width, NULL((void*)0),
3996 NULL((void*)0), NULL((void*)0));
3997 }
3998
3999 ctk_style_context_save_to_node (context, priv->undershoot_node[0]);
4000 ctk_render_background (context, cr, rect.x + icon_width - 1, rect.y, UNDERSHOOT_SIZE20, rect.height);
4001 ctk_render_frame (context, cr, rect.x + icon_width - 1, rect.y, UNDERSHOOT_SIZE20, rect.height);
4002 ctk_style_context_restore (context);
4003 }
4004
4005 if (priv->scroll_offset < max_offset)
4006 {
4007 int icon_width = 0;
4008 int icon_idx = rtl ? 0 : 1;
4009 if (priv->icons[icon_idx] != NULL((void*)0))
4010 {
4011 ctk_css_gadget_get_preferred_size (priv->icons[icon_idx]->gadget,
4012 CTK_ORIENTATION_HORIZONTAL,
4013 -1,
4014 &icon_width, NULL((void*)0),
4015 NULL((void*)0), NULL((void*)0));
4016 }
4017 ctk_style_context_save_to_node (context, priv->undershoot_node[1]);
4018 ctk_render_background (context, cr, rect.x + rect.width - UNDERSHOOT_SIZE20 - icon_width + 1, rect.y, UNDERSHOOT_SIZE20, rect.height);
4019 ctk_render_frame (context, cr, rect.x + rect.width - UNDERSHOOT_SIZE20 - icon_width + 1, rect.y, UNDERSHOOT_SIZE20, rect.height);
4020 ctk_style_context_restore (context);
4021 }
4022}
4023
4024static gboolean
4025ctk_entry_render (CtkCssGadget *gadget,
4026 cairo_t *cr,
4027 int x G_GNUC_UNUSED__attribute__ ((__unused__)),
4028 int y G_GNUC_UNUSED__attribute__ ((__unused__)),
4029 int width G_GNUC_UNUSED__attribute__ ((__unused__)),
4030 int height G_GNUC_UNUSED__attribute__ ((__unused__)),
4031 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
4032{
4033 CtkWidget *widget;
4034 CtkEntry *entry;
4035 CtkEntryPrivate *priv;
4036 int i;
4037
4038 widget = ctk_css_gadget_get_owner (gadget);
4039 entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
4040 priv = entry->priv;
4041
4042 /* Draw progress */
4043 if (priv->progress_gadget && ctk_css_gadget_get_visible (priv->progress_gadget))
4044 ctk_css_gadget_draw (priv->progress_gadget, cr);
4045
4046 /* Draw text and cursor */
4047 cairo_save (cr);
4048
4049 if (priv->dnd_position != -1)
4050 ctk_entry_draw_cursor (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
, cr, CURSOR_DND);
4051
4052 ctk_entry_draw_text (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
, cr);
4053
4054 /* When no text is being displayed at all, don't show the cursor */
4055 if (ctk_entry_get_display_mode (entry) != DISPLAY_BLANK &&
4056 ctk_widget_has_focus (widget) &&
4057 priv->selection_bound == priv->current_pos && priv->cursor_visible)
4058 ctk_entry_draw_cursor (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
, cr, CURSOR_STANDARD);
4059
4060 cairo_restore (cr);
4061
4062 /* Draw icons */
4063 for (i = 0; i < MAX_ICONS2; i++)
4064 {
4065 EntryIconInfo *icon_info = priv->icons[i];
4066
4067 if (icon_info != NULL((void*)0))
4068 ctk_css_gadget_draw (icon_info->gadget, cr);
4069 }
4070
4071 ctk_entry_draw_undershoot (entry, cr);
4072
4073 return FALSE(0);
4074}
4075
4076static gint
4077ctk_entry_enter_notify (CtkWidget *widget,
4078 CdkEventCrossing *event)
4079{
4080 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
4081 CtkEntryPrivate *priv = entry->priv;
4082 gint i;
4083
4084 for (i = 0; i < MAX_ICONS2; i++)
4085 {
4086 EntryIconInfo *icon_info = priv->icons[i];
4087
4088 if (icon_info != NULL((void*)0) && event->window == icon_info->window)
4089 {
4090 if (should_prelight (entry, i))
4091 {
4092 icon_info->prelight = TRUE(!(0));
4093 update_icon_state (widget, i);
4094 ctk_widget_queue_draw (widget);
4095 }
4096
4097 break;
4098 }
4099 }
4100
4101 return CDK_EVENT_PROPAGATE((0));
4102}
4103
4104static gint
4105ctk_entry_leave_notify (CtkWidget *widget,
4106 CdkEventCrossing *event)
4107{
4108 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
4109 CtkEntryPrivate *priv = entry->priv;
4110 gint i;
4111
4112 for (i = 0; i < MAX_ICONS2; i++)
4113 {
4114 EntryIconInfo *icon_info = priv->icons[i];
4115
4116 if (icon_info != NULL((void*)0) && event->window == icon_info->window)
4117 {
4118 /* a grab means that we may never see the button release */
4119 if (event->mode == CDK_CROSSING_GRAB || event->mode == CDK_CROSSING_CTK_GRAB)
4120 icon_info->pressed = FALSE(0);
4121
4122 if (should_prelight (entry, i))
4123 {
4124 icon_info->prelight = FALSE(0);
4125 update_icon_state (widget, i);
4126 ctk_widget_queue_draw (widget);
4127 }
4128
4129 break;
4130 }
4131 }
4132
4133 return CDK_EVENT_PROPAGATE((0));
4134}
4135
4136static void
4137ctk_entry_get_pixel_ranges (CtkEntry *entry,
4138 gint **ranges,
4139 gint *n_ranges)
4140{
4141 gint start_char, end_char;
4142
4143 if (ctk_editable_get_selection_bounds (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, &start_char, &end_char)
)
16
Assuming the condition is false
17
Taking false branch
4144 {
4145 PangoLayout *layout = ctk_entry_ensure_layout (entry, TRUE(!(0)));
4146 PangoLayoutLine *line = pango_layout_get_lines_readonly (layout)->data;
4147 const char *text = pango_layout_get_text (layout);
4148 gint start_index = g_utf8_offset_to_pointer (text, start_char) - text;
4149 gint end_index = g_utf8_offset_to_pointer (text, end_char) - text;
4150 gint real_n_ranges, i;
4151
4152 pango_layout_line_get_x_ranges (line, start_index, end_index, ranges, &real_n_ranges);
4153
4154 if (ranges)
4155 {
4156 gint *r = *ranges;
4157
4158 for (i = 0; i < real_n_ranges; ++i)
4159 {
4160 r[2 * i + 1] = (r[2 * i + 1] - r[2 * i]) / PANGO_SCALE1024;
4161 r[2 * i] = r[2 * i] / PANGO_SCALE1024;
4162 }
4163 }
4164
4165 if (n_ranges)
4166 *n_ranges = real_n_ranges;
4167 }
4168 else
4169 {
4170 if (n_ranges
17.1
'n_ranges' is non-null
)
18
Taking true branch
4171 *n_ranges = 0;
4172 if (ranges
18.1
'ranges' is non-null
)
19
Taking true branch
4173 *ranges = NULL((void*)0);
20
Null pointer value stored to 'ranges'
4174 }
4175}
4176
4177static gboolean
4178in_selection (CtkEntry *entry,
4179 gint x)
4180{
4181 gint *ranges;
4182 gint n_ranges, i;
4183 gint retval = FALSE(0);
4184
4185 ctk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
4186
4187 for (i = 0; i < n_ranges; ++i)
4188 {
4189 if (x >= ranges[2 * i] && x < ranges[2 * i] + ranges[2 * i + 1])
4190 {
4191 retval = TRUE(!(0));
4192 break;
4193 }
4194 }
4195
4196 g_free (ranges);
4197 return retval;
4198}
4199
4200static void
4201ctk_entry_move_handle (CtkEntry *entry,
4202 CtkTextHandlePosition pos,
4203 gint x,
4204 gint y,
4205 gint height)
4206{
4207 CtkEntryPrivate *priv = entry->priv;
4208
4209 if (!_ctk_text_handle_get_is_dragged (priv->text_handle, pos) &&
4210 (x < 0 || x > priv->text_allocation.width))
4211 {
4212 /* Hide the handle if it's not being manipulated
4213 * and fell outside of the visible text area.
4214 */
4215 _ctk_text_handle_set_visible (priv->text_handle, pos, FALSE(0));
4216 }
4217 else
4218 {
4219 CtkAllocation allocation;
4220 CdkRectangle rect;
4221
4222 ctk_widget_get_allocation (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, &allocation);
4223 rect.x = x + priv->text_allocation.x - allocation.x;
4224 rect.y = y + priv->text_allocation.y - allocation.y;
4225 rect.width = 1;
4226 rect.height = height;
4227
4228 _ctk_text_handle_set_visible (priv->text_handle, pos, TRUE(!(0)));
4229 _ctk_text_handle_set_position (priv->text_handle, pos, &rect);
4230 _ctk_text_handle_set_direction (priv->text_handle, pos, priv->resolved_dir);
4231 }
4232}
4233
4234static gint
4235ctk_entry_get_selection_bound_location (CtkEntry *entry)
4236{
4237 CtkEntryPrivate *priv = entry->priv;
4238 PangoLayout *layout;
4239 PangoRectangle pos;
4240 gint x;
4241 const gchar *text;
4242 gint index;
4243
4244 layout = ctk_entry_ensure_layout (entry, FALSE(0));
4245 text = pango_layout_get_text (layout);
4246 index = g_utf8_offset_to_pointer (text, priv->selection_bound) - text;
4247 pango_layout_index_to_pos (layout, index, &pos);
4248
4249 if (ctk_widget_get_direction (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
) == CTK_TEXT_DIR_RTL)
4250 x = (pos.x + pos.width) / PANGO_SCALE1024;
4251 else
4252 x = pos.x / PANGO_SCALE1024;
4253
4254 return x;
4255}
4256
4257static void
4258ctk_entry_update_handles (CtkEntry *entry,
4259 CtkTextHandleMode mode)
4260{
4261 CtkEntryPrivate *priv = entry->priv;
4262 gint strong_x, height;
4263 gint cursor, bound;
4264
4265 _ctk_text_handle_set_mode (priv->text_handle, mode);
4266
4267 height = cdk_window_get_height (priv->text_area);
4268
4269 ctk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, NULL((void*)0));
4270 cursor = strong_x - priv->scroll_offset;
4271
4272 if (mode == CTK_TEXT_HANDLE_MODE_SELECTION)
4273 {
4274 gint start, end;
4275
4276 bound = ctk_entry_get_selection_bound_location (entry) - priv->scroll_offset;
4277
4278 if (priv->selection_bound > priv->current_pos)
4279 {
4280 start = cursor;
4281 end = bound;
4282 }
4283 else
4284 {
4285 start = bound;
4286 end = cursor;
4287 }
4288
4289 /* Update start selection bound */
4290 ctk_entry_move_handle (entry, CTK_TEXT_HANDLE_POSITION_SELECTION_START,
4291 start, 0, height);
4292 ctk_entry_move_handle (entry, CTK_TEXT_HANDLE_POSITION_SELECTION_END,
4293 end, 0, height);
4294 }
4295 else
4296 ctk_entry_move_handle (entry, CTK_TEXT_HANDLE_POSITION_CURSOR,
4297 cursor, 0, height);
4298}
4299
4300static gboolean
4301ctk_entry_event (CtkWidget *widget,
4302 CdkEvent *event)
4303{
4304 CtkEntryPrivate *priv = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
->priv;
4305 EntryIconInfo *icon_info = NULL((void*)0);
4306 CdkEventSequence *sequence;
4307 CdkDevice *device;
4308 gdouble x, y;
4309 gint i;
4310
4311 if (event->type == CDK_MOTION_NOTIFY &&
4312 priv->mouse_cursor_obscured &&
4313 event->any.window == priv->text_area)
4314 {
4315 CdkCursor *cursor;
4316
4317 cursor = cdk_cursor_new_from_name (ctk_widget_get_display (widget), "text");
4318 cdk_window_set_cursor (priv->text_area, cursor);
4319 g_object_unref (cursor);
4320 priv->mouse_cursor_obscured = FALSE(0);
4321 return CDK_EVENT_PROPAGATE((0));
4322 }
4323
4324 for (i = 0; i < MAX_ICONS2; i++)
4325 {
4326 if (priv->icons[i] &&
4327 event->any.window != NULL((void*)0) &&
4328 priv->icons[i]->window == event->any.window)
4329 {
4330 icon_info = priv->icons[i];
4331 break;
4332 }
4333 }
4334
4335 if (!icon_info)
4336 return CDK_EVENT_PROPAGATE((0));
4337
4338 if (icon_info->insensitive)
4339 return CDK_EVENT_STOP((!(0)));
4340
4341 sequence = cdk_event_get_event_sequence (event);
4342 device = cdk_event_get_device (event);
4343 cdk_event_get_coords (event, &x, &y);
4344
4345 switch (event->type)
4346 {
4347 case CDK_TOUCH_BEGIN:
4348 if (icon_info->current_sequence)
4349 break;
4350
4351 icon_info->current_sequence = sequence;
4352 /* Fall through */
4353 case CDK_BUTTON_PRESS:
4354 case CDK_2BUTTON_PRESS:
4355 case CDK_3BUTTON_PRESS:
4356 if (should_prelight (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
, i))
4357 {
4358 icon_info->prelight = FALSE(0);
4359 update_icon_state (widget, i);
4360 ctk_widget_queue_draw (widget);
4361 }
4362
4363 priv->start_x = x;
4364 priv->start_y = y;
4365 icon_info->pressed = TRUE(!(0));
4366 icon_info->device = device;
4367
4368 if (!icon_info->nonactivatable)
4369 g_signal_emit (widget, signals[ICON_PRESS], 0, i, event);
4370
4371 break;
4372 case CDK_TOUCH_UPDATE:
4373 if (icon_info->device != device ||
4374 icon_info->current_sequence != sequence)
4375 break;
4376 /* Fall through */
4377 case CDK_MOTION_NOTIFY:
4378 if (icon_info->pressed &&
4379 icon_info->target_list != NULL((void*)0) &&
4380 ctk_drag_check_threshold (widget,
4381 priv->start_x,
4382 priv->start_y,
4383 x, y))
4384 {
4385 icon_info->in_drag = TRUE(!(0));
4386 ctk_drag_begin_with_coordinates (widget,
4387 icon_info->target_list,
4388 icon_info->actions,
4389 1,
4390 event,
4391 priv->start_x,
4392 priv->start_y);
4393 }
4394
4395 break;
4396 case CDK_TOUCH_END:
4397 if (icon_info->device != device ||
4398 icon_info->current_sequence != sequence)
4399 break;
4400
4401 icon_info->current_sequence = NULL((void*)0);
4402 /* Fall through */
4403 case CDK_BUTTON_RELEASE:
4404 icon_info->pressed = FALSE(0);
4405 icon_info->device = NULL((void*)0);
4406
4407 if (should_prelight (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
, i) &&
4408 x >= 0 && y >= 0 &&
4409 x < cdk_window_get_width (icon_info->window) &&
4410 y < cdk_window_get_height (icon_info->window))
4411 {
4412 icon_info->prelight = TRUE(!(0));
4413 update_icon_state (widget, i);
4414 ctk_widget_queue_draw (widget);
4415 }
4416
4417 if (!icon_info->nonactivatable)
4418 g_signal_emit (widget, signals[ICON_RELEASE], 0, i, event);
4419
4420 break;
4421 default:
4422 return CDK_EVENT_PROPAGATE((0));
4423 }
4424
4425 return CDK_EVENT_STOP((!(0)));
4426}
4427
4428static void
4429gesture_get_current_point_in_layout (CtkGestureSingle *gesture,
4430 CtkEntry *entry,
4431 gint *x,
4432 gint *y)
4433{
4434 gint tx, ty;
4435 CdkEventSequence *sequence;
4436 gdouble px, py;
4437
4438 sequence = ctk_gesture_single_get_current_sequence (gesture);
4439 ctk_gesture_get_point (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
, sequence, &px, &py);
4440 ctk_entry_get_layout_offsets (entry, &tx, &ty);
4441
4442 if (x)
4443 *x = px - tx;
4444 if (y)
4445 *y = py - ty;
4446}
4447
4448static void
4449ctk_entry_multipress_gesture_pressed (CtkGestureMultiPress *gesture,
4450 gint n_press,
4451 gdouble widget_x G_GNUC_UNUSED__attribute__ ((__unused__)),
4452 gdouble widget_y G_GNUC_UNUSED__attribute__ ((__unused__)),
4453 CtkEntry *entry)
4454{
4455 CtkEditable *editable = CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
;
4456 CtkWidget *widget = CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
;
4457 CtkEntryPrivate *priv = entry->priv;
4458 CdkEventSequence *current;
4459 const CdkEvent *event;
4460 gint x, y, sel_start, sel_end;
4461 guint button;
4462 gint tmp_pos;
4463
4464 button = ctk_gesture_single_get_current_button (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type ()
))))))
);
4465 current = ctk_gesture_single_get_current_sequence (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type ()
))))))
);
4466 event = ctk_gesture_get_last_event (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
, current);
4467
4468 ctk_gesture_set_sequence_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
, current,
4469 CTK_EVENT_SEQUENCE_CLAIMED);
4470 gesture_get_current_point_in_layout (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type ()
))))))
, entry, &x, &y);
4471 ctk_entry_reset_blink_time (entry);
4472
4473 if (!ctk_widget_has_focus (widget))
4474 {
4475 priv->in_click = TRUE(!(0));
4476 ctk_widget_grab_focus (widget);
4477 priv->in_click = FALSE(0);
4478 }
4479
4480 tmp_pos = ctk_entry_find_position (entry, x);
4481
4482 if (cdk_event_triggers_context_menu (event))
4483 {
4484 ctk_entry_do_popup (entry, event);
4485 }
4486 else if (n_press == 1 && button == CDK_BUTTON_MIDDLE(2) &&
4487 get_middle_click_paste (entry))
4488 {
4489 if (priv->editable)
4490 {
4491 priv->insert_pos = tmp_pos;
4492 ctk_entry_paste (entry, CDK_SELECTION_PRIMARY((CdkAtom)((gpointer) (gulong) (1))));
4493 }
4494 else
4495 {
4496 ctk_widget_error_bell (widget);
4497 }
4498 }
4499 else if (button == CDK_BUTTON_PRIMARY(1))
4500 {
4501 gboolean have_selection = ctk_editable_get_selection_bounds (editable, &sel_start, &sel_end);
4502 CtkTextHandleMode mode;
4503 gboolean is_touchscreen, extend_selection;
4504 CdkDevice *source;
4505
4506 source = cdk_event_get_source_device (event);
4507 is_touchscreen = ctk_simulate_touchscreen () ||
4508 cdk_device_get_source (source) == CDK_SOURCE_TOUCHSCREEN;
4509
4510 if (!is_touchscreen)
4511 mode = CTK_TEXT_HANDLE_MODE_NONE;
4512 else if (have_selection)
4513 mode = CTK_TEXT_HANDLE_MODE_SELECTION;
4514 else
4515 mode = CTK_TEXT_HANDLE_MODE_CURSOR;
4516
4517 if (is_touchscreen)
4518 ctk_entry_ensure_text_handles (entry);
4519
4520 priv->in_drag = FALSE(0);
4521 priv->select_words = FALSE(0);
4522 priv->select_lines = FALSE(0);
4523
4524 extend_selection =
4525 (event->button.state &
4526 ctk_widget_get_modifier_mask (widget,
4527 CDK_MODIFIER_INTENT_EXTEND_SELECTION));
4528
4529 if (extend_selection)
4530 ctk_entry_reset_im_context (entry);
4531
4532 switch (n_press)
4533 {
4534 case 1:
4535 if (in_selection (entry, x))
4536 {
4537 if (is_touchscreen)
4538 {
4539 if (entry->priv->selection_bubble &&
4540 ctk_widget_get_visible (entry->priv->selection_bubble))
4541 ctk_entry_selection_bubble_popup_unset (entry);
4542 else
4543 ctk_entry_selection_bubble_popup_set (entry);
4544 }
4545 else if (extend_selection)
4546 {
4547 /* Truncate current selection, but keep it as big as possible */
4548 if (tmp_pos - sel_start > sel_end - tmp_pos)
4549 ctk_entry_set_positions (entry, sel_start, tmp_pos);
4550 else
4551 ctk_entry_set_positions (entry, tmp_pos, sel_end);
4552
4553 /* all done, so skip the extend_to_left stuff later */
4554 extend_selection = FALSE(0);
4555 }
4556 else
4557 {
4558 /* We'll either start a drag, or clear the selection */
4559 priv->in_drag = TRUE(!(0));
4560 priv->drag_start_x = x;
4561 priv->drag_start_y = y;
4562 }
4563 }
4564 else
4565 {
4566 ctk_entry_selection_bubble_popup_unset (entry);
4567
4568 if (!extend_selection)
4569 {
4570 ctk_editable_set_position (editable, tmp_pos);
4571 priv->handle_place_time = g_get_monotonic_time ();
4572 }
4573 else
4574 {
4575 /* select from the current position to the clicked position */
4576 if (!have_selection)
4577 sel_start = sel_end = priv->current_pos;
4578
4579 ctk_entry_set_positions (entry, tmp_pos, tmp_pos);
4580 }
4581 }
4582
4583 break;
4584
4585 case 2:
4586 priv->select_words = TRUE(!(0));
4587 ctk_entry_select_word (entry);
4588 if (is_touchscreen)
4589 mode = CTK_TEXT_HANDLE_MODE_SELECTION;
4590 break;
4591
4592 case 3:
4593 priv->select_lines = TRUE(!(0));
4594 ctk_entry_select_line (entry);
4595 if (is_touchscreen)
4596 mode = CTK_TEXT_HANDLE_MODE_SELECTION;
4597 break;
4598
4599 default:
4600 break;
4601 }
4602
4603 if (extend_selection)
4604 {
4605 gboolean extend_to_left;
4606 gint start, end;
4607
4608 start = MIN (priv->current_pos, priv->selection_bound)(((priv->current_pos) < (priv->selection_bound)) ? (
priv->current_pos) : (priv->selection_bound))
;
4609 start = MIN (sel_start, start)(((sel_start) < (start)) ? (sel_start) : (start));
4610
4611 end = MAX (priv->current_pos, priv->selection_bound)(((priv->current_pos) > (priv->selection_bound)) ? (
priv->current_pos) : (priv->selection_bound))
;
4612 end = MAX (sel_end, end)(((sel_end) > (end)) ? (sel_end) : (end));
4613
4614 if (tmp_pos == sel_start || tmp_pos == sel_end)
4615 extend_to_left = (tmp_pos == start);
4616 else
4617 extend_to_left = (end == sel_end);
4618
4619 if (extend_to_left)
4620 ctk_entry_set_positions (entry, start, end);
4621 else
4622 ctk_entry_set_positions (entry, end, start);
4623 }
4624
4625 ctk_gesture_set_state (priv->drag_gesture,
4626 CTK_EVENT_SEQUENCE_CLAIMED);
4627
4628 if (priv->text_handle)
4629 ctk_entry_update_handles (entry, mode);
4630 }
4631
4632 if (n_press >= 3)
4633 ctk_event_controller_reset (CTK_EVENT_CONTROLLER (gesture)((((CtkEventController*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((gesture)), ((ctk_event_controller_get_type
()))))))
);
4634}
4635
4636static gchar *
4637_ctk_entry_get_selected_text (CtkEntry *entry)
4638{
4639 CtkEditable *editable = CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
;
4640 gint start_text, end_text;
4641 gchar *text = NULL((void*)0);
4642
4643 if (ctk_editable_get_selection_bounds (editable, &start_text, &end_text))
9
Assuming the condition is true
10
Taking true branch
4644 text = ctk_editable_get_chars (editable, start_text, end_text);
4645
4646 return text;
11
Returning pointer (loaded from 'text'), which participates in a condition later
4647}
4648
4649static void
4650ctk_entry_show_magnifier (CtkEntry *entry,
4651 gint x,
4652 gint y G_GNUC_UNUSED__attribute__ ((__unused__)))
4653{
4654 CtkAllocation allocation;
4655 cairo_rectangle_int_t rect;
4656 CtkEntryPrivate *priv;
4657
4658 ctk_entry_ensure_magnifier (entry);
4659
4660 ctk_widget_get_allocation (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, &allocation);
4661
4662 priv = entry->priv;
4663 rect.x = x + priv->text_allocation.x - allocation.x;
4664 rect.width = 1;
4665 rect.y = priv->text_allocation.y - allocation.y;
4666 rect.height = priv->text_allocation.height;
4667
4668 _ctk_magnifier_set_coords (CTK_MAGNIFIER (priv->magnifier)((((CtkMagnifier*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->magnifier)), ((_ctk_magnifier_get_type ()))))))
, rect.x,
4669 rect.y + rect.height / 2);
4670 rect.x = CLAMP (rect.x, 0, allocation.width)(((rect.x) > (allocation.width)) ? (allocation.width) : ((
(rect.x) < (0)) ? (0) : (rect.x)))
;
4671 ctk_popover_set_pointing_to (CTK_POPOVER (priv->magnifier_popover)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->magnifier_popover)), ((ctk_popover_get_type ())
)))))
,
4672 &rect);
4673 ctk_popover_popup (CTK_POPOVER (priv->magnifier_popover)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->magnifier_popover)), ((ctk_popover_get_type ())
)))))
);
4674}
4675
4676static void
4677ctk_entry_drag_gesture_update (CtkGestureDrag *gesture,
4678 gdouble offset_x G_GNUC_UNUSED__attribute__ ((__unused__)),
4679 gdouble offset_y G_GNUC_UNUSED__attribute__ ((__unused__)),
4680 CtkEntry *entry)
4681{
4682 CtkWidget *widget = CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
;
4683 CtkEntryPrivate *priv = entry->priv;
4684 CdkEventSequence *sequence;
4685 const CdkEvent *event;
4686 gint x, y;
4687
4688 ctk_entry_selection_bubble_popup_unset (entry);
4689
4690 gesture_get_current_point_in_layout (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type ()
))))))
, entry, &x, &y);
4691 sequence = ctk_gesture_single_get_current_sequence (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type ()
))))))
);
4692 event = ctk_gesture_get_last_event (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
, sequence);
4693
4694 if (priv->mouse_cursor_obscured)
4695 {
4696 CdkCursor *cursor;
4697
4698 cursor = cdk_cursor_new_from_name (ctk_widget_get_display (widget), "text");
4699 cdk_window_set_cursor (priv->text_area, cursor);
4700 g_object_unref (cursor);
4701 priv->mouse_cursor_obscured = FALSE(0);
4702 }
4703
4704 if (priv->select_lines)
4705 return;
4706
4707 if (priv->in_drag)
4708 {
4709 if (ctk_entry_get_display_mode (entry) == DISPLAY_NORMAL &&
4710 ctk_drag_check_threshold (widget,
4711 priv->drag_start_x, priv->drag_start_y,
4712 x, y))
4713 {
4714 gint *ranges;
4715 gint n_ranges;
4716 CtkTargetList *target_list = ctk_target_list_new (NULL((void*)0), 0);
4717 guint actions = priv->editable ? CDK_ACTION_COPY | CDK_ACTION_MOVE : CDK_ACTION_COPY;
4718 guint button;
4719
4720 ctk_target_list_add_text_targets (target_list, 0);
4721
4722 ctk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
4723
4724 button = ctk_gesture_single_get_current_button (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type ()
))))))
);
4725 ctk_drag_begin_with_coordinates (widget, target_list, actions,
4726 button, (CdkEvent*) event,
4727 priv->drag_start_x + ranges[0],
4728 priv->drag_start_y);
4729 g_free (ranges);
4730
4731 priv->in_drag = FALSE(0);
4732
4733 ctk_target_list_unref (target_list);
4734 }
4735 }
4736 else
4737 {
4738 CdkInputSource input_source;
4739 CdkDevice *source;
4740 guint length;
4741 gint tmp_pos;
4742
4743 length = ctk_entry_buffer_get_length (get_buffer (entry));
4744
4745 if (y < 0)
4746 tmp_pos = 0;
4747 else if (y >= cdk_window_get_height (priv->text_area))
4748 tmp_pos = length;
4749 else
4750 tmp_pos = ctk_entry_find_position (entry, x);
4751
4752 source = cdk_event_get_source_device (event);
4753 input_source = cdk_device_get_source (source);
4754
4755 if (priv->select_words)
4756 {
4757 gint min, max;
4758 gint old_min, old_max;
4759 gint pos, bound;
4760
4761 min = ctk_entry_move_backward_word (entry, tmp_pos, TRUE(!(0)));
4762 max = ctk_entry_move_forward_word (entry, tmp_pos, TRUE(!(0)));
4763
4764 pos = priv->current_pos;
4765 bound = priv->selection_bound;
4766
4767 old_min = MIN (priv->current_pos, priv->selection_bound)(((priv->current_pos) < (priv->selection_bound)) ? (
priv->current_pos) : (priv->selection_bound))
;
4768 old_max = MAX (priv->current_pos, priv->selection_bound)(((priv->current_pos) > (priv->selection_bound)) ? (
priv->current_pos) : (priv->selection_bound))
;
4769
4770 if (min < old_min)
4771 {
4772 pos = min;
4773 bound = old_max;
4774 }
4775 else if (old_max < max)
4776 {
4777 pos = max;
4778 bound = old_min;
4779 }
4780 else if (pos == old_min)
4781 {
4782 if (priv->current_pos != min)
4783 pos = max;
4784 }
4785 else
4786 {
4787 if (priv->current_pos != max)
4788 pos = min;
4789 }
4790
4791 ctk_entry_set_positions (entry, pos, bound);
4792 }
4793 else
4794 ctk_entry_set_positions (entry, tmp_pos, -1);
4795
4796 /* Update touch handles' position */
4797 if (ctk_simulate_touchscreen () ||
4798 input_source == CDK_SOURCE_TOUCHSCREEN)
4799 {
4800 ctk_entry_ensure_text_handles (entry);
4801 ctk_entry_update_handles (entry,
4802 (priv->current_pos == priv->selection_bound) ?
4803 CTK_TEXT_HANDLE_MODE_CURSOR :
4804 CTK_TEXT_HANDLE_MODE_SELECTION);
4805 ctk_entry_show_magnifier (entry, x - priv->scroll_offset, y);
4806 }
4807 }
4808}
4809
4810static void
4811ctk_entry_drag_gesture_end (CtkGestureDrag *gesture,
4812 gdouble offset_x G_GNUC_UNUSED__attribute__ ((__unused__)),
4813 gdouble offset_y G_GNUC_UNUSED__attribute__ ((__unused__)),
4814 CtkEntry *entry)
4815{
4816 CtkEntryPrivate *priv = entry->priv;
4817 gboolean in_drag, is_touchscreen;
4818 CdkEventSequence *sequence;
4819 const CdkEvent *event;
4820 CdkDevice *source;
4821
4822 sequence = ctk_gesture_single_get_current_sequence (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type ()
))))))
);
4823 in_drag = priv->in_drag;
4824 priv->in_drag = FALSE(0);
4825
4826 if (priv->magnifier_popover)
4827 ctk_popover_popdown (CTK_POPOVER (priv->magnifier_popover)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->magnifier_popover)), ((ctk_popover_get_type ())
)))))
);
4828
4829 /* Check whether the drag was cancelled rather than finished */
4830 if (!ctk_gesture_handles_sequence (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
, sequence))
4831 return;
4832
4833 event = ctk_gesture_get_last_event (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
, sequence);
4834 source = cdk_event_get_source_device (event);
4835 is_touchscreen = ctk_simulate_touchscreen () ||
4836 cdk_device_get_source (source) == CDK_SOURCE_TOUCHSCREEN;
4837
4838 if (in_drag)
4839 {
4840 gint tmp_pos = ctk_entry_find_position (entry, priv->drag_start_x);
4841
4842 ctk_editable_set_position (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, tmp_pos);
4843 }
4844
4845 if (is_touchscreen &&
4846 !ctk_editable_get_selection_bounds (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, NULL((void*)0), NULL((void*)0)))
4847 ctk_entry_update_handles (entry, CTK_TEXT_HANDLE_MODE_CURSOR);
4848
4849 ctk_entry_update_primary_selection (entry);
4850}
4851
4852static void
4853set_invisible_cursor (CdkWindow *window)
4854{
4855 CdkCursor *cursor;
4856
4857 cursor = cdk_cursor_new_from_name (cdk_window_get_display (window), "none");
4858 cdk_window_set_cursor (window, cursor);
4859 g_object_unref (cursor);
4860}
4861
4862static void
4863ctk_entry_obscure_mouse_cursor (CtkEntry *entry)
4864{
4865 CtkEntryPrivate *priv = entry->priv;
4866
4867 if (priv->mouse_cursor_obscured)
4868 return;
4869
4870 if (priv->text_area)
4871 {
4872 set_invisible_cursor (priv->text_area);
4873 priv->mouse_cursor_obscured = TRUE(!(0));
4874 }
4875}
4876
4877static gint
4878ctk_entry_key_press (CtkWidget *widget,
4879 CdkEventKey *event)
4880{
4881 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
4882 CtkEntryPrivate *priv = entry->priv;
4883 gboolean retval = FALSE(0);
4884
4885 priv->handling_key_event = TRUE(!(0));
4886
4887 ctk_entry_reset_blink_time (entry);
4888 ctk_entry_pend_cursor_blink (entry);
4889
4890 ctk_entry_selection_bubble_popup_unset (entry);
4891
4892 if (!event->send_event && priv->text_handle)
4893 _ctk_text_handle_set_mode (priv->text_handle,
4894 CTK_TEXT_HANDLE_MODE_NONE);
4895
4896 if (priv->editable)
4897 {
4898 if (ctk_im_context_filter_keypress (priv->im_context, event))
4899 {
4900 priv->need_im_reset = TRUE(!(0));
4901 retval = TRUE(!(0));
4902 goto out;
4903 }
4904 }
4905
4906 if (event->keyval == CDK_KEY_Return0xff0d ||
4907 event->keyval == CDK_KEY_KP_Enter0xff8d ||
4908 event->keyval == CDK_KEY_ISO_Enter0xfe34 ||
4909 event->keyval == CDK_KEY_Escape0xff1b)
4910 ctk_entry_reset_im_context (entry);
4911
4912 if (CTK_WIDGET_CLASS (ctk_entry_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_entry_parent_class)), ((ctk_widget_get_type ()))))))
->key_press_event (widget, event))
4913 {
4914 /* Activate key bindings */
4915 retval = TRUE(!(0));
4916 goto out;
4917 }
4918
4919 if (!priv->editable && event->length)
4920 ctk_widget_error_bell (widget);
4921
4922out:
4923 priv->handling_key_event = FALSE(0);
4924
4925 return retval;
4926}
4927
4928static gint
4929ctk_entry_key_release (CtkWidget *widget,
4930 CdkEventKey *event)
4931{
4932 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
4933 CtkEntryPrivate *priv = entry->priv;
4934 gboolean retval = FALSE(0);
4935
4936 priv->handling_key_event = TRUE(!(0));
4937
4938 if (priv->editable)
4939 {
4940 if (ctk_im_context_filter_keypress (priv->im_context, event))
4941 {
4942 priv->need_im_reset = TRUE(!(0));
4943 retval = TRUE(!(0));
4944 goto out;
4945 }
4946 }
4947
4948 retval = CTK_WIDGET_CLASS (ctk_entry_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_entry_parent_class)), ((ctk_widget_get_type ()))))))
->key_release_event (widget, event);
4949
4950out:
4951 priv->handling_key_event = FALSE(0);
4952 return retval;
4953}
4954
4955static gint
4956ctk_entry_focus_in (CtkWidget *widget,
4957 CdkEventFocus *event G_GNUC_UNUSED__attribute__ ((__unused__)))
4958{
4959 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
4960 CtkEntryPrivate *priv = entry->priv;
4961 CdkKeymap *keymap;
4962
4963 ctk_widget_queue_draw (widget);
4964
4965 keymap = cdk_keymap_get_for_display (ctk_widget_get_display (widget));
4966
4967 if (priv->editable)
4968 {
4969 priv->need_im_reset = TRUE(!(0));
4970 ctk_im_context_focus_in (priv->im_context);
4971 keymap_state_changed (keymap, entry);
4972 g_signal_connect (keymap, "state-changed",g_signal_connect_data ((keymap), ("state-changed"), (((GCallback
) (keymap_state_changed))), (entry), ((void*)0), (GConnectFlags
) 0)
4973 G_CALLBACK (keymap_state_changed), entry)g_signal_connect_data ((keymap), ("state-changed"), (((GCallback
) (keymap_state_changed))), (entry), ((void*)0), (GConnectFlags
) 0)
;
4974 }
4975
4976 g_signal_connect (keymap, "direction-changed",g_signal_connect_data ((keymap), ("direction-changed"), (((GCallback
) (keymap_direction_changed))), (entry), ((void*)0), (GConnectFlags
) 0)
4977 G_CALLBACK (keymap_direction_changed), entry)g_signal_connect_data ((keymap), ("direction-changed"), (((GCallback
) (keymap_direction_changed))), (entry), ((void*)0), (GConnectFlags
) 0)
;
4978
4979 if (ctk_entry_buffer_get_bytes (get_buffer (entry)) == 0 &&
4980 priv->placeholder_text != NULL((void*)0))
4981 {
4982 ctk_entry_recompute (entry);
4983 }
4984 else
4985 {
4986 ctk_entry_reset_blink_time (entry);
4987 ctk_entry_check_cursor_blink (entry);
4988 }
4989
4990 return CDK_EVENT_PROPAGATE((0));
4991}
4992
4993static gint
4994ctk_entry_focus_out (CtkWidget *widget,
4995 CdkEventFocus *event G_GNUC_UNUSED__attribute__ ((__unused__)))
4996{
4997 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
4998 CtkEntryPrivate *priv = entry->priv;
4999 CtkEntryCompletion *completion;
5000 CdkKeymap *keymap;
5001
5002 ctk_entry_selection_bubble_popup_unset (entry);
5003
5004 if (priv->text_handle)
5005 _ctk_text_handle_set_mode (priv->text_handle,
5006 CTK_TEXT_HANDLE_MODE_NONE);
5007
5008 ctk_widget_queue_draw (widget);
5009
5010 keymap = cdk_keymap_get_for_display (ctk_widget_get_display (widget));
5011
5012 if (priv->editable)
5013 {
5014 priv->need_im_reset = TRUE(!(0));
5015 ctk_im_context_focus_out (priv->im_context);
5016 remove_capslock_feedback (entry);
5017 }
5018
5019 if (ctk_entry_buffer_get_bytes (get_buffer (entry)) == 0 &&
5020 priv->placeholder_text != NULL((void*)0))
5021 {
5022 ctk_entry_recompute (entry);
5023 }
5024 else
5025 {
5026 ctk_entry_check_cursor_blink (entry);
5027 }
5028
5029 g_signal_handlers_disconnect_by_func (keymap, keymap_state_changed, entry)g_signal_handlers_disconnect_matched ((keymap), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (keymap_state_changed), (entry))
;
5030 g_signal_handlers_disconnect_by_func (keymap, keymap_direction_changed, entry)g_signal_handlers_disconnect_matched ((keymap), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (keymap_direction_changed), (entry))
;
5031
5032 completion = ctk_entry_get_completion (entry);
5033 if (completion)
5034 _ctk_entry_completion_popdown (completion);
5035
5036 return CDK_EVENT_PROPAGATE((0));
5037}
5038
5039void
5040_ctk_entry_grab_focus (CtkEntry *entry,
5041 gboolean select_all)
5042{
5043 if (!ctk_widget_get_can_focus (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
5044 return;
5045
5046 if (!ctk_widget_is_sensitive (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
5047 return;
5048
5049 CTK_WIDGET_CLASS (ctk_entry_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_entry_parent_class)), ((ctk_widget_get_type ()))))))
->grab_focus (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
5050
5051 if (select_all)
5052 ctk_editable_select_region (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, 0, -1);
5053}
5054
5055static void
5056ctk_entry_grab_focus (CtkWidget *widget)
5057{
5058 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
5059 CtkEntryPrivate *priv = entry->priv;
5060 gboolean select_on_focus;
5061
5062 if (priv->editable && !priv->in_click)
5063 {
5064 g_object_get (ctk_widget_get_settings (widget),
5065 "ctk-entry-select-on-focus",
5066 &select_on_focus,
5067 NULL((void*)0));
5068
5069 _ctk_entry_grab_focus (entry, select_on_focus);
5070 }
5071 else
5072 {
5073 _ctk_entry_grab_focus (entry, FALSE(0));
5074 }
5075}
5076
5077/**
5078 * ctk_entry_grab_focus_without_selecting:
5079 * @entry: a #CtkEntry
5080 *
5081 * Causes @entry to have keyboard focus.
5082 *
5083 * It behaves like ctk_widget_grab_focus(),
5084 * except that it doesn't select the contents of the entry.
5085 * You only want to call this on some special entries
5086 * which the user usually doesn't want to replace all text in,
5087 * such as search-as-you-type entries.
5088 *
5089 * Since: 3.16
5090 */
5091void
5092ctk_entry_grab_focus_without_selecting (CtkEntry *entry)
5093{
5094 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
5095
5096 _ctk_entry_grab_focus (entry, FALSE(0));
5097}
5098
5099static void
5100ctk_entry_direction_changed (CtkWidget *widget,
5101 CtkTextDirection previous_dir)
5102{
5103 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
5104
5105 ctk_entry_recompute (entry);
5106
5107 update_icon_style (widget, CTK_ENTRY_ICON_PRIMARY);
5108 update_icon_style (widget, CTK_ENTRY_ICON_SECONDARY);
5109
5110 update_node_ordering (entry);
5111
5112 CTK_WIDGET_CLASS (ctk_entry_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_entry_parent_class)), ((ctk_widget_get_type ()))))))
->direction_changed (widget, previous_dir);
5113}
5114
5115static void
5116ctk_entry_state_flags_changed (CtkWidget *widget,
5117 CtkStateFlags previous_state G_GNUC_UNUSED__attribute__ ((__unused__)))
5118{
5119 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
5120 CtkEntryPrivate *priv = entry->priv;
5121 CdkCursor *cursor;
5122
5123 if (ctk_widget_get_realized (widget))
5124 {
5125 if (ctk_widget_is_sensitive (widget))
5126 cursor = cdk_cursor_new_from_name (ctk_widget_get_display (widget), "text");
5127 else
5128 cursor = NULL((void*)0);
5129
5130 cdk_window_set_cursor (priv->text_area, cursor);
5131
5132 if (cursor)
5133 g_object_unref (cursor);
5134
5135 priv->mouse_cursor_obscured = FALSE(0);
5136
5137 update_cursors (widget);
5138 }
5139
5140 if (!ctk_widget_is_sensitive (widget))
5141 {
5142 /* Clear any selection */
5143 ctk_editable_select_region (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, priv->current_pos, priv->current_pos);
5144 }
5145
5146 update_node_state (entry);
5147 update_icon_state (widget, CTK_ENTRY_ICON_PRIMARY);
5148 update_icon_state (widget, CTK_ENTRY_ICON_SECONDARY);
5149
5150 ctk_entry_update_cached_style_values (entry);
5151}
5152
5153static void
5154ctk_entry_screen_changed (CtkWidget *widget,
5155 CdkScreen *old_screen G_GNUC_UNUSED__attribute__ ((__unused__)))
5156{
5157 ctk_entry_recompute (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
);
5158}
5159
5160/* CtkEditable method implementations
5161 */
5162static void
5163ctk_entry_insert_text (CtkEditable *editable,
5164 const gchar *new_text,
5165 gint new_text_length,
5166 gint *position)
5167{
5168 g_object_ref (editable)((__typeof__ (editable)) (g_object_ref) (editable));
5169
5170 /*
5171 * The incoming text may a password or other secret. We make sure
5172 * not to copy it into temporary buffers.
5173 */
5174
5175 g_signal_emit_by_name (editable, "insert-text", new_text, new_text_length, position);
5176
5177 g_object_unref (editable);
5178}
5179
5180static void
5181ctk_entry_delete_text (CtkEditable *editable,
5182 gint start_pos,
5183 gint end_pos)
5184{
5185 g_object_ref (editable)((__typeof__ (editable)) (g_object_ref) (editable));
5186
5187 g_signal_emit_by_name (editable, "delete-text", start_pos, end_pos);
5188
5189 g_object_unref (editable);
5190}
5191
5192static gchar *
5193ctk_entry_get_chars (CtkEditable *editable,
5194 gint start_pos,
5195 gint end_pos)
5196{
5197 CtkEntry *entry = CTK_ENTRY (editable)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((editable)), ((ctk_entry_get_type ()))))))
;
5198 const gchar *text;
5199 gint text_length;
5200 gint start_index, end_index;
5201
5202 text = ctk_entry_buffer_get_text (get_buffer (entry));
5203 text_length = ctk_entry_buffer_get_length (get_buffer (entry));
5204
5205 if (end_pos < 0)
5206 end_pos = text_length;
5207
5208 start_pos = MIN (text_length, start_pos)(((text_length) < (start_pos)) ? (text_length) : (start_pos
))
;
5209 end_pos = MIN (text_length, end_pos)(((text_length) < (end_pos)) ? (text_length) : (end_pos));
5210
5211 start_index = g_utf8_offset_to_pointer (text, start_pos) - text;
5212 end_index = g_utf8_offset_to_pointer (text, end_pos) - text;
5213
5214 return g_strndup (text + start_index, end_index - start_index);
5215}
5216
5217static void
5218ctk_entry_real_set_position (CtkEditable *editable,
5219 gint position)
5220{
5221 CtkEntry *entry = CTK_ENTRY (editable)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((editable)), ((ctk_entry_get_type ()))))))
;
5222 CtkEntryPrivate *priv = entry->priv;
5223
5224 guint length;
5225
5226 length = ctk_entry_buffer_get_length (get_buffer (entry));
5227 if (position < 0 || position > length)
5228 position = length;
5229
5230 if (position != priv->current_pos ||
5231 position != priv->selection_bound)
5232 {
5233 ctk_entry_reset_im_context (entry);
5234 ctk_entry_set_positions (entry, position, position);
5235 }
5236}
5237
5238static gint
5239ctk_entry_get_position (CtkEditable *editable)
5240{
5241 CtkEntry *entry = CTK_ENTRY (editable)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((editable)), ((ctk_entry_get_type ()))))))
;
5242 CtkEntryPrivate *priv = entry->priv;
5243
5244 return priv->current_pos;
5245}
5246
5247static void
5248ctk_entry_set_selection_bounds (CtkEditable *editable,
5249 gint start,
5250 gint end)
5251{
5252 CtkEntry *entry = CTK_ENTRY (editable)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((editable)), ((ctk_entry_get_type ()))))))
;
5253 guint length;
5254
5255 length = ctk_entry_buffer_get_length (get_buffer (entry));
5256 if (start < 0)
5257 start = length;
5258 if (end < 0)
5259 end = length;
5260
5261 ctk_entry_reset_im_context (entry);
5262
5263 ctk_entry_set_positions (entry,
5264 MIN (end, length)(((end) < (length)) ? (end) : (length)),
5265 MIN (start, length)(((start) < (length)) ? (start) : (length)));
5266
5267 ctk_entry_update_primary_selection (entry);
5268}
5269
5270static gboolean
5271ctk_entry_get_selection_bounds (CtkEditable *editable,
5272 gint *start,
5273 gint *end)
5274{
5275 CtkEntry *entry = CTK_ENTRY (editable)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((editable)), ((ctk_entry_get_type ()))))))
;
5276 CtkEntryPrivate *priv = entry->priv;
5277
5278 *start = priv->selection_bound;
5279 *end = priv->current_pos;
5280
5281 return (priv->selection_bound != priv->current_pos);
5282}
5283
5284static void
5285ctk_entry_update_cached_style_values (CtkEntry *entry)
5286{
5287 CtkEntryPrivate *priv = entry->priv;
5288
5289 if (!priv->invisible_char_set)
5290 {
5291 gunichar ch = find_invisible_char (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
5292
5293 if (priv->invisible_char != ch)
5294 {
5295 priv->invisible_char = ch;
5296 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_INVISIBLE_CHAR]);
5297 }
5298 }
5299}
5300
5301static void
5302ctk_entry_style_updated (CtkWidget *widget)
5303{
5304 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
5305
5306 CTK_WIDGET_CLASS (ctk_entry_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_entry_parent_class)), ((ctk_widget_get_type ()))))))
->style_updated (widget);
5307
5308 ctk_entry_update_cached_style_values (entry);
5309}
5310
5311/* CtkCellEditable method implementations
5312 */
5313static void
5314ctk_cell_editable_entry_activated (CtkEntry *entry,
5315 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
5316{
5317 ctk_cell_editable_editing_done (CTK_CELL_EDITABLE (entry)((((CtkCellEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_cell_editable_get_type ()))))))
);
5318 ctk_cell_editable_remove_widget (CTK_CELL_EDITABLE (entry)((((CtkCellEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_cell_editable_get_type ()))))))
);
5319}
5320
5321static gboolean
5322ctk_cell_editable_key_press_event (CtkEntry *entry,
5323 CdkEventKey *key_event,
5324 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
5325{
5326 CtkEntryPrivate *priv = entry->priv;
5327
5328 if (key_event->keyval == CDK_KEY_Escape0xff1b)
5329 {
5330 priv->editing_canceled = TRUE(!(0));
5331 ctk_cell_editable_editing_done (CTK_CELL_EDITABLE (entry)((((CtkCellEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_cell_editable_get_type ()))))))
);
5332 ctk_cell_editable_remove_widget (CTK_CELL_EDITABLE (entry)((((CtkCellEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_cell_editable_get_type ()))))))
);
5333
5334 return CDK_EVENT_STOP((!(0)));
5335 }
5336
5337 /* override focus */
5338 if (key_event->keyval == CDK_KEY_Up0xff52 || key_event->keyval == CDK_KEY_Down0xff54)
5339 {
5340 ctk_cell_editable_editing_done (CTK_CELL_EDITABLE (entry)((((CtkCellEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_cell_editable_get_type ()))))))
);
5341 ctk_cell_editable_remove_widget (CTK_CELL_EDITABLE (entry)((((CtkCellEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_cell_editable_get_type ()))))))
);
5342
5343 return CDK_EVENT_STOP((!(0)));
5344 }
5345
5346 return CDK_EVENT_PROPAGATE((0));
5347}
5348
5349static void
5350ctk_entry_start_editing (CtkCellEditable *cell_editable,
5351 CdkEvent *event G_GNUC_UNUSED__attribute__ ((__unused__)))
5352{
5353 g_signal_connect (cell_editable, "activate",g_signal_connect_data ((cell_editable), ("activate"), (((GCallback
) (ctk_cell_editable_entry_activated))), (((void*)0)), ((void
*)0), (GConnectFlags) 0)
5354 G_CALLBACK (ctk_cell_editable_entry_activated), NULL)g_signal_connect_data ((cell_editable), ("activate"), (((GCallback
) (ctk_cell_editable_entry_activated))), (((void*)0)), ((void
*)0), (GConnectFlags) 0)
;
5355 g_signal_connect (cell_editable, "key-press-event",g_signal_connect_data ((cell_editable), ("key-press-event"), (
((GCallback) (ctk_cell_editable_key_press_event))), (((void*)
0)), ((void*)0), (GConnectFlags) 0)
5356 G_CALLBACK (ctk_cell_editable_key_press_event), NULL)g_signal_connect_data ((cell_editable), ("key-press-event"), (
((GCallback) (ctk_cell_editable_key_press_event))), (((void*)
0)), ((void*)0), (GConnectFlags) 0)
;
5357}
5358
5359static void
5360ctk_entry_password_hint_free (CtkEntryPasswordHint *password_hint)
5361{
5362 if (password_hint->source_id)
5363 g_source_remove (password_hint->source_id);
5364
5365 g_slice_free (CtkEntryPasswordHint, password_hint)do { if (1) g_slice_free1 (sizeof (CtkEntryPasswordHint), (password_hint
)); else (void) ((CtkEntryPasswordHint*) 0 == (password_hint)
); } while (0)
;
5366}
5367
5368
5369static gboolean
5370ctk_entry_remove_password_hint (gpointer data)
5371{
5372 CtkEntryPasswordHint *password_hint = g_object_get_qdata (data, quark_password_hint);
5373 password_hint->position = -1;
5374
5375 /* Force the string to be redrawn, but now without a visible character */
5376 ctk_entry_recompute (CTK_ENTRY (data)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((ctk_entry_get_type ()))))))
);
5377 return G_SOURCE_REMOVE(0);
5378}
5379
5380/* Default signal handlers
5381 */
5382static void
5383ctk_entry_real_insert_text (CtkEditable *editable,
5384 const gchar *new_text,
5385 gint new_text_length,
5386 gint *position)
5387{
5388 guint n_inserted;
5389 gint n_chars;
5390
5391 n_chars = g_utf8_strlen (new_text, new_text_length);
5392
5393 /*
5394 * The actual insertion into the buffer. This will end up firing the
5395 * following signal handlers: buffer_inserted_text(), buffer_notify_display_text(),
5396 * buffer_notify_text(), buffer_notify_length()
5397 */
5398 begin_change (CTK_ENTRY (editable)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((editable)), ((ctk_entry_get_type ()))))))
);
5399
5400 n_inserted = ctk_entry_buffer_insert_text (get_buffer (CTK_ENTRY (editable)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((editable)), ((ctk_entry_get_type ()))))))
), *position, new_text, n_chars);
5401
5402 end_change (CTK_ENTRY (editable)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((editable)), ((ctk_entry_get_type ()))))))
);
5403
5404 if (n_inserted != n_chars)
5405 ctk_widget_error_bell (CTK_WIDGET (editable)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((editable)), ((ctk_widget_get_type ()))))))
);
5406
5407 *position += n_inserted;
5408}
5409
5410static void
5411ctk_entry_real_delete_text (CtkEditable *editable,
5412 gint start_pos,
5413 gint end_pos)
5414{
5415 /*
5416 * The actual deletion from the buffer. This will end up firing the
5417 * following signal handlers: buffer_deleted_text(), buffer_notify_display_text(),
5418 * buffer_notify_text(), buffer_notify_length()
5419 */
5420
5421 begin_change (CTK_ENTRY (editable)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((editable)), ((ctk_entry_get_type ()))))))
);
5422
5423 ctk_entry_buffer_delete_text (get_buffer (CTK_ENTRY (editable)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((editable)), ((ctk_entry_get_type ()))))))
), start_pos, end_pos - start_pos);
5424
5425 end_change (CTK_ENTRY (editable)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((editable)), ((ctk_entry_get_type ()))))))
);
5426}
5427
5428/* CtkEntryBuffer signal handlers
5429 */
5430static void
5431buffer_inserted_text (CtkEntryBuffer *buffer G_GNUC_UNUSED__attribute__ ((__unused__)),
5432 guint position,
5433 const gchar *chars G_GNUC_UNUSED__attribute__ ((__unused__)),
5434 guint n_chars,
5435 CtkEntry *entry)
5436{
5437 CtkEntryPrivate *priv = entry->priv;
5438 guint password_hint_timeout;
5439 guint current_pos;
5440 gint selection_bound;
5441
5442 current_pos = priv->current_pos;
5443 if (current_pos > position)
5444 current_pos += n_chars;
5445
5446 selection_bound = priv->selection_bound;
5447 if (selection_bound > position)
5448 selection_bound += n_chars;
5449
5450 ctk_entry_set_positions (entry, current_pos, selection_bound);
5451 ctk_entry_recompute (entry);
5452
5453 /* Calculate the password hint if it needs to be displayed. */
5454 if (n_chars == 1 && !priv->visible)
5455 {
5456 g_object_get (ctk_widget_get_settings (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
),
5457 "ctk-entry-password-hint-timeout", &password_hint_timeout,
5458 NULL((void*)0));
5459
5460 if (password_hint_timeout > 0)
5461 {
5462 CtkEntryPasswordHint *password_hint = g_object_get_qdata (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
,
5463 quark_password_hint);
5464 if (!password_hint)
5465 {
5466 password_hint = g_slice_new0 (CtkEntryPasswordHint)((CtkEntryPasswordHint*) g_slice_alloc0 (sizeof (CtkEntryPasswordHint
)))
;
5467 g_object_set_qdata_full (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, quark_password_hint, password_hint,
5468 (GDestroyNotify)ctk_entry_password_hint_free);
5469 }
5470
5471 password_hint->position = position;
5472 if (password_hint->source_id)
5473 g_source_remove (password_hint->source_id);
5474 password_hint->source_id = cdk_threads_add_timeout (password_hint_timeout,
5475 (GSourceFunc)ctk_entry_remove_password_hint, entry);
5476 g_source_set_name_by_id (password_hint->source_id, "[ctk+] ctk_entry_remove_password_hint");
5477 }
5478 }
5479}
5480
5481static void
5482buffer_deleted_text (CtkEntryBuffer *buffer G_GNUC_UNUSED__attribute__ ((__unused__)),
5483 guint position,
5484 guint n_chars,
5485 CtkEntry *entry)
5486{
5487 CtkEntryPrivate *priv = entry->priv;
5488 guint end_pos = position + n_chars;
5489 gint selection_bound;
5490 guint current_pos;
5491
5492 current_pos = priv->current_pos;
5493 if (current_pos > position)
5494 current_pos -= MIN (current_pos, end_pos)(((current_pos) < (end_pos)) ? (current_pos) : (end_pos)) - position;
5495
5496 selection_bound = priv->selection_bound;
5497 if (selection_bound > position)
5498 selection_bound -= MIN (selection_bound, end_pos)(((selection_bound) < (end_pos)) ? (selection_bound) : (end_pos
))
- position;
5499
5500 ctk_entry_set_positions (entry, current_pos, selection_bound);
5501 ctk_entry_recompute (entry);
5502
5503 /* We might have deleted the selection */
5504 ctk_entry_update_primary_selection (entry);
5505
5506 /* Disable the password hint if one exists. */
5507 if (!priv->visible)
5508 {
5509 CtkEntryPasswordHint *password_hint = g_object_get_qdata (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
,
5510 quark_password_hint);
5511 if (password_hint)
5512 {
5513 if (password_hint->source_id)
5514 g_source_remove (password_hint->source_id);
5515 password_hint->source_id = 0;
5516 password_hint->position = -1;
5517 }
5518 }
5519}
5520
5521static void
5522buffer_notify_text (CtkEntryBuffer *buffer G_GNUC_UNUSED__attribute__ ((__unused__)),
5523 GParamSpec *spec G_GNUC_UNUSED__attribute__ ((__unused__)),
5524 CtkEntry *entry)
5525{
5526 if (entry->priv->handling_key_event)
5527 ctk_entry_obscure_mouse_cursor (entry);
5528
5529 emit_changed (entry);
5530 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_TEXT]);
5531}
5532
5533static void
5534buffer_notify_length (CtkEntryBuffer *buffer G_GNUC_UNUSED__attribute__ ((__unused__)),
5535 GParamSpec *spec G_GNUC_UNUSED__attribute__ ((__unused__)),
5536 CtkEntry *entry)
5537{
5538 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_TEXT_LENGTH]);
5539}
5540
5541static void
5542buffer_notify_max_length (CtkEntryBuffer *buffer G_GNUC_UNUSED__attribute__ ((__unused__)),
5543 GParamSpec *spec G_GNUC_UNUSED__attribute__ ((__unused__)),
5544 CtkEntry *entry)
5545{
5546 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_MAX_LENGTH]);
5547}
5548
5549static void
5550buffer_connect_signals (CtkEntry *entry)
5551{
5552 g_signal_connect (get_buffer (entry), "inserted-text", G_CALLBACK (buffer_inserted_text), entry)g_signal_connect_data ((get_buffer (entry)), ("inserted-text"
), (((GCallback) (buffer_inserted_text))), (entry), ((void*)0
), (GConnectFlags) 0)
;
5553 g_signal_connect (get_buffer (entry), "deleted-text", G_CALLBACK (buffer_deleted_text), entry)g_signal_connect_data ((get_buffer (entry)), ("deleted-text")
, (((GCallback) (buffer_deleted_text))), (entry), ((void*)0),
(GConnectFlags) 0)
;
5554 g_signal_connect (get_buffer (entry), "notify::text", G_CALLBACK (buffer_notify_text), entry)g_signal_connect_data ((get_buffer (entry)), ("notify::text")
, (((GCallback) (buffer_notify_text))), (entry), ((void*)0), (
GConnectFlags) 0)
;
5555 g_signal_connect (get_buffer (entry), "notify::length", G_CALLBACK (buffer_notify_length), entry)g_signal_connect_data ((get_buffer (entry)), ("notify::length"
), (((GCallback) (buffer_notify_length))), (entry), ((void*)0
), (GConnectFlags) 0)
;
5556 g_signal_connect (get_buffer (entry), "notify::max-length", G_CALLBACK (buffer_notify_max_length), entry)g_signal_connect_data ((get_buffer (entry)), ("notify::max-length"
), (((GCallback) (buffer_notify_max_length))), (entry), ((void
*)0), (GConnectFlags) 0)
;
5557}
5558
5559static void
5560buffer_disconnect_signals (CtkEntry *entry)
5561{
5562 g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_inserted_text, entry)g_signal_handlers_disconnect_matched ((get_buffer (entry)), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (buffer_inserted_text), (entry))
;
5563 g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_deleted_text, entry)g_signal_handlers_disconnect_matched ((get_buffer (entry)), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (buffer_deleted_text), (entry))
;
5564 g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_notify_text, entry)g_signal_handlers_disconnect_matched ((get_buffer (entry)), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (buffer_notify_text), (entry))
;
5565 g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_notify_length, entry)g_signal_handlers_disconnect_matched ((get_buffer (entry)), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (buffer_notify_length), (entry))
;
5566 g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_notify_max_length, entry)g_signal_handlers_disconnect_matched ((get_buffer (entry)), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (buffer_notify_max_length), (entry))
;
5567}
5568
5569/* Compute the X position for an offset that corresponds to the "more important
5570 * cursor position for that offset. We use this when trying to guess to which
5571 * end of the selection we should go to when the user hits the left or
5572 * right arrow key.
5573 */
5574static gint
5575get_better_cursor_x (CtkEntry *entry,
5576 gint offset)
5577{
5578 CtkEntryPrivate *priv = entry->priv;
5579 CdkKeymap *keymap = cdk_keymap_get_for_display (ctk_widget_get_display (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
));
5580 PangoDirection keymap_direction = cdk_keymap_get_direction (keymap);
5581 gboolean split_cursor;
5582
5583 PangoLayout *layout = ctk_entry_ensure_layout (entry, TRUE(!(0)));
5584 const gchar *text = pango_layout_get_text (layout);
5585 gint index = g_utf8_offset_to_pointer (text, offset) - text;
5586
5587 PangoRectangle strong_pos, weak_pos;
5588
5589 g_object_get (ctk_widget_get_settings (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
),
5590 "ctk-split-cursor", &split_cursor,
5591 NULL((void*)0));
5592
5593 pango_layout_get_cursor_pos (layout, index, &strong_pos, &weak_pos);
5594
5595 if (split_cursor)
5596 return strong_pos.x / PANGO_SCALE1024;
5597 else
5598 return (keymap_direction == priv->resolved_dir) ? strong_pos.x / PANGO_SCALE1024 : weak_pos.x / PANGO_SCALE1024;
5599}
5600
5601static void
5602ctk_entry_move_cursor (CtkEntry *entry,
5603 CtkMovementStep step,
5604 gint count,
5605 gboolean extend_selection)
5606{
5607 CtkEntryPrivate *priv = entry->priv;
5608 gint new_pos = priv->current_pos;
5609
5610 ctk_entry_reset_im_context (entry);
5611
5612 if (priv->current_pos != priv->selection_bound && !extend_selection)
5613 {
5614 /* If we have a current selection and aren't extending it, move to the
5615 * start/or end of the selection as appropriate
5616 */
5617 switch (step)
5618 {
5619 case CTK_MOVEMENT_VISUAL_POSITIONS:
5620 {
5621 gint current_x = get_better_cursor_x (entry, priv->current_pos);
5622 gint bound_x = get_better_cursor_x (entry, priv->selection_bound);
5623
5624 if (count <= 0)
5625 new_pos = current_x < bound_x ? priv->current_pos : priv->selection_bound;
5626 else
5627 new_pos = current_x > bound_x ? priv->current_pos : priv->selection_bound;
5628 }
5629 break;
5630
5631 case CTK_MOVEMENT_WORDS:
5632 if (priv->resolved_dir == PANGO_DIRECTION_RTL)
5633 count *= -1;
5634 /* Fall through */
5635
5636 case CTK_MOVEMENT_LOGICAL_POSITIONS:
5637 if (count < 0)
5638 new_pos = MIN (priv->current_pos, priv->selection_bound)(((priv->current_pos) < (priv->selection_bound)) ? (
priv->current_pos) : (priv->selection_bound))
;
5639 else
5640 new_pos = MAX (priv->current_pos, priv->selection_bound)(((priv->current_pos) > (priv->selection_bound)) ? (
priv->current_pos) : (priv->selection_bound))
;
5641
5642 break;
5643
5644 case CTK_MOVEMENT_DISPLAY_LINE_ENDS:
5645 case CTK_MOVEMENT_PARAGRAPH_ENDS:
5646 case CTK_MOVEMENT_BUFFER_ENDS:
5647 new_pos = count < 0 ? 0 : ctk_entry_buffer_get_length (get_buffer (entry));
5648 break;
5649
5650 case CTK_MOVEMENT_DISPLAY_LINES:
5651 case CTK_MOVEMENT_PARAGRAPHS:
5652 case CTK_MOVEMENT_PAGES:
5653 case CTK_MOVEMENT_HORIZONTAL_PAGES:
5654 break;
5655 }
5656 }
5657 else
5658 {
5659 switch (step)
5660 {
5661 case CTK_MOVEMENT_LOGICAL_POSITIONS:
5662 new_pos = ctk_entry_move_logically (entry, new_pos, count);
5663 break;
5664
5665 case CTK_MOVEMENT_VISUAL_POSITIONS:
5666 new_pos = ctk_entry_move_visually (entry, new_pos, count);
5667
5668 if (priv->current_pos == new_pos)
5669 {
5670 if (!extend_selection)
5671 {
5672 if (!ctk_widget_keynav_failed (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
,
5673 count > 0 ?
5674 CTK_DIR_RIGHT : CTK_DIR_LEFT))
5675 {
5676 CtkWidget *toplevel = ctk_widget_get_toplevel (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
5677
5678 if (toplevel)
5679 ctk_widget_child_focus (toplevel,
5680 count > 0 ?
5681 CTK_DIR_RIGHT : CTK_DIR_LEFT);
5682 }
5683 }
5684 else
5685 {
5686 ctk_widget_error_bell (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
5687 }
5688 }
5689 break;
5690
5691 case CTK_MOVEMENT_WORDS:
5692 if (priv->resolved_dir == PANGO_DIRECTION_RTL)
5693 count *= -1;
5694
5695 while (count > 0)
5696 {
5697 new_pos = ctk_entry_move_forward_word (entry, new_pos, FALSE(0));
5698 count--;
5699 }
5700
5701 while (count < 0)
5702 {
5703 new_pos = ctk_entry_move_backward_word (entry, new_pos, FALSE(0));
5704 count++;
5705 }
5706
5707 if (priv->current_pos == new_pos)
5708 ctk_widget_error_bell (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
5709
5710 break;
5711
5712 case CTK_MOVEMENT_DISPLAY_LINE_ENDS:
5713 case CTK_MOVEMENT_PARAGRAPH_ENDS:
5714 case CTK_MOVEMENT_BUFFER_ENDS:
5715 new_pos = count < 0 ? 0 : ctk_entry_buffer_get_length (get_buffer (entry));
5716
5717 if (priv->current_pos == new_pos)
5718 ctk_widget_error_bell (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
5719
5720 break;
5721
5722 case CTK_MOVEMENT_DISPLAY_LINES:
5723 case CTK_MOVEMENT_PARAGRAPHS:
5724 case CTK_MOVEMENT_PAGES:
5725 case CTK_MOVEMENT_HORIZONTAL_PAGES:
5726 break;
5727 }
5728 }
5729
5730 if (extend_selection)
5731 ctk_editable_select_region (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, priv->selection_bound, new_pos);
5732 else
5733 ctk_editable_set_position (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, new_pos);
5734
5735 ctk_entry_pend_cursor_blink (entry);
5736}
5737
5738static void
5739ctk_entry_insert_at_cursor (CtkEntry *entry,
5740 const gchar *str)
5741{
5742 CtkEntryPrivate *priv = entry->priv;
5743 CtkEditable *editable = CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
;
5744 gint pos = priv->current_pos;
5745
5746 if (priv->editable)
5747 {
5748 ctk_entry_reset_im_context (entry);
5749 ctk_editable_insert_text (editable, str, -1, &pos);
5750 ctk_editable_set_position (editable, pos);
5751 }
5752}
5753
5754static void
5755ctk_entry_delete_from_cursor (CtkEntry *entry,
5756 CtkDeleteType type,
5757 gint count)
5758{
5759 CtkEntryPrivate *priv = entry->priv;
5760 CtkEditable *editable = CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
;
5761 gint start_pos = priv->current_pos;
5762 gint end_pos = priv->current_pos;
5763 gint old_n_bytes = ctk_entry_buffer_get_bytes (get_buffer (entry));
5764
5765 ctk_entry_reset_im_context (entry);
5766
5767 if (!priv->editable)
5768 {
5769 ctk_widget_error_bell (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
5770 return;
5771 }
5772
5773 if (priv->selection_bound != priv->current_pos)
5774 {
5775 ctk_editable_delete_selection (editable);
5776 return;
5777 }
5778
5779 switch (type)
5780 {
5781 case CTK_DELETE_CHARS:
5782 end_pos = ctk_entry_move_logically (entry, priv->current_pos, count);
5783 ctk_editable_delete_text (editable, MIN (start_pos, end_pos)(((start_pos) < (end_pos)) ? (start_pos) : (end_pos)), MAX (start_pos, end_pos)(((start_pos) > (end_pos)) ? (start_pos) : (end_pos)));
5784 break;
5785
5786 case CTK_DELETE_WORDS:
5787 if (count < 0)
5788 {
5789 /* Move to end of current word, or if not on a word, end of previous word */
5790 end_pos = ctk_entry_move_backward_word (entry, end_pos, FALSE(0));
5791 end_pos = ctk_entry_move_forward_word (entry, end_pos, FALSE(0));
5792 }
5793 else if (count > 0)
5794 {
5795 /* Move to beginning of current word, or if not on a word, begining of next word */
5796 start_pos = ctk_entry_move_forward_word (entry, start_pos, FALSE(0));
5797 start_pos = ctk_entry_move_backward_word (entry, start_pos, FALSE(0));
5798 }
5799
5800 /* Fall through */
5801 case CTK_DELETE_WORD_ENDS:
5802 while (count < 0)
5803 {
5804 start_pos = ctk_entry_move_backward_word (entry, start_pos, FALSE(0));
5805 count++;
5806 }
5807
5808 while (count > 0)
5809 {
5810 end_pos = ctk_entry_move_forward_word (entry, end_pos, FALSE(0));
5811 count--;
5812 }
5813
5814 ctk_editable_delete_text (editable, start_pos, end_pos);
5815 break;
5816
5817 case CTK_DELETE_DISPLAY_LINE_ENDS:
5818 case CTK_DELETE_PARAGRAPH_ENDS:
5819 if (count < 0)
5820 ctk_editable_delete_text (editable, 0, priv->current_pos);
5821 else
5822 ctk_editable_delete_text (editable, priv->current_pos, -1);
5823
5824 break;
5825
5826 case CTK_DELETE_DISPLAY_LINES:
5827 case CTK_DELETE_PARAGRAPHS:
5828 ctk_editable_delete_text (editable, 0, -1);
5829 break;
5830
5831 case CTK_DELETE_WHITESPACE:
5832 ctk_entry_delete_whitespace (entry);
5833 break;
5834 }
5835
5836 if (ctk_entry_buffer_get_bytes (get_buffer (entry)) == old_n_bytes)
5837 ctk_widget_error_bell (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
5838
5839 ctk_entry_pend_cursor_blink (entry);
5840}
5841
5842static void
5843ctk_entry_backspace (CtkEntry *entry)
5844{
5845 CtkEntryPrivate *priv = entry->priv;
5846 CtkEditable *editable = CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
;
5847 gint prev_pos;
5848
5849 ctk_entry_reset_im_context (entry);
5850
5851 if (!priv->editable)
5852 {
5853 ctk_widget_error_bell (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
5854 return;
5855 }
5856
5857 if (priv->selection_bound != priv->current_pos)
5858 {
5859 ctk_editable_delete_selection (editable);
5860 return;
5861 }
5862
5863 prev_pos = ctk_entry_move_logically (entry, priv->current_pos, -1);
5864
5865 if (prev_pos < priv->current_pos)
5866 {
5867 PangoLayout *layout = ctk_entry_ensure_layout (entry, FALSE(0));
5868 PangoLogAttr *log_attrs;
5869 gint n_attrs;
5870
5871 pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
5872
5873 /* Deleting parts of characters */
5874 if (log_attrs[priv->current_pos].backspace_deletes_character)
5875 {
5876 gchar *cluster_text;
5877 gchar *normalized_text;
5878 glong len;
5879
5880 cluster_text = _ctk_entry_get_display_text (entry, prev_pos,
5881 priv->current_pos);
5882 normalized_text = g_utf8_normalize (cluster_text,
5883 strlen (cluster_text),
5884 G_NORMALIZE_NFD);
5885 len = g_utf8_strlen (normalized_text, -1);
5886
5887 ctk_editable_delete_text (editable, prev_pos, priv->current_pos);
5888 if (len > 1)
5889 {
5890 gint pos = priv->current_pos;
5891
5892 ctk_editable_insert_text (editable, normalized_text,
5893 g_utf8_offset_to_pointer (normalized_text, len - 1) - normalized_text,
5894 &pos);
5895 ctk_editable_set_position (editable, pos);
5896 }
5897
5898 g_free (normalized_text);
5899 g_free (cluster_text);
5900 }
5901 else
5902 {
5903 ctk_editable_delete_text (editable, prev_pos, priv->current_pos);
5904 }
5905
5906 g_free (log_attrs);
5907 }
5908 else
5909 {
5910 ctk_widget_error_bell (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
5911 }
5912
5913 ctk_entry_pend_cursor_blink (entry);
5914}
5915
5916static void
5917ctk_entry_copy_clipboard (CtkEntry *entry)
5918{
5919 CtkEntryPrivate *priv = entry->priv;
5920 CtkEditable *editable = CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
;
5921 gint start, end;
5922 gchar *str;
5923
5924 if (ctk_editable_get_selection_bounds (editable, &start, &end))
5925 {
5926 if (!priv->visible)
5927 {
5928 ctk_widget_error_bell (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
5929 return;
5930 }
5931
5932 str = _ctk_entry_get_display_text (entry, start, end);
5933 ctk_clipboard_set_text (ctk_widget_get_clipboard (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
,
5934 CDK_SELECTION_CLIPBOARD((CdkAtom)((gpointer) (gulong) (69)))),
5935 str, -1);
5936 g_free (str);
5937 }
5938}
5939
5940static void
5941ctk_entry_cut_clipboard (CtkEntry *entry)
5942{
5943 CtkEntryPrivate *priv = entry->priv;
5944 CtkEditable *editable = CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
;
5945 gint start, end;
5946
5947 if (!priv->visible)
5948 {
5949 ctk_widget_error_bell (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
5950 return;
5951 }
5952
5953 ctk_entry_copy_clipboard (entry);
5954
5955 if (priv->editable)
5956 {
5957 if (ctk_editable_get_selection_bounds (editable, &start, &end))
5958 ctk_editable_delete_text (editable, start, end);
5959 }
5960 else
5961 {
5962 ctk_widget_error_bell (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
5963 }
5964
5965 ctk_entry_selection_bubble_popup_unset (entry);
5966
5967 if (priv->text_handle)
5968 {
5969 CtkTextHandleMode handle_mode;
5970
5971 handle_mode = _ctk_text_handle_get_mode (priv->text_handle);
5972
5973 if (handle_mode != CTK_TEXT_HANDLE_MODE_NONE)
5974 ctk_entry_update_handles (entry, CTK_TEXT_HANDLE_MODE_CURSOR);
5975 }
5976}
5977
5978static void
5979ctk_entry_paste_clipboard (CtkEntry *entry)
5980{
5981 CtkEntryPrivate *priv = entry->priv;
5982
5983 if (priv->editable)
5984 ctk_entry_paste (entry, CDK_SELECTION_CLIPBOARD((CdkAtom)((gpointer) (gulong) (69))));
5985 else
5986 ctk_widget_error_bell (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
5987
5988 if (priv->text_handle)
5989 {
5990 CtkTextHandleMode handle_mode;
5991
5992 handle_mode = _ctk_text_handle_get_mode (priv->text_handle);
5993
5994 if (handle_mode != CTK_TEXT_HANDLE_MODE_NONE)
5995 ctk_entry_update_handles (entry, CTK_TEXT_HANDLE_MODE_CURSOR);
5996 }
5997}
5998
5999static void
6000ctk_entry_delete_cb (CtkEntry *entry)
6001{
6002 CtkEntryPrivate *priv = entry->priv;
6003 CtkEditable *editable = CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
;
6004 gint start, end;
6005
6006 if (priv->editable)
6007 {
6008 if (ctk_editable_get_selection_bounds (editable, &start, &end))
6009 ctk_editable_delete_text (editable, start, end);
6010 }
6011}
6012
6013static void
6014ctk_entry_toggle_overwrite (CtkEntry *entry)
6015{
6016 CtkEntryPrivate *priv = entry->priv;
6017
6018 priv->overwrite_mode = !priv->overwrite_mode;
6019 ctk_entry_pend_cursor_blink (entry);
6020 ctk_widget_queue_draw (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
6021}
6022
6023static void
6024ctk_entry_select_all (CtkEntry *entry)
6025{
6026 ctk_entry_select_line (entry);
6027}
6028
6029static void
6030ctk_entry_real_activate (CtkEntry *entry)
6031{
6032 CtkEntryPrivate *priv = entry->priv;
6033 CtkWindow *window;
6034 CtkWidget *default_widget, *focus_widget;
6035 CtkWidget *toplevel;
6036 CtkWidget *widget;
6037
6038 widget = CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
;
6039
6040 if (priv->activates_default)
6041 {
6042 toplevel = ctk_widget_get_toplevel (widget);
6043 if (CTK_IS_WINDOW (toplevel)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(toplevel)); GType __t = ((ctk_window_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; }))))
)
6044 {
6045 window = CTK_WINDOW (toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toplevel)), ((ctk_window_get_type ()))))))
;
6046
6047 if (window)
6048 {
6049 default_widget = ctk_window_get_default_widget (window);
6050 focus_widget = ctk_window_get_focus (window);
6051 if (widget != default_widget &&
6052 !(widget == focus_widget && (!default_widget || !ctk_widget_get_sensitive (default_widget))))
6053 ctk_window_activate_default (window);
6054 }
6055 }
6056 }
6057}
6058
6059static void
6060keymap_direction_changed (CdkKeymap *keymap G_GNUC_UNUSED__attribute__ ((__unused__)),
6061 CtkEntry *entry)
6062{
6063 ctk_entry_recompute (entry);
6064}
6065
6066/* IM Context Callbacks
6067 */
6068
6069static void
6070ctk_entry_commit_cb (CtkIMContext *context G_GNUC_UNUSED__attribute__ ((__unused__)),
6071 const gchar *str,
6072 CtkEntry *entry)
6073{
6074 CtkEntryPrivate *priv = entry->priv;
6075
6076 if (priv->editable)
6077 ctk_entry_enter_text (entry, str);
6078}
6079
6080static void
6081ctk_entry_preedit_changed_cb (CtkIMContext *context G_GNUC_UNUSED__attribute__ ((__unused__)),
6082 CtkEntry *entry)
6083{
6084 CtkEntryPrivate *priv = entry->priv;
6085
6086 if (priv->editable)
6087 {
6088 gchar *preedit_string;
6089 gint cursor_pos;
6090
6091 ctk_im_context_get_preedit_string (priv->im_context,
6092 &preedit_string, NULL((void*)0),
6093 &cursor_pos);
6094 g_signal_emit (entry, signals[PREEDIT_CHANGED], 0, preedit_string);
6095 priv->preedit_length = strlen (preedit_string);
6096 cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (preedit_string, -1))(((cursor_pos) > (g_utf8_strlen (preedit_string, -1))) ? (
g_utf8_strlen (preedit_string, -1)) : (((cursor_pos) < (0)
) ? (0) : (cursor_pos)))
;
6097 priv->preedit_cursor = cursor_pos;
6098 g_free (preedit_string);
6099
6100 ctk_entry_recompute (entry);
6101 }
6102}
6103
6104static gboolean
6105ctk_entry_retrieve_surrounding_cb (CtkIMContext *context,
6106 CtkEntry *entry)
6107{
6108 CtkEntryPrivate *priv = entry->priv;
6109 gchar *text;
6110
6111 /* XXXX ??? does this even make sense when text is not visible? Should we return FALSE? */
6112 text = _ctk_entry_get_display_text (entry, 0, -1);
6113 ctk_im_context_set_surrounding (context, text, strlen (text), /* Length in bytes */
6114 g_utf8_offset_to_pointer (text, priv->current_pos) - text);
6115 g_free (text);
6116
6117 return TRUE(!(0));
6118}
6119
6120static gboolean
6121ctk_entry_delete_surrounding_cb (CtkIMContext *slave G_GNUC_UNUSED__attribute__ ((__unused__)),
6122 gint offset,
6123 gint n_chars,
6124 CtkEntry *entry)
6125{
6126 CtkEntryPrivate *priv = entry->priv;
6127
6128 if (priv->editable)
6129 ctk_editable_delete_text (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
,
6130 priv->current_pos + offset,
6131 priv->current_pos + offset + n_chars);
6132
6133 return TRUE(!(0));
6134}
6135
6136/* Internal functions
6137 */
6138
6139/* Used for im_commit_cb and inserting Unicode chars */
6140void
6141ctk_entry_enter_text (CtkEntry *entry,
6142 const gchar *str)
6143{
6144 CtkEntryPrivate *priv = entry->priv;
6145 CtkEditable *editable = CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
;
6146 gint tmp_pos;
6147 gboolean old_need_im_reset;
6148 guint text_length;
6149
6150 old_need_im_reset = priv->need_im_reset;
6151 priv->need_im_reset = FALSE(0);
6152
6153 if (ctk_editable_get_selection_bounds (editable, NULL((void*)0), NULL((void*)0)))
6154 ctk_editable_delete_selection (editable);
6155 else
6156 {
6157 if (priv->overwrite_mode)
6158 {
6159 text_length = ctk_entry_buffer_get_length (get_buffer (entry));
6160 if (priv->current_pos < text_length)
6161 ctk_entry_delete_from_cursor (entry, CTK_DELETE_CHARS, 1);
6162 }
6163 }
6164
6165 tmp_pos = priv->current_pos;
6166 ctk_editable_insert_text (editable, str, strlen (str), &tmp_pos);
6167 ctk_editable_set_position (editable, tmp_pos);
6168
6169 priv->need_im_reset = old_need_im_reset;
6170}
6171
6172/* All changes to priv->current_pos and priv->selection_bound
6173 * should go through this function.
6174 */
6175void
6176ctk_entry_set_positions (CtkEntry *entry,
6177 gint current_pos,
6178 gint selection_bound)
6179{
6180 CtkEntryPrivate *priv = entry->priv;
6181 gboolean changed = FALSE(0);
6182
6183 g_object_freeze_notify (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
6184
6185 if (current_pos != -1 &&
6186 priv->current_pos != current_pos)
6187 {
6188 priv->current_pos = current_pos;
6189 changed = TRUE(!(0));
6190
6191 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_CURSOR_POSITION]);
6192 }
6193
6194 if (selection_bound != -1 &&
6195 priv->selection_bound != selection_bound)
6196 {
6197 priv->selection_bound = selection_bound;
6198 changed = TRUE(!(0));
6199
6200 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_SELECTION_BOUND]);
6201 }
6202
6203 g_object_thaw_notify (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
6204
6205 if (priv->current_pos != priv->selection_bound)
6206 {
6207 if (!priv->selection_node)
6208 {
6209 CtkCssNode *widget_node;
6210
6211 widget_node = ctk_css_gadget_get_node (priv->gadget);
6212 priv->selection_node = ctk_css_node_new ();
6213 ctk_css_node_set_name (priv->selection_node, I_("selection")g_intern_static_string ("selection"));
6214 ctk_css_node_set_parent (priv->selection_node, widget_node);
6215 ctk_css_node_set_state (priv->selection_node, ctk_css_node_get_state (widget_node));
6216 g_object_unref (priv->selection_node);
6217 }
6218 }
6219 else
6220 {
6221 if (priv->selection_node)
6222 {
6223 ctk_css_node_set_parent (priv->selection_node, NULL((void*)0));
6224 priv->selection_node = NULL((void*)0);
6225 }
6226 }
6227
6228 if (changed)
6229 {
6230 ctk_entry_move_adjustments (entry);
6231 ctk_entry_recompute (entry);
6232 }
6233}
6234
6235static void
6236ctk_entry_reset_layout (CtkEntry *entry)
6237{
6238 CtkEntryPrivate *priv = entry->priv;
6239
6240 if (priv->cached_layout)
6241 {
6242 g_object_unref (priv->cached_layout);
6243 priv->cached_layout = NULL((void*)0);
6244 }
6245}
6246
6247static void
6248update_im_cursor_location (CtkEntry *entry)
6249{
6250 CtkEntryPrivate *priv = entry->priv;
6251 CdkRectangle area;
6252 gint strong_x;
6253 gint strong_xoffset;
6254 gint area_width, area_height;
6255
6256 ctk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, NULL((void*)0));
6257 ctk_entry_get_text_area_size (entry, NULL((void*)0), NULL((void*)0), &area_width, &area_height);
6258
6259 strong_xoffset = strong_x - priv->scroll_offset;
6260 if (strong_xoffset < 0)
6261 {
6262 strong_xoffset = 0;
6263 }
6264 else if (strong_xoffset > area_width)
6265 {
6266 strong_xoffset = area_width;
6267 }
6268 area.x = strong_xoffset;
6269 area.y = 0;
6270 area.width = 0;
6271 area.height = area_height;
6272
6273 ctk_im_context_set_cursor_location (priv->im_context, &area);
6274}
6275
6276static void
6277ctk_entry_recompute (CtkEntry *entry)
6278{
6279 CtkEntryPrivate *priv = entry->priv;
6280 CtkTextHandleMode handle_mode;
6281
6282 ctk_entry_reset_layout (entry);
6283 ctk_entry_check_cursor_blink (entry);
6284
6285 ctk_entry_adjust_scroll (entry);
6286
6287 update_im_cursor_location (entry);
6288
6289 if (priv->text_handle)
6290 {
6291 handle_mode = _ctk_text_handle_get_mode (priv->text_handle);
6292
6293 if (handle_mode != CTK_TEXT_HANDLE_MODE_NONE)
6294 ctk_entry_update_handles (entry, handle_mode);
6295 }
6296
6297 ctk_widget_queue_draw (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
6298}
6299
6300static void
6301ctk_entry_get_placeholder_text_color (CtkEntry *entry,
6302 PangoColor *color)
6303{
6304 CtkWidget *widget = CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
;
6305 CtkStyleContext *context;
6306 CdkRGBA fg = { .red = 0.5, .green = 0.5, .blue = 0.5 };
6307
6308 context = ctk_widget_get_style_context (widget);
6309 ctk_style_context_lookup_color (context, "placeholder_text_color", &fg);
6310
6311 color->red = CLAMP (fg.red * 65535. + 0.5, 0, 65535)(((fg.red * 65535. + 0.5) > (65535)) ? (65535) : (((fg.red
* 65535. + 0.5) < (0)) ? (0) : (fg.red * 65535. + 0.5)))
;
6312 color->green = CLAMP (fg.green * 65535. + 0.5, 0, 65535)(((fg.green * 65535. + 0.5) > (65535)) ? (65535) : (((fg.green
* 65535. + 0.5) < (0)) ? (0) : (fg.green * 65535. + 0.5))
)
;
6313 color->blue = CLAMP (fg.blue * 65535. + 0.5, 0, 65535)(((fg.blue * 65535. + 0.5) > (65535)) ? (65535) : (((fg.blue
* 65535. + 0.5) < (0)) ? (0) : (fg.blue * 65535. + 0.5)))
;
6314}
6315
6316static inline gboolean
6317show_placeholder_text (CtkEntry *entry)
6318{
6319 CtkEntryPrivate *priv = entry->priv;
6320
6321 if (!ctk_widget_has_focus (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
) &&
6322 ctk_entry_buffer_get_bytes (get_buffer (entry)) == 0 &&
6323 priv->placeholder_text != NULL((void*)0))
6324 return TRUE(!(0));
6325
6326 return FALSE(0);
6327}
6328
6329static PangoLayout *
6330ctk_entry_create_layout (CtkEntry *entry,
6331 gboolean include_preedit)
6332{
6333 CtkEntryPrivate *priv = entry->priv;
6334 CtkWidget *widget = CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
;
6335 CtkStyleContext *context;
6336 PangoLayout *layout;
6337 PangoAttrList *tmp_attrs;
6338 gboolean placeholder_layout;
6339
6340 gchar *preedit_string = NULL((void*)0);
6341 gint preedit_length = 0;
6342 PangoAttrList *preedit_attrs = NULL((void*)0);
6343
6344 gchar *display_text;
6345 guint n_bytes;
6346
6347 context = ctk_widget_get_style_context (widget);
6348
6349 layout = ctk_widget_create_pango_layout (widget, NULL((void*)0));
6350 pango_layout_set_single_paragraph_mode (layout, TRUE(!(0)));
6351
6352 tmp_attrs = _ctk_style_context_get_pango_attributes (context);
6353 tmp_attrs = _ctk_pango_attr_list_merge (tmp_attrs, priv->attrs);
6354 if (!tmp_attrs)
6355 tmp_attrs = pango_attr_list_new ();
6356
6357 placeholder_layout = show_placeholder_text (entry);
6358 if (placeholder_layout)
6359 display_text = g_strdup (priv->placeholder_text)g_strdup_inline (priv->placeholder_text);
6360 else
6361 display_text = _ctk_entry_get_display_text (entry, 0, -1);
6362
6363 n_bytes = strlen (display_text);
6364
6365 if (!placeholder_layout && include_preedit)
6366 {
6367 ctk_im_context_get_preedit_string (priv->im_context,
6368 &preedit_string, &preedit_attrs, NULL((void*)0));
6369 preedit_length = priv->preedit_length;
6370 }
6371 else if (placeholder_layout)
6372 {
6373 PangoColor color;
6374 PangoAttribute *attr;
6375
6376 ctk_entry_get_placeholder_text_color (entry, &color);
6377 attr = pango_attr_foreground_new (color.red, color.green, color.blue);
6378 attr->start_index = 0;
6379 attr->end_index = G_MAXINT2147483647;
6380 pango_attr_list_insert (tmp_attrs, attr);
6381 pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
6382 }
6383
6384 if (preedit_length)
6385 {
6386 GString *tmp_string = g_string_new (display_text);
6387 gint pos;
6388
6389 pos = g_utf8_offset_to_pointer (display_text, priv->current_pos) - display_text;
6390 g_string_insert (tmp_string, pos, preedit_string);
6391 pango_layout_set_text (layout, tmp_string->str, tmp_string->len);
6392 pango_attr_list_splice (tmp_attrs, preedit_attrs, pos, preedit_length);
6393 g_string_free (tmp_string, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(tmp_string), ((!(0)))) : g_string_free_and_steal (tmp_string
)) : (g_string_free) ((tmp_string), ((!(0)))))
;
6394 }
6395 else
6396 {
6397 PangoDirection pango_dir;
6398
6399 if (ctk_entry_get_display_mode (entry) == DISPLAY_NORMAL)
6400 pango_dir = _ctk_pango_find_base_dir (display_text, n_bytes);
6401 else
6402 pango_dir = PANGO_DIRECTION_NEUTRAL;
6403
6404 if (pango_dir == PANGO_DIRECTION_NEUTRAL)
6405 {
6406 if (ctk_widget_has_focus (widget))
6407 {
6408 CdkDisplay *display = ctk_widget_get_display (widget);
6409 CdkKeymap *keymap = cdk_keymap_get_for_display (display);
6410 if (cdk_keymap_get_direction (keymap) == PANGO_DIRECTION_RTL)
6411 pango_dir = PANGO_DIRECTION_RTL;
6412 else
6413 pango_dir = PANGO_DIRECTION_LTR;
6414 }
6415 else
6416 {
6417 if (ctk_widget_get_direction (widget) == CTK_TEXT_DIR_RTL)
6418 pango_dir = PANGO_DIRECTION_RTL;
6419 else
6420 pango_dir = PANGO_DIRECTION_LTR;
6421 }
6422 }
6423
6424 pango_context_set_base_dir (ctk_widget_get_pango_context (widget), pango_dir);
6425
6426 priv->resolved_dir = pango_dir;
6427
6428 pango_layout_set_text (layout, display_text, n_bytes);
6429 }
6430
6431 pango_layout_set_attributes (layout, tmp_attrs);
6432
6433 if (priv->tabs)
6434 pango_layout_set_tabs (layout, priv->tabs);
6435
6436 g_free (preedit_string);
6437 g_free (display_text);
6438
6439 if (preedit_attrs)
6440 pango_attr_list_unref (preedit_attrs);
6441
6442 pango_attr_list_unref (tmp_attrs);
6443
6444 return layout;
6445}
6446
6447static PangoLayout *
6448ctk_entry_ensure_layout (CtkEntry *entry,
6449 gboolean include_preedit)
6450{
6451 CtkEntryPrivate *priv = entry->priv;
6452
6453 if (priv->preedit_length > 0 &&
6454 !include_preedit != !priv->cache_includes_preedit)
6455 ctk_entry_reset_layout (entry);
6456
6457 if (!priv->cached_layout)
6458 {
6459 priv->cached_layout = ctk_entry_create_layout (entry, include_preedit);
6460 priv->cache_includes_preedit = include_preedit;
6461 }
6462
6463 return priv->cached_layout;
6464}
6465
6466static void
6467get_layout_position (CtkEntry *entry,
6468 gint *x,
6469 gint *y)
6470{
6471 CtkEntryPrivate *priv = entry->priv;
6472 PangoLayout *layout;
6473 PangoRectangle logical_rect;
6474 gint y_pos, area_height;
6475 PangoLayoutLine *line;
6476
6477 layout = ctk_entry_ensure_layout (entry, TRUE(!(0)));
6478
6479 area_height = PANGO_SCALE1024 * priv->text_allocation.height;
6480
6481 line = pango_layout_get_lines_readonly (layout)->data;
6482 pango_layout_line_get_extents (line, NULL((void*)0), &logical_rect);
6483
6484 /* Align primarily for locale's ascent/descent */
6485 if (priv->text_baseline < 0)
6486 y_pos = ((area_height - priv->ascent - priv->descent) / 2 +
6487 priv->ascent + logical_rect.y);
6488 else
6489 y_pos = PANGO_SCALE1024 * priv->text_baseline - pango_layout_get_baseline (layout);
6490
6491 /* Now see if we need to adjust to fit in actual drawn string */
6492 if (logical_rect.height > area_height)
6493 y_pos = (area_height - logical_rect.height) / 2;
6494 else if (y_pos < 0)
6495 y_pos = 0;
6496 else if (y_pos + logical_rect.height > area_height)
6497 y_pos = area_height - logical_rect.height;
6498
6499 y_pos = y_pos / PANGO_SCALE1024;
6500
6501 if (x)
6502 *x = - priv->scroll_offset;
6503
6504 if (y)
6505 *y = y_pos;
6506}
6507
6508static void
6509ctk_entry_draw_text (CtkEntry *entry,
6510 cairo_t *cr)
6511{
6512 CtkEntryPrivate *priv = entry->priv;
6513 CtkWidget *widget = CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
;
6514 CtkStyleContext *context;
6515 PangoLayout *layout;
6516 gint x, y;
6517 gint start_pos, end_pos;
6518 CtkAllocation allocation;
6519
6520 /* Nothing to display at all */
6521 if (ctk_entry_get_display_mode (entry) == DISPLAY_BLANK)
6522 return;
6523
6524 context = ctk_widget_get_style_context (widget);
6525 ctk_widget_get_allocation (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, &allocation);
6526 layout = ctk_entry_ensure_layout (entry, TRUE(!(0)));
6527
6528 cairo_save (cr);
6529
6530 cairo_rectangle (cr,
6531 priv->text_allocation.x - allocation.x,
6532 priv->text_allocation.y - allocation.y,
6533 priv->text_allocation.width,
6534 priv->text_allocation.height);
6535 cairo_clip (cr);
6536
6537 ctk_entry_get_layout_offsets (entry, &x, &y);
6538
6539 if (show_placeholder_text (entry))
6540 pango_layout_set_width (layout, PANGO_SCALE1024 * priv->text_allocation.width);
6541
6542 ctk_render_layout (context, cr, x, y, layout);
6543
6544 if (ctk_editable_get_selection_bounds (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, &start_pos, &end_pos))
6545 {
6546 const char *text = pango_layout_get_text (layout);
6547 gint start_index = g_utf8_offset_to_pointer (text, start_pos) - text;
6548 gint end_index = g_utf8_offset_to_pointer (text, end_pos) - text;
6549 cairo_region_t *clip;
6550 gint range[2];
6551
6552 range[0] = MIN (start_index, end_index)(((start_index) < (end_index)) ? (start_index) : (end_index
))
;
6553 range[1] = MAX (start_index, end_index)(((start_index) > (end_index)) ? (start_index) : (end_index
))
;
6554
6555 ctk_style_context_save_to_node (context, priv->selection_node);
6556
6557 clip = cdk_pango_layout_get_clip_region (layout, x, y, range, 1);
6558 cdk_cairo_region (cr, clip);
6559 cairo_clip (cr);
6560 cairo_region_destroy (clip);
6561
6562 ctk_render_background (context, cr,
6563 0, 0,
6564 allocation.width, allocation.height);
6565
6566 ctk_render_layout (context, cr, x, y, layout);
6567
6568 ctk_style_context_restore (context);
6569 }
6570
6571 cairo_restore (cr);
6572}
6573
6574static void
6575ctk_entry_draw_cursor (CtkEntry *entry,
6576 cairo_t *cr,
6577 CursorType type)
6578{
6579 CtkEntryPrivate *priv = entry->priv;
6580 CtkWidget *widget = CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
;
6581 CtkStyleContext *context;
6582 PangoRectangle cursor_rect;
6583 gint cursor_index;
6584 gboolean block;
6585 gboolean block_at_line_end;
6586 PangoLayout *layout;
6587 const char *text;
6588 gint x, y;
6589
6590 context = ctk_widget_get_style_context (widget);
6591
6592 layout = ctk_entry_ensure_layout (entry, TRUE(!(0)));
6593 text = pango_layout_get_text (layout);
6594 ctk_entry_get_layout_offsets (entry, &x, &y);
6595
6596 if (type == CURSOR_DND)
6597 cursor_index = g_utf8_offset_to_pointer (text, priv->dnd_position) - text;
6598 else
6599 cursor_index = g_utf8_offset_to_pointer (text, priv->current_pos + priv->preedit_cursor) - text;
6600
6601 if (!priv->overwrite_mode)
6602 block = FALSE(0);
6603 else
6604 block = _ctk_text_util_get_block_cursor_location (layout,
6605 cursor_index, &cursor_rect, &block_at_line_end);
6606
6607 if (!block)
6608 {
6609 ctk_render_insertion_cursor (context, cr,
6610 x, y,
6611 layout, cursor_index, priv->resolved_dir);
6612 }
6613 else /* overwrite_mode */
6614 {
6615 CdkRGBA cursor_color;
6616 CdkRectangle rect;
6617
6618 cairo_save (cr);
6619
6620 rect.x = PANGO_PIXELS (cursor_rect.x)(((int)(cursor_rect.x) + 512) >> 10) + x;
6621 rect.y = PANGO_PIXELS (cursor_rect.y)(((int)(cursor_rect.y) + 512) >> 10) + y;
6622 rect.width = PANGO_PIXELS (cursor_rect.width)(((int)(cursor_rect.width) + 512) >> 10);
6623 rect.height = PANGO_PIXELS (cursor_rect.height)(((int)(cursor_rect.height) + 512) >> 10);
6624
6625 _ctk_style_context_get_cursor_color (context, &cursor_color, NULL((void*)0));
6626 cdk_cairo_set_source_rgba (cr, &cursor_color);
6627 cdk_cairo_rectangle (cr, &rect);
6628 cairo_fill (cr);
6629
6630 if (!block_at_line_end)
6631 {
6632 CdkRGBA color;
6633
6634 ctk_style_context_get_background_color (context,
6635 ctk_style_context_get_state (context),
6636 &color);
6637
6638 cdk_cairo_rectangle (cr, &rect);
6639 cairo_clip (cr);
6640 cairo_move_to (cr, x, y);
6641 cdk_cairo_set_source_rgba (cr, &color);
6642 pango_cairo_show_layout (cr, layout);
6643 }
6644
6645 cairo_restore (cr);
6646 }
6647}
6648
6649static void
6650ctk_entry_handle_dragged (CtkTextHandle *handle,
6651 CtkTextHandlePosition pos,
6652 gint x,
6653 gint y,
6654 CtkEntry *entry)
6655{
6656 gint cursor_pos, selection_bound_pos, tmp_pos;
6657 CtkEntryPrivate *priv = entry->priv;
6658 CtkTextHandleMode mode;
6659 gint *min, *max;
6660
6661 ctk_entry_selection_bubble_popup_unset (entry);
6662
6663 cursor_pos = priv->current_pos;
6664 selection_bound_pos = priv->selection_bound;
6665 mode = _ctk_text_handle_get_mode (handle);
6666
6667 tmp_pos = ctk_entry_find_position (entry, x + priv->scroll_offset);
6668
6669 if (mode == CTK_TEXT_HANDLE_MODE_CURSOR ||
6670 cursor_pos >= selection_bound_pos)
6671 {
6672 max = &cursor_pos;
6673 min = &selection_bound_pos;
6674 }
6675 else
6676 {
6677 max = &selection_bound_pos;
6678 min = &cursor_pos;
6679 }
6680
6681 if (pos == CTK_TEXT_HANDLE_POSITION_SELECTION_END)
6682 {
6683 if (mode == CTK_TEXT_HANDLE_MODE_SELECTION)
6684 {
6685 gint min_pos;
6686
6687 min_pos = MAX (*min + 1, 0)(((*min + 1) > (0)) ? (*min + 1) : (0));
6688 tmp_pos = MAX (tmp_pos, min_pos)(((tmp_pos) > (min_pos)) ? (tmp_pos) : (min_pos));
6689 }
6690
6691 *max = tmp_pos;
6692 }
6693 else
6694 {
6695 if (mode == CTK_TEXT_HANDLE_MODE_SELECTION)
6696 {
6697 gint max_pos;
6698
6699 max_pos = *max - 1;
6700 *min = MIN (tmp_pos, max_pos)(((tmp_pos) < (max_pos)) ? (tmp_pos) : (max_pos));
6701 }
6702 }
6703
6704 if (cursor_pos != priv->current_pos ||
6705 selection_bound_pos != priv->selection_bound)
6706 {
6707 if (mode == CTK_TEXT_HANDLE_MODE_CURSOR)
6708 {
6709 entry->priv->cursor_handle_dragged = TRUE(!(0));
6710 ctk_entry_set_positions (entry, cursor_pos, cursor_pos);
6711 }
6712 else
6713 {
6714 entry->priv->selection_handle_dragged = TRUE(!(0));
6715 ctk_entry_set_positions (entry, cursor_pos, selection_bound_pos);
6716 }
6717
6718 ctk_entry_update_handles (entry, mode);
6719 }
6720
6721 ctk_entry_show_magnifier (entry, x, y);
6722}
6723
6724static void
6725ctk_entry_handle_drag_started (CtkTextHandle *handle G_GNUC_UNUSED__attribute__ ((__unused__)),
6726 CtkTextHandlePosition pos G_GNUC_UNUSED__attribute__ ((__unused__)),
6727 CtkEntry *entry)
6728{
6729 entry->priv->cursor_handle_dragged = FALSE(0);
6730 entry->priv->selection_handle_dragged = FALSE(0);
6731}
6732
6733static void
6734ctk_entry_handle_drag_finished (CtkTextHandle *handle G_GNUC_UNUSED__attribute__ ((__unused__)),
6735 CtkTextHandlePosition pos G_GNUC_UNUSED__attribute__ ((__unused__)),
6736 CtkEntry *entry)
6737{
6738 CtkEntryPrivate *priv = entry->priv;
6739
6740 if (!priv->cursor_handle_dragged && !priv->selection_handle_dragged)
6741 {
6742 CtkSettings *settings;
6743 guint double_click_time;
6744
6745 settings = ctk_widget_get_settings (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
6746 g_object_get (settings, "ctk-double-click-time", &double_click_time, NULL((void*)0));
6747 if (g_get_monotonic_time() - priv->handle_place_time < double_click_time * 1000)
6748 {
6749 ctk_entry_select_word (entry);
6750 ctk_entry_update_handles (entry, CTK_TEXT_HANDLE_MODE_SELECTION);
6751 }
6752 else
6753 ctk_entry_selection_bubble_popup_set (entry);
6754 }
6755
6756 if (priv->magnifier_popover)
6757 ctk_popover_popdown (CTK_POPOVER (priv->magnifier_popover)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->magnifier_popover)), ((ctk_popover_get_type ())
)))))
);
6758}
6759
6760
6761/**
6762 * ctk_entry_reset_im_context:
6763 * @entry: a #CtkEntry
6764 *
6765 * Reset the input method context of the entry if needed.
6766 *
6767 * This can be necessary in the case where modifying the buffer
6768 * would confuse on-going input method behavior.
6769 *
6770 * Since: 2.22
6771 */
6772void
6773ctk_entry_reset_im_context (CtkEntry *entry)
6774{
6775 CtkEntryPrivate *priv = entry->priv;
6776
6777 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
6778
6779 if (priv->need_im_reset)
6780 {
6781 priv->need_im_reset = FALSE(0);
6782 ctk_im_context_reset (priv->im_context);
6783 }
6784}
6785
6786/**
6787 * ctk_entry_im_context_filter_keypress:
6788 * @entry: a #CtkEntry
6789 * @event: (type Cdk.EventKey): the key event
6790 *
6791 * Allow the #CtkEntry input method to internally handle key press
6792 * and release events. If this function returns %TRUE, then no further
6793 * processing should be done for this key event. See
6794 * ctk_im_context_filter_keypress().
6795 *
6796 * Note that you are expected to call this function from your handler
6797 * when overriding key event handling. This is needed in the case when
6798 * you need to insert your own key handling between the input method
6799 * and the default key event handling of the #CtkEntry.
6800 * See ctk_text_view_reset_im_context() for an example of use.
6801 *
6802 * Returns: %TRUE if the input method handled the key event.
6803 *
6804 * Since: 2.22
6805 */
6806gboolean
6807ctk_entry_im_context_filter_keypress (CtkEntry *entry,
6808 CdkEventKey *event)
6809{
6810 CtkEntryPrivate *priv;
6811
6812 g_return_val_if_fail (CTK_IS_ENTRY (entry), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return ((0)); } } while (0)
;
6813
6814 priv = entry->priv;
6815
6816 return ctk_im_context_filter_keypress (priv->im_context, event);
6817}
6818
6819CtkIMContext*
6820_ctk_entry_get_im_context (CtkEntry *entry)
6821{
6822 return entry->priv->im_context;
6823}
6824
6825CtkCssGadget *
6826ctk_entry_get_gadget (CtkEntry *entry)
6827{
6828 return entry->priv->gadget;
6829}
6830
6831static gint
6832ctk_entry_find_position (CtkEntry *entry,
6833 gint x)
6834{
6835 CtkEntryPrivate *priv = entry->priv;
6836 PangoLayout *layout;
6837 PangoLayoutLine *line;
6838 gint index;
6839 gint pos;
6840 gint trailing;
6841 const gchar *text;
6842 gint cursor_index;
6843
6844 layout = ctk_entry_ensure_layout (entry, TRUE(!(0)));
6845 text = pango_layout_get_text (layout);
6846 cursor_index = g_utf8_offset_to_pointer (text, priv->current_pos) - text;
6847
6848 line = pango_layout_get_lines_readonly (layout)->data;
6849 pango_layout_line_x_to_index (line, x * PANGO_SCALE1024, &index, &trailing);
6850
6851 if (index >= cursor_index && priv->preedit_length)
6852 {
6853 if (index >= cursor_index + priv->preedit_length)
6854 index -= priv->preedit_length;
6855 else
6856 {
6857 index = cursor_index;
6858 trailing = 0;
6859 }
6860 }
6861
6862 pos = g_utf8_pointer_to_offset (text, text + index);
6863 pos += trailing;
6864
6865 return pos;
6866}
6867
6868static void
6869ctk_entry_get_cursor_locations (CtkEntry *entry,
6870 CursorType type,
6871 gint *strong_x,
6872 gint *weak_x)
6873{
6874 CtkEntryPrivate *priv = entry->priv;
6875 DisplayMode mode = ctk_entry_get_display_mode (entry);
6876
6877 /* Nothing to display at all, so no cursor is relevant */
6878 if (mode == DISPLAY_BLANK)
6879 {
6880 if (strong_x)
6881 *strong_x = 0;
6882
6883 if (weak_x)
6884 *weak_x = 0;
6885 }
6886 else
6887 {
6888 PangoLayout *layout = ctk_entry_ensure_layout (entry, TRUE(!(0)));
6889 const gchar *text = pango_layout_get_text (layout);
6890 PangoRectangle strong_pos, weak_pos;
6891 gint index;
6892
6893 if (type == CURSOR_STANDARD)
6894 {
6895 index = g_utf8_offset_to_pointer (text, priv->current_pos + priv->preedit_cursor) - text;
6896 }
6897 else /* type == CURSOR_DND */
6898 {
6899 index = g_utf8_offset_to_pointer (text, priv->dnd_position) - text;
6900
6901 if (priv->dnd_position > priv->current_pos)
6902 {
6903 if (mode == DISPLAY_NORMAL)
6904 index += priv->preedit_length;
6905 else
6906 {
6907 gint preedit_len_chars = g_utf8_strlen (text, -1) - ctk_entry_buffer_get_length (get_buffer (entry));
6908 index += preedit_len_chars * g_unichar_to_utf8 (priv->invisible_char, NULL((void*)0));
6909 }
6910 }
6911 }
6912
6913 pango_layout_get_cursor_pos (layout, index, &strong_pos, &weak_pos);
6914
6915 if (strong_x)
6916 *strong_x = strong_pos.x / PANGO_SCALE1024;
6917
6918 if (weak_x)
6919 *weak_x = weak_pos.x / PANGO_SCALE1024;
6920 }
6921}
6922
6923static gboolean
6924ctk_entry_get_is_selection_handle_dragged (CtkEntry *entry)
6925{
6926 CtkEntryPrivate *priv = entry->priv;
6927 CtkTextHandlePosition pos;
6928
6929 if (!priv->text_handle)
6930 return FALSE(0);
6931
6932 if (_ctk_text_handle_get_mode (priv->text_handle) != CTK_TEXT_HANDLE_MODE_SELECTION)
6933 return FALSE(0);
6934
6935 if (priv->current_pos >= priv->selection_bound)
6936 pos = CTK_TEXT_HANDLE_POSITION_SELECTION_START;
6937 else
6938 pos = CTK_TEXT_HANDLE_POSITION_SELECTION_END;
6939
6940 return _ctk_text_handle_get_is_dragged (priv->text_handle, pos);
6941}
6942
6943static void
6944ctk_entry_get_scroll_limits (CtkEntry *entry,
6945 gint *min_offset,
6946 gint *max_offset)
6947{
6948 CtkEntryPrivate *priv = entry->priv;
6949 gfloat xalign;
6950 PangoLayout *layout;
6951 PangoLayoutLine *line;
6952 PangoRectangle logical_rect;
6953 gint text_width;
6954
6955 layout = ctk_entry_ensure_layout (entry, TRUE(!(0)));
6956 line = pango_layout_get_lines_readonly (layout)->data;
6957
6958 pango_layout_line_get_extents (line, NULL((void*)0), &logical_rect);
6959
6960 /* Display as much text as we can */
6961
6962 if (priv->resolved_dir == PANGO_DIRECTION_LTR)
6963 xalign = priv->xalign;
6964 else
6965 xalign = 1.0 - priv->xalign;
6966
6967 text_width = PANGO_PIXELS(logical_rect.width)(((int)(logical_rect.width) + 512) >> 10);
6968
6969 if (text_width > priv->text_allocation.width)
6970 {
6971 *min_offset = 0;
6972 *max_offset = text_width - priv->text_allocation.width;
6973 }
6974 else
6975 {
6976 *min_offset = (text_width - priv->text_allocation.width) * xalign;
6977 *max_offset = *min_offset;
6978 }
6979}
6980
6981static void
6982ctk_entry_adjust_scroll (CtkEntry *entry)
6983{
6984 CtkEntryPrivate *priv = entry->priv;
6985 gint min_offset, max_offset;
6986 gint strong_x, weak_x;
6987 gint strong_xoffset, weak_xoffset;
6988 CtkTextHandleMode handle_mode;
6989
6990 if (!ctk_widget_get_realized (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
6991 return;
6992
6993 ctk_entry_get_scroll_limits (entry, &min_offset, &max_offset);
6994
6995 priv->scroll_offset = CLAMP (priv->scroll_offset, min_offset, max_offset)(((priv->scroll_offset) > (max_offset)) ? (max_offset) :
(((priv->scroll_offset) < (min_offset)) ? (min_offset)
: (priv->scroll_offset)))
;
6996
6997 if (ctk_entry_get_is_selection_handle_dragged (entry))
6998 {
6999 /* The text handle corresponding to the selection bound is
7000 * being dragged, ensure it stays onscreen even if we scroll
7001 * cursors away, this is so both handles can cause content
7002 * to scroll.
7003 */
7004 strong_x = weak_x = ctk_entry_get_selection_bound_location (entry);
7005 }
7006 else
7007 {
7008 /* And make sure cursors are on screen. Note that the cursor is
7009 * actually drawn one pixel into the INNER_BORDER space on
7010 * the right, when the scroll is at the utmost right. This
7011 * looks better to to me than confining the cursor inside the
7012 * border entirely, though it means that the cursor gets one
7013 * pixel closer to the edge of the widget on the right than
7014 * on the left. This might need changing if one changed
7015 * INNER_BORDER from 2 to 1, as one would do on a
7016 * small-screen-real-estate display.
7017 *
7018 * We always make sure that the strong cursor is on screen, and
7019 * put the weak cursor on screen if possible.
7020 */
7021 ctk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, &weak_x);
7022 }
7023
7024 strong_xoffset = strong_x - priv->scroll_offset;
7025
7026 if (strong_xoffset < 0)
7027 {
7028 priv->scroll_offset += strong_xoffset;
7029 strong_xoffset = 0;
7030 }
7031 else if (strong_xoffset > priv->text_allocation.width)
7032 {
7033 priv->scroll_offset += strong_xoffset - priv->text_allocation.width;
7034 strong_xoffset = priv->text_allocation.width;
7035 }
7036
7037 weak_xoffset = weak_x - priv->scroll_offset;
7038
7039 if (weak_xoffset < 0 && strong_xoffset - weak_xoffset <= priv->text_allocation.width)
7040 {
7041 priv->scroll_offset += weak_xoffset;
7042 }
7043 else if (weak_xoffset > priv->text_allocation.width &&
7044 strong_xoffset - (weak_xoffset - priv->text_allocation.width) >= 0)
7045 {
7046 priv->scroll_offset += weak_xoffset - priv->text_allocation.width;
7047 }
7048
7049 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_SCROLL_OFFSET]);
7050
7051 if (priv->text_handle)
7052 {
7053 handle_mode = _ctk_text_handle_get_mode (priv->text_handle);
7054
7055 if (handle_mode != CTK_TEXT_HANDLE_MODE_NONE)
7056 ctk_entry_update_handles (entry, handle_mode);
7057 }
7058}
7059
7060static void
7061ctk_entry_move_adjustments (CtkEntry *entry)
7062{
7063 CtkWidget *widget = CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
;
7064 CtkAllocation allocation;
7065 CtkAdjustment *adjustment;
7066 PangoContext *context;
7067 PangoFontMetrics *metrics;
7068 gint x, layout_x;
7069 gint char_width;
7070
7071 adjustment = g_object_get_qdata (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, quark_cursor_hadjustment);
7072 if (!adjustment)
7073 return;
7074
7075 ctk_css_gadget_get_content_allocation (entry->priv->gadget, &allocation, NULL((void*)0));
7076
7077 /* Cursor/char position, layout offset, border width, and widget allocation */
7078 ctk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &x, NULL((void*)0));
7079 get_layout_position (entry, &layout_x, NULL((void*)0));
7080 x += allocation.x + layout_x;
7081
7082 /* Approximate width of a char, so user can see what is ahead/behind */
7083 context = ctk_widget_get_pango_context (widget);
7084
7085 metrics = pango_context_get_metrics (context,
7086 pango_context_get_font_description (context),
7087 pango_context_get_language (context));
7088 char_width = pango_font_metrics_get_approximate_char_width (metrics) / PANGO_SCALE1024;
7089
7090 /* Scroll it */
7091 ctk_adjustment_clamp_page (adjustment,
7092 x - (char_width + 1), /* one char + one pixel before */
7093 x + (char_width + 2)); /* one char + cursor + one pixel after */
7094}
7095
7096static gint
7097ctk_entry_move_visually (CtkEntry *entry,
7098 gint start,
7099 gint count)
7100{
7101 CtkEntryPrivate *priv = entry->priv;
7102 gint index;
7103 PangoLayout *layout = ctk_entry_ensure_layout (entry, FALSE(0));
7104 const gchar *text;
7105
7106 text = pango_layout_get_text (layout);
7107
7108 index = g_utf8_offset_to_pointer (text, start) - text;
7109
7110 while (count != 0)
7111 {
7112 int new_index, new_trailing;
7113 gboolean split_cursor;
7114 gboolean strong;
7115
7116 g_object_get (ctk_widget_get_settings (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
),
7117 "ctk-split-cursor", &split_cursor,
7118 NULL((void*)0));
7119
7120 if (split_cursor)
7121 strong = TRUE(!(0));
7122 else
7123 {
7124 CdkKeymap *keymap = cdk_keymap_get_for_display (ctk_widget_get_display (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
));
7125 PangoDirection keymap_direction = cdk_keymap_get_direction (keymap);
7126
7127 strong = keymap_direction == priv->resolved_dir;
7128 }
7129
7130 if (count > 0)
7131 {
7132 pango_layout_move_cursor_visually (layout, strong, index, 0, 1, &new_index, &new_trailing);
7133 count--;
7134 }
7135 else
7136 {
7137 pango_layout_move_cursor_visually (layout, strong, index, 0, -1, &new_index, &new_trailing);
7138 count++;
7139 }
7140
7141 if (new_index < 0)
7142 index = 0;
7143 else if (new_index != G_MAXINT2147483647)
7144 index = new_index;
7145
7146 while (new_trailing--)
7147 index = g_utf8_next_char (text + index)((text + index) + g_utf8_skip[*(const guchar *)(text + index)
])
- text;
7148 }
7149
7150 return g_utf8_pointer_to_offset (text, text + index);
7151}
7152
7153static gint
7154ctk_entry_move_logically (CtkEntry *entry,
7155 gint start,
7156 gint count)
7157{
7158 gint new_pos = start;
7159 guint length;
7160
7161 length = ctk_entry_buffer_get_length (get_buffer (entry));
7162
7163 /* Prevent any leak of information */
7164 if (ctk_entry_get_display_mode (entry) != DISPLAY_NORMAL)
7165 {
7166 new_pos = CLAMP (start + count, 0, length)(((start + count) > (length)) ? (length) : (((start + count
) < (0)) ? (0) : (start + count)))
;
7167 }
7168 else
7169 {
7170 PangoLayout *layout = ctk_entry_ensure_layout (entry, FALSE(0));
7171 PangoLogAttr *log_attrs;
7172 gint n_attrs;
7173
7174 pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
7175
7176 while (count > 0 && new_pos < length)
7177 {
7178 do
7179 new_pos++;
7180 while (new_pos < length && !log_attrs[new_pos].is_cursor_position);
7181
7182 count--;
7183 }
7184 while (count < 0 && new_pos > 0)
7185 {
7186 do
7187 new_pos--;
7188 while (new_pos > 0 && !log_attrs[new_pos].is_cursor_position);
7189
7190 count++;
7191 }
7192
7193 g_free (log_attrs);
7194 }
7195
7196 return new_pos;
7197}
7198
7199static gint
7200ctk_entry_move_forward_word (CtkEntry *entry,
7201 gint start,
7202 gboolean allow_whitespace)
7203{
7204 gint new_pos = start;
7205 guint length;
7206
7207 length = ctk_entry_buffer_get_length (get_buffer (entry));
7208
7209 /* Prevent any leak of information */
7210 if (ctk_entry_get_display_mode (entry) != DISPLAY_NORMAL)
7211 {
7212 new_pos = length;
7213 }
7214 else if (new_pos < length)
7215 {
7216 PangoLayout *layout = ctk_entry_ensure_layout (entry, FALSE(0));
7217 PangoLogAttr *log_attrs;
7218 gint n_attrs;
7219
7220 pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
7221
7222 /* Find the next word boundary */
7223 new_pos++;
7224 while (new_pos < n_attrs - 1 && !(log_attrs[new_pos].is_word_end ||
7225 (log_attrs[new_pos].is_word_start && allow_whitespace)))
7226 new_pos++;
7227
7228 g_free (log_attrs);
7229 }
7230
7231 return new_pos;
7232}
7233
7234
7235static gint
7236ctk_entry_move_backward_word (CtkEntry *entry,
7237 gint start,
7238 gboolean allow_whitespace)
7239{
7240 gint new_pos = start;
7241
7242 /* Prevent any leak of information */
7243 if (ctk_entry_get_display_mode (entry) != DISPLAY_NORMAL)
7244 {
7245 new_pos = 0;
7246 }
7247 else if (start > 0)
7248 {
7249 PangoLayout *layout = ctk_entry_ensure_layout (entry, FALSE(0));
7250 PangoLogAttr *log_attrs;
7251 gint n_attrs;
7252
7253 pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
7254
7255 new_pos = start - 1;
7256
7257 /* Find the previous word boundary */
7258 while (new_pos > 0 && !(log_attrs[new_pos].is_word_start ||
7259 (log_attrs[new_pos].is_word_end && allow_whitespace)))
7260 new_pos--;
7261
7262 g_free (log_attrs);
7263 }
7264
7265 return new_pos;
7266}
7267
7268static void
7269ctk_entry_delete_whitespace (CtkEntry *entry)
7270{
7271 CtkEntryPrivate *priv = entry->priv;
7272 PangoLayout *layout = ctk_entry_ensure_layout (entry, FALSE(0));
7273 PangoLogAttr *log_attrs;
7274 gint n_attrs;
7275 gint start, end;
7276
7277 pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
7278
7279 start = end = priv->current_pos;
7280
7281 while (start > 0 && log_attrs[start-1].is_white)
7282 start--;
7283
7284 while (end < n_attrs && log_attrs[end].is_white)
7285 end++;
7286
7287 g_free (log_attrs);
7288
7289 if (start != end)
7290 ctk_editable_delete_text (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, start, end);
7291}
7292
7293
7294static void
7295ctk_entry_select_word (CtkEntry *entry)
7296{
7297 CtkEntryPrivate *priv = entry->priv;
7298 gint start_pos = ctk_entry_move_backward_word (entry, priv->current_pos, TRUE(!(0)));
7299 gint end_pos = ctk_entry_move_forward_word (entry, priv->current_pos, TRUE(!(0)));
7300
7301 ctk_editable_select_region (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, start_pos, end_pos);
7302}
7303
7304static void
7305ctk_entry_select_line (CtkEntry *entry)
7306{
7307 ctk_editable_select_region (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, 0, -1);
7308}
7309
7310static gint
7311truncate_multiline (const gchar *text)
7312{
7313 gint length;
7314
7315 for (length = 0;
7316 text[length] && text[length] != '\n' && text[length] != '\r';
7317 length++);
7318
7319 return length;
7320}
7321
7322static void
7323paste_received (CtkClipboard *clipboard G_GNUC_UNUSED__attribute__ ((__unused__)),
7324 const gchar *text,
7325 gpointer data)
7326{
7327 CtkEntry *entry = CTK_ENTRY (data)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((ctk_entry_get_type ()))))))
;
7328 CtkEditable *editable = CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
;
7329 CtkEntryPrivate *priv = entry->priv;
7330 guint button;
7331
7332 button = ctk_gesture_single_get_current_button (CTK_GESTURE_SINGLE (priv->multipress_gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((priv->multipress_gesture)), ((ctk_gesture_single_get_type
()))))))
);
7333
7334 if (button == CDK_BUTTON_MIDDLE(2))
7335 {
7336 gint pos, start, end;
7337 pos = priv->insert_pos;
7338 ctk_editable_get_selection_bounds (editable, &start, &end);
7339 if (!((start <= pos && pos <= end) || (end <= pos && pos <= start)))
7340 ctk_editable_select_region (editable, pos, pos);
7341 }
7342
7343 if (text)
7344 {
7345 gint pos, start, end;
7346 gint length = -1;
7347 gboolean popup_completion;
7348 CtkEntryCompletion *completion;
7349
7350 completion = ctk_entry_get_completion (entry);
7351
7352 if (priv->truncate_multiline)
7353 length = truncate_multiline (text);
7354
7355 /* only complete if the selection is at the end */
7356 popup_completion = (ctk_entry_buffer_get_length (get_buffer (entry)) ==
7357 MAX (priv->current_pos, priv->selection_bound)(((priv->current_pos) > (priv->selection_bound)) ? (
priv->current_pos) : (priv->selection_bound))
);
7358
7359 if (completion)
7360 {
7361 if (ctk_widget_get_mapped (completion->priv->popup_window))
7362 _ctk_entry_completion_popdown (completion);
7363
7364 if (!popup_completion && completion->priv->changed_id > 0)
7365 g_signal_handler_block (entry, completion->priv->changed_id);
7366 }
7367
7368 begin_change (entry);
7369 if (ctk_editable_get_selection_bounds (editable, &start, &end))
7370 ctk_editable_delete_text (editable, start, end);
7371
7372 pos = priv->current_pos;
7373 ctk_editable_insert_text (editable, text, length, &pos);
7374 ctk_editable_set_position (editable, pos);
7375 end_change (entry);
7376
7377 if (completion &&
7378 !popup_completion && completion->priv->changed_id > 0)
7379 g_signal_handler_unblock (entry, completion->priv->changed_id);
7380 }
7381
7382 g_object_unref (entry);
7383}
7384
7385static void
7386ctk_entry_paste (CtkEntry *entry,
7387 CdkAtom selection)
7388{
7389 g_object_ref (entry)((__typeof__ (entry)) (g_object_ref) (entry));
7390 ctk_clipboard_request_text (ctk_widget_get_clipboard (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, selection),
7391 paste_received, entry);
7392}
7393
7394static void
7395primary_get_cb (CtkClipboard *clipboard G_GNUC_UNUSED__attribute__ ((__unused__)),
7396 CtkSelectionData *selection_data,
7397 guint info G_GNUC_UNUSED__attribute__ ((__unused__)),
7398 gpointer data)
7399{
7400 CtkEntry *entry = CTK_ENTRY (data)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((ctk_entry_get_type ()))))))
;
7401 gint start, end;
7402
7403 if (ctk_editable_get_selection_bounds (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, &start, &end))
7404 {
7405 gchar *str = _ctk_entry_get_display_text (entry, start, end);
7406 ctk_selection_data_set_text (selection_data, str, -1);
7407 g_free (str);
7408 }
7409}
7410
7411static void
7412primary_clear_cb (CtkClipboard *clipboard G_GNUC_UNUSED__attribute__ ((__unused__)),
7413 gpointer data)
7414{
7415 CtkEntry *entry = CTK_ENTRY (data)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((ctk_entry_get_type ()))))))
;
7416 CtkEntryPrivate *priv = entry->priv;
7417
7418 ctk_editable_select_region (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, priv->current_pos, priv->current_pos);
7419}
7420
7421static void
7422ctk_entry_update_primary_selection (CtkEntry *entry)
7423{
7424 CtkTargetList *list;
7425 CtkTargetEntry *targets;
7426 CtkClipboard *clipboard;
7427 gint start, end;
7428 gint n_targets;
7429
7430 if (!ctk_widget_get_realized (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
7431 return;
7432
7433 list = ctk_target_list_new (NULL((void*)0), 0);
7434 ctk_target_list_add_text_targets (list, 0);
7435
7436 targets = ctk_target_table_new_from_list (list, &n_targets);
7437
7438 clipboard = ctk_widget_get_clipboard (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, CDK_SELECTION_PRIMARY((CdkAtom)((gpointer) (gulong) (1))));
7439
7440 if (ctk_editable_get_selection_bounds (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, &start, &end))
7441 {
7442 ctk_clipboard_set_with_owner (clipboard, targets, n_targets,
7443 primary_get_cb, primary_clear_cb, G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
7444 }
7445 else
7446 {
7447 if (ctk_clipboard_get_owner (clipboard) == G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
)
7448 ctk_clipboard_clear (clipboard);
7449 }
7450
7451 ctk_target_table_free (targets, n_targets);
7452 ctk_target_list_unref (list);
7453}
7454
7455static void
7456ctk_entry_clear_icon (CtkEntry *entry,
7457 CtkEntryIconPosition icon_pos)
7458{
7459 CtkEntryPrivate *priv = entry->priv;
7460 EntryIconInfo *icon_info = priv->icons[icon_pos];
7461 CtkIconHelper *icon_helper;
7462 CtkImageType storage_type;
7463
7464 if (icon_info == NULL((void*)0))
7465 return;
7466
7467 icon_helper = CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
;
7468 if (_ctk_icon_helper_get_is_empty (icon_helper))
7469 return;
7470
7471 g_object_freeze_notify (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
7472
7473 /* Explicitly check, as the pointer may become invalidated
7474 * during destruction.
7475 */
7476 if (CDK_IS_WINDOW (icon_info->window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(icon_info->window)); GType __t = ((cdk_window_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; }))))
)
7477 cdk_window_hide (icon_info->window);
7478
7479 storage_type = _ctk_icon_helper_get_storage_type (icon_helper);
7480
7481 switch (storage_type)
7482 {
7483 case CTK_IMAGE_PIXBUF:
7484 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
,
7485 entry_props[icon_pos == CTK_ENTRY_ICON_PRIMARY
7486 ? PROP_PIXBUF_PRIMARY
7487 : PROP_PIXBUF_SECONDARY]);
7488 break;
7489
7490 case CTK_IMAGE_STOCK:
7491 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
,
7492 entry_props[icon_pos == CTK_ENTRY_ICON_PRIMARY
7493 ? PROP_STOCK_PRIMARY
7494 : PROP_STOCK_SECONDARY]);
7495 break;
7496
7497 case CTK_IMAGE_ICON_NAME:
7498 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
,
7499 entry_props[icon_pos == CTK_ENTRY_ICON_PRIMARY
7500 ? PROP_ICON_NAME_PRIMARY
7501 : PROP_ICON_NAME_SECONDARY]);
7502 break;
7503
7504 case CTK_IMAGE_GICON:
7505 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
,
7506 entry_props[icon_pos == CTK_ENTRY_ICON_PRIMARY
7507 ? PROP_GICON_PRIMARY
7508 : PROP_GICON_SECONDARY]);
7509 break;
7510
7511 default:
7512 g_assert_not_reached ()do { g_assertion_message_expr ("Ctk", "ctkentry.c", 7512, ((const
char*) (__func__)), ((void*)0)); } while (0)
;
7513 break;
7514 }
7515
7516 _ctk_icon_helper_clear (icon_helper);
7517
7518 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
,
7519 entry_props[icon_pos == CTK_ENTRY_ICON_PRIMARY
7520 ? PROP_STORAGE_TYPE_PRIMARY
7521 : PROP_STORAGE_TYPE_SECONDARY]);
7522
7523 g_object_thaw_notify (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
7524}
7525
7526/* Public API
7527 */
7528
7529/**
7530 * ctk_entry_new:
7531 *
7532 * Creates a new entry.
7533 *
7534 * Returns: a new #CtkEntry.
7535 */
7536CtkWidget*
7537ctk_entry_new (void)
7538{
7539 return g_object_new (CTK_TYPE_ENTRY(ctk_entry_get_type ()), NULL((void*)0));
7540}
7541
7542/**
7543 * ctk_entry_new_with_buffer:
7544 * @buffer: The buffer to use for the new #CtkEntry.
7545 *
7546 * Creates a new entry with the specified text buffer.
7547 *
7548 * Returns: a new #CtkEntry
7549 *
7550 * Since: 2.18
7551 */
7552CtkWidget*
7553ctk_entry_new_with_buffer (CtkEntryBuffer *buffer)
7554{
7555 g_return_val_if_fail (CTK_IS_ENTRY_BUFFER (buffer), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((buffer)); GType __t = ((ctk_entry_buffer_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY_BUFFER (buffer)"); return (((void*)0)); } }
while (0)
;
7556 return g_object_new (CTK_TYPE_ENTRY(ctk_entry_get_type ()), "buffer", buffer, NULL((void*)0));
7557}
7558
7559static CtkEntryBuffer*
7560get_buffer (CtkEntry *entry)
7561{
7562 CtkEntryPrivate *priv = entry->priv;
7563
7564 if (priv->buffer == NULL((void*)0))
7565 {
7566 CtkEntryBuffer *buffer;
7567 buffer = ctk_entry_buffer_new (NULL((void*)0), 0);
7568 ctk_entry_set_buffer (entry, buffer);
7569 g_object_unref (buffer);
7570 }
7571
7572 return priv->buffer;
7573}
7574
7575/**
7576 * ctk_entry_get_buffer:
7577 * @entry: a #CtkEntry
7578 *
7579 * Get the #CtkEntryBuffer object which holds the text for
7580 * this widget.
7581 *
7582 * Since: 2.18
7583 *
7584 * Returns: (transfer none): A #CtkEntryBuffer object.
7585 */
7586CtkEntryBuffer*
7587ctk_entry_get_buffer (CtkEntry *entry)
7588{
7589 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
7590
7591 return get_buffer (entry);
7592}
7593
7594/**
7595 * ctk_entry_set_buffer:
7596 * @entry: a #CtkEntry
7597 * @buffer: a #CtkEntryBuffer
7598 *
7599 * Set the #CtkEntryBuffer object which holds the text for
7600 * this widget.
7601 *
7602 * Since: 2.18
7603 */
7604void
7605ctk_entry_set_buffer (CtkEntry *entry,
7606 CtkEntryBuffer *buffer)
7607{
7608 CtkEntryPrivate *priv;
7609 GObject *obj;
7610 gboolean had_buffer = FALSE(0);
7611
7612 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
7613
7614 priv = entry->priv;
7615
7616 if (buffer)
7617 {
7618 g_return_if_fail (CTK_IS_ENTRY_BUFFER (buffer))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((buffer)); GType __t = ((ctk_entry_buffer_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY_BUFFER (buffer)"); return; } } while (0)
;
7619 g_object_ref (buffer)((__typeof__ (buffer)) (g_object_ref) (buffer));
7620 }
7621
7622 if (priv->buffer)
7623 {
7624 had_buffer = TRUE(!(0));
7625 buffer_disconnect_signals (entry);
7626 g_object_unref (priv->buffer);
7627 }
7628
7629 priv->buffer = buffer;
7630
7631 if (priv->buffer)
7632 buffer_connect_signals (entry);
7633
7634 obj = G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
;
7635 g_object_freeze_notify (obj);
7636 g_object_notify_by_pspec (obj, entry_props[PROP_BUFFER]);
7637 g_object_notify_by_pspec (obj, entry_props[PROP_TEXT]);
7638 g_object_notify_by_pspec (obj, entry_props[PROP_TEXT_LENGTH]);
7639 g_object_notify_by_pspec (obj, entry_props[PROP_MAX_LENGTH]);
7640 g_object_notify_by_pspec (obj, entry_props[PROP_VISIBILITY]);
7641 g_object_notify_by_pspec (obj, entry_props[PROP_INVISIBLE_CHAR]);
7642 g_object_notify_by_pspec (obj, entry_props[PROP_INVISIBLE_CHAR_SET]);
7643 g_object_thaw_notify (obj);
7644
7645 if (had_buffer)
7646 {
7647 ctk_editable_set_position (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, 0);
7648 ctk_entry_recompute (entry);
7649 }
7650}
7651
7652/**
7653 * ctk_entry_get_text_area:
7654 * @entry: a #CtkEntry
7655 * @text_area: (out): Return location for the text area.
7656 *
7657 * Gets the area where the entry’s text is drawn. This function is
7658 * useful when drawing something to the entry in a draw callback.
7659 *
7660 * If the entry is not realized, @text_area is filled with zeros.
7661 *
7662 * See also ctk_entry_get_icon_area().
7663 *
7664 * Since: 3.0
7665 **/
7666void
7667ctk_entry_get_text_area (CtkEntry *entry,
7668 CdkRectangle *text_area)
7669{
7670 CtkEntryPrivate *priv;
7671
7672 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
7673 g_return_if_fail (text_area != NULL)do { if ((text_area != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "text_area != NULL"); return
; } } while (0)
;
7674
7675 priv = entry->priv;
7676
7677 if (ctk_widget_get_realized (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
7678 {
7679 CtkAllocation allocation;
7680
7681 *text_area = priv->text_allocation;
7682
7683 ctk_widget_get_allocation (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, &allocation);
7684 text_area->x -= allocation.x;
7685 text_area->y -= allocation.y;
7686 }
7687 else
7688 {
7689 text_area->x = 0;
7690 text_area->y = 0;
7691 text_area->width = 0;
7692 text_area->height = 0;
7693 }
7694}
7695
7696/**
7697 * ctk_entry_set_text:
7698 * @entry: a #CtkEntry
7699 * @text: the new text
7700 *
7701 * Sets the text in the widget to the given
7702 * value, replacing the current contents.
7703 *
7704 * See ctk_entry_buffer_set_text().
7705 */
7706void
7707ctk_entry_set_text (CtkEntry *entry,
7708 const gchar *text)
7709{
7710 gint tmp_pos;
7711 CtkEntryCompletion *completion;
7712
7713 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
7714 g_return_if_fail (text != NULL)do { if ((text != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "text != NULL"); return;
} } while (0)
;
7715
7716 /* Actually setting the text will affect the cursor and selection;
7717 * if the contents don't actually change, this will look odd to the user.
7718 */
7719 if (strcmp (ctk_entry_buffer_get_text (get_buffer (entry)), text) == 0)
7720 return;
7721
7722 completion = ctk_entry_get_completion (entry);
7723 if (completion && completion->priv->changed_id > 0)
7724 g_signal_handler_block (entry, completion->priv->changed_id);
7725
7726 begin_change (entry);
7727 ctk_editable_delete_text (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, 0, -1);
7728 tmp_pos = 0;
7729 ctk_editable_insert_text (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, text, strlen (text), &tmp_pos);
7730 end_change (entry);
7731
7732 if (completion && completion->priv->changed_id > 0)
7733 g_signal_handler_unblock (entry, completion->priv->changed_id);
7734}
7735
7736/**
7737 * ctk_entry_set_visibility:
7738 * @entry: a #CtkEntry
7739 * @visible: %TRUE if the contents of the entry are displayed
7740 * as plaintext
7741 *
7742 * Sets whether the contents of the entry are visible or not.
7743 * When visibility is set to %FALSE, characters are displayed
7744 * as the invisible char, and will also appear that way when
7745 * the text in the entry widget is copied elsewhere.
7746 *
7747 * By default, CTK+ picks the best invisible character available
7748 * in the current font, but it can be changed with
7749 * ctk_entry_set_invisible_char().
7750 *
7751 * Note that you probably want to set #CtkEntry:input-purpose
7752 * to %CTK_INPUT_PURPOSE_PASSWORD or %CTK_INPUT_PURPOSE_PIN to
7753 * inform input methods about the purpose of this entry,
7754 * in addition to setting visibility to %FALSE.
7755 */
7756void
7757ctk_entry_set_visibility (CtkEntry *entry,
7758 gboolean visible)
7759{
7760 CtkEntryPrivate *priv;
7761
7762 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
7763
7764 priv = entry->priv;
7765
7766 visible = visible != FALSE(0);
7767
7768 if (priv->visible != visible)
7769 {
7770 priv->visible = visible;
7771
7772 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_VISIBILITY]);
7773 ctk_entry_recompute (entry);
7774 }
7775}
7776
7777/**
7778 * ctk_entry_get_visibility:
7779 * @entry: a #CtkEntry
7780 *
7781 * Retrieves whether the text in @entry is visible. See
7782 * ctk_entry_set_visibility().
7783 *
7784 * Returns: %TRUE if the text is currently visible
7785 **/
7786gboolean
7787ctk_entry_get_visibility (CtkEntry *entry)
7788{
7789 g_return_val_if_fail (CTK_IS_ENTRY (entry), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return ((0)); } } while (0)
;
7790
7791 return entry->priv->visible;
7792}
7793
7794/**
7795 * ctk_entry_set_invisible_char:
7796 * @entry: a #CtkEntry
7797 * @ch: a Unicode character
7798 *
7799 * Sets the character to use in place of the actual text when
7800 * ctk_entry_set_visibility() has been called to set text visibility
7801 * to %FALSE. i.e. this is the character used in “password mode” to
7802 * show the user how many characters have been typed. By default, CTK+
7803 * picks the best invisible char available in the current font. If you
7804 * set the invisible char to 0, then the user will get no feedback
7805 * at all; there will be no text on the screen as they type.
7806 **/
7807void
7808ctk_entry_set_invisible_char (CtkEntry *entry,
7809 gunichar ch)
7810{
7811 CtkEntryPrivate *priv;
7812
7813 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
7814
7815 priv = entry->priv;
7816
7817 if (!priv->invisible_char_set)
7818 {
7819 priv->invisible_char_set = TRUE(!(0));
7820 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_INVISIBLE_CHAR_SET]);
7821 }
7822
7823 if (ch == priv->invisible_char)
7824 return;
7825
7826 priv->invisible_char = ch;
7827 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_INVISIBLE_CHAR]);
7828 ctk_entry_recompute (entry);
7829}
7830
7831/**
7832 * ctk_entry_get_invisible_char:
7833 * @entry: a #CtkEntry
7834 *
7835 * Retrieves the character displayed in place of the real characters
7836 * for entries with visibility set to false. See ctk_entry_set_invisible_char().
7837 *
7838 * Returns: the current invisible char, or 0, if the entry does not
7839 * show invisible text at all.
7840 **/
7841gunichar
7842ctk_entry_get_invisible_char (CtkEntry *entry)
7843{
7844 g_return_val_if_fail (CTK_IS_ENTRY (entry), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (0); } } while (0)
;
7845
7846 return entry->priv->invisible_char;
7847}
7848
7849/**
7850 * ctk_entry_unset_invisible_char:
7851 * @entry: a #CtkEntry
7852 *
7853 * Unsets the invisible char previously set with
7854 * ctk_entry_set_invisible_char(). So that the
7855 * default invisible char is used again.
7856 *
7857 * Since: 2.16
7858 **/
7859void
7860ctk_entry_unset_invisible_char (CtkEntry *entry)
7861{
7862 CtkEntryPrivate *priv;
7863 gunichar ch;
7864
7865 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
7866
7867 priv = entry->priv;
7868
7869 if (!priv->invisible_char_set)
7870 return;
7871
7872 priv->invisible_char_set = FALSE(0);
7873 ch = find_invisible_char (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
7874
7875 if (priv->invisible_char != ch)
7876 {
7877 priv->invisible_char = ch;
7878 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_INVISIBLE_CHAR]);
7879 }
7880
7881 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_INVISIBLE_CHAR_SET]);
7882 ctk_entry_recompute (entry);
7883}
7884
7885/**
7886 * ctk_entry_set_overwrite_mode:
7887 * @entry: a #CtkEntry
7888 * @overwrite: new value
7889 *
7890 * Sets whether the text is overwritten when typing in the #CtkEntry.
7891 *
7892 * Since: 2.14
7893 **/
7894void
7895ctk_entry_set_overwrite_mode (CtkEntry *entry,
7896 gboolean overwrite)
7897{
7898 CtkEntryPrivate *priv = entry->priv;
7899
7900 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
7901
7902 if (priv->overwrite_mode == overwrite)
7903 return;
7904
7905 ctk_entry_toggle_overwrite (entry);
7906
7907 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_OVERWRITE_MODE]);
7908}
7909
7910/**
7911 * ctk_entry_get_overwrite_mode:
7912 * @entry: a #CtkEntry
7913 *
7914 * Gets the value set by ctk_entry_set_overwrite_mode().
7915 *
7916 * Returns: whether the text is overwritten when typing.
7917 *
7918 * Since: 2.14
7919 **/
7920gboolean
7921ctk_entry_get_overwrite_mode (CtkEntry *entry)
7922{
7923 g_return_val_if_fail (CTK_IS_ENTRY (entry), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return ((0)); } } while (0)
;
7924
7925 return entry->priv->overwrite_mode;
7926}
7927
7928/**
7929 * ctk_entry_get_text:
7930 * @entry: a #CtkEntry
7931 *
7932 * Retrieves the contents of the entry widget.
7933 * See also ctk_editable_get_chars().
7934 *
7935 * This is equivalent to getting @entry's #CtkEntryBuffer and calling
7936 * ctk_entry_buffer_get_text() on it.
7937 *
7938 * Returns: a pointer to the contents of the widget as a
7939 * string. This string points to internally allocated
7940 * storage in the widget and must not be freed, modified or
7941 * stored.
7942 **/
7943const gchar*
7944ctk_entry_get_text (CtkEntry *entry)
7945{
7946 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
7947
7948 return ctk_entry_buffer_get_text (get_buffer (entry));
7949}
7950
7951/**
7952 * ctk_entry_set_max_length:
7953 * @entry: a #CtkEntry
7954 * @max: the maximum length of the entry, or 0 for no maximum.
7955 * (other than the maximum length of entries.) The value passed in will
7956 * be clamped to the range 0-65536.
7957 *
7958 * Sets the maximum allowed length of the contents of the widget. If
7959 * the current contents are longer than the given length, then they
7960 * will be truncated to fit.
7961 *
7962 * This is equivalent to getting @entry's #CtkEntryBuffer and
7963 * calling ctk_entry_buffer_set_max_length() on it.
7964 * ]|
7965 **/
7966void
7967ctk_entry_set_max_length (CtkEntry *entry,
7968 gint max)
7969{
7970 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
7971 ctk_entry_buffer_set_max_length (get_buffer (entry), max);
7972}
7973
7974/**
7975 * ctk_entry_get_max_length:
7976 * @entry: a #CtkEntry
7977 *
7978 * Retrieves the maximum allowed length of the text in
7979 * @entry. See ctk_entry_set_max_length().
7980 *
7981 * This is equivalent to getting @entry's #CtkEntryBuffer and
7982 * calling ctk_entry_buffer_get_max_length() on it.
7983 *
7984 * Returns: the maximum allowed number of characters
7985 * in #CtkEntry, or 0 if there is no maximum.
7986 **/
7987gint
7988ctk_entry_get_max_length (CtkEntry *entry)
7989{
7990 g_return_val_if_fail (CTK_IS_ENTRY (entry), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (0); } } while (0)
;
7991
7992 return ctk_entry_buffer_get_max_length (get_buffer (entry));
7993}
7994
7995/**
7996 * ctk_entry_get_text_length:
7997 * @entry: a #CtkEntry
7998 *
7999 * Retrieves the current length of the text in
8000 * @entry.
8001 *
8002 * This is equivalent to getting @entry's #CtkEntryBuffer and
8003 * calling ctk_entry_buffer_get_length() on it.
8004
8005 *
8006 * Returns: the current number of characters
8007 * in #CtkEntry, or 0 if there are none.
8008 *
8009 * Since: 2.14
8010 **/
8011guint16
8012ctk_entry_get_text_length (CtkEntry *entry)
8013{
8014 g_return_val_if_fail (CTK_IS_ENTRY (entry), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (0); } } while (0)
;
8015
8016 return ctk_entry_buffer_get_length (get_buffer (entry));
8017}
8018
8019/**
8020 * ctk_entry_set_activates_default:
8021 * @entry: a #CtkEntry
8022 * @setting: %TRUE to activate window’s default widget on Enter keypress
8023 *
8024 * If @setting is %TRUE, pressing Enter in the @entry will activate the default
8025 * widget for the window containing the entry. This usually means that
8026 * the dialog box containing the entry will be closed, since the default
8027 * widget is usually one of the dialog buttons.
8028 *
8029 * (For experts: if @setting is %TRUE, the entry calls
8030 * ctk_window_activate_default() on the window containing the entry, in
8031 * the default handler for the #CtkEntry::activate signal.)
8032 **/
8033void
8034ctk_entry_set_activates_default (CtkEntry *entry,
8035 gboolean setting)
8036{
8037 CtkEntryPrivate *priv;
8038
8039 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
8040
8041 priv = entry->priv;
8042
8043 setting = setting != FALSE(0);
8044
8045 if (setting != priv->activates_default)
8046 {
8047 priv->activates_default = setting;
8048 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_ACTIVATES_DEFAULT]);
8049 }
8050}
8051
8052/**
8053 * ctk_entry_get_activates_default:
8054 * @entry: a #CtkEntry
8055 *
8056 * Retrieves the value set by ctk_entry_set_activates_default().
8057 *
8058 * Returns: %TRUE if the entry will activate the default widget
8059 */
8060gboolean
8061ctk_entry_get_activates_default (CtkEntry *entry)
8062{
8063 g_return_val_if_fail (CTK_IS_ENTRY (entry), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return ((0)); } } while (0)
;
8064
8065 return entry->priv->activates_default;
8066}
8067
8068/**
8069 * ctk_entry_set_width_chars:
8070 * @entry: a #CtkEntry
8071 * @n_chars: width in chars
8072 *
8073 * Changes the size request of the entry to be about the right size
8074 * for @n_chars characters. Note that it changes the size
8075 * request, the size can still be affected by
8076 * how you pack the widget into containers. If @n_chars is -1, the
8077 * size reverts to the default entry size.
8078 **/
8079void
8080ctk_entry_set_width_chars (CtkEntry *entry,
8081 gint n_chars)
8082{
8083 CtkEntryPrivate *priv;
8084
8085 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
8086
8087 priv = entry->priv;
8088
8089 if (priv->width_chars != n_chars)
8090 {
8091 priv->width_chars = n_chars;
8092 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_WIDTH_CHARS]);
8093 ctk_widget_queue_resize (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
8094 }
8095}
8096
8097/**
8098 * ctk_entry_get_width_chars:
8099 * @entry: a #CtkEntry
8100 *
8101 * Gets the value set by ctk_entry_set_width_chars().
8102 *
8103 * Returns: number of chars to request space for, or negative if unset
8104 **/
8105gint
8106ctk_entry_get_width_chars (CtkEntry *entry)
8107{
8108 g_return_val_if_fail (CTK_IS_ENTRY (entry), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (0); } } while (0)
;
8109
8110 return entry->priv->width_chars;
8111}
8112
8113/**
8114 * ctk_entry_set_max_width_chars:
8115 * @entry: a #CtkEntry
8116 * @n_chars: the new desired maximum width, in characters
8117 *
8118 * Sets the desired maximum width in characters of @entry.
8119 *
8120 * Since: 3.12
8121 */
8122void
8123ctk_entry_set_max_width_chars (CtkEntry *entry,
8124 gint n_chars)
8125{
8126 CtkEntryPrivate *priv;
8127
8128 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
8129
8130 priv = entry->priv;
8131
8132 if (priv->max_width_chars != n_chars)
8133 {
8134 priv->max_width_chars = n_chars;
8135 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_MAX_WIDTH_CHARS]);
8136 ctk_widget_queue_resize (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
8137 }
8138}
8139
8140/**
8141 * ctk_entry_get_max_width_chars:
8142 * @entry: a #CtkEntry
8143 *
8144 * Retrieves the desired maximum width of @entry, in characters.
8145 * See ctk_entry_set_max_width_chars().
8146 *
8147 * Returns: the maximum width of the entry, in characters
8148 *
8149 * Since: 3.12
8150 */
8151gint
8152ctk_entry_get_max_width_chars (CtkEntry *entry)
8153{
8154 g_return_val_if_fail (CTK_IS_ENTRY (entry), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (0); } } while (0)
;
8155
8156 return entry->priv->max_width_chars;
8157}
8158
8159/**
8160 * ctk_entry_set_has_frame:
8161 * @entry: a #CtkEntry
8162 * @setting: new value
8163 *
8164 * Sets whether the entry has a beveled frame around it.
8165 **/
8166void
8167ctk_entry_set_has_frame (CtkEntry *entry,
8168 gboolean setting)
8169{
8170 CtkStyleContext *context;
8171
8172 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
8173
8174 setting = (setting != FALSE(0));
8175
8176 if (setting == ctk_entry_get_has_frame (entry))
8177 return;
8178
8179 context = ctk_widget_get_style_context (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
8180 if (setting)
8181 ctk_style_context_remove_class (context, CTK_STYLE_CLASS_FLAT"flat");
8182 else
8183 ctk_style_context_add_class (context, CTK_STYLE_CLASS_FLAT"flat");
8184 ctk_widget_queue_draw (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
8185 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_HAS_FRAME]);
8186}
8187
8188/**
8189 * ctk_entry_get_has_frame:
8190 * @entry: a #CtkEntry
8191 *
8192 * Gets the value set by ctk_entry_set_has_frame().
8193 *
8194 * Returns: whether the entry has a beveled frame
8195 **/
8196gboolean
8197ctk_entry_get_has_frame (CtkEntry *entry)
8198{
8199 CtkStyleContext *context;
8200
8201 g_return_val_if_fail (CTK_IS_ENTRY (entry), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return ((0)); } } while (0)
;
8202
8203 context = ctk_widget_get_style_context (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
8204
8205 return !ctk_style_context_has_class (context, CTK_STYLE_CLASS_FLAT"flat");
8206}
8207
8208/**
8209 * ctk_entry_set_inner_border:
8210 * @entry: a #CtkEntry
8211 * @border: (allow-none): a #CtkBorder, or %NULL
8212 *
8213 * Sets %entry’s inner-border property to @border, or clears it if %NULL
8214 * is passed. The inner-border is the area around the entry’s text, but
8215 * inside its frame.
8216 *
8217 * If set, this property overrides the inner-border style property.
8218 * Overriding the style-provided border is useful when you want to do
8219 * in-place editing of some text in a canvas or list widget, where
8220 * pixel-exact positioning of the entry is important.
8221 *
8222 * Since: 2.10
8223 *
8224 * Deprecated: 3.4: Use the standard border and padding CSS properties (through
8225 * objects like #CtkStyleContext and #CtkCssProvider); the value set with
8226 * this function is ignored by #CtkEntry.
8227 **/
8228void
8229ctk_entry_set_inner_border (CtkEntry *entry,
8230 const CtkBorder *border)
8231{
8232 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
8233
8234 ctk_entry_do_set_inner_border (entry, border);
8235}
8236
8237/**
8238 * ctk_entry_get_inner_border:
8239 * @entry: a #CtkEntry
8240 *
8241 * This function returns the entry’s #CtkEntry:inner-border property. See
8242 * ctk_entry_set_inner_border() for more information.
8243 *
8244 * Returns: (nullable) (transfer none): the entry’s #CtkBorder, or
8245 * %NULL if none was set.
8246 *
8247 * Since: 2.10
8248 *
8249 * Deprecated: 3.4: Use the standard border and padding CSS properties (through
8250 * objects like #CtkStyleContext and #CtkCssProvider); the value returned by
8251 * this function is ignored by #CtkEntry.
8252 **/
8253const CtkBorder *
8254ctk_entry_get_inner_border (CtkEntry *entry)
8255{
8256 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
8257
8258 return ctk_entry_do_get_inner_border (entry);
8259}
8260
8261/**
8262 * ctk_entry_get_layout:
8263 * @entry: a #CtkEntry
8264 *
8265 * Gets the #PangoLayout used to display the entry.
8266 * The layout is useful to e.g. convert text positions to
8267 * pixel positions, in combination with ctk_entry_get_layout_offsets().
8268 * The returned layout is owned by the entry and must not be
8269 * modified or freed by the caller.
8270 *
8271 * Keep in mind that the layout text may contain a preedit string, so
8272 * ctk_entry_layout_index_to_text_index() and
8273 * ctk_entry_text_index_to_layout_index() are needed to convert byte
8274 * indices in the layout to byte indices in the entry contents.
8275 *
8276 * Returns: (transfer none): the #PangoLayout for this entry
8277 **/
8278PangoLayout*
8279ctk_entry_get_layout (CtkEntry *entry)
8280{
8281 PangoLayout *layout;
8282
8283 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
8284
8285 layout = ctk_entry_ensure_layout (entry, TRUE(!(0)));
8286
8287 return layout;
8288}
8289
8290
8291/**
8292 * ctk_entry_layout_index_to_text_index:
8293 * @entry: a #CtkEntry
8294 * @layout_index: byte index into the entry layout text
8295 *
8296 * Converts from a position in the entry’s #PangoLayout (returned by
8297 * ctk_entry_get_layout()) to a position in the entry contents
8298 * (returned by ctk_entry_get_text()).
8299 *
8300 * Returns: byte index into the entry contents
8301 **/
8302gint
8303ctk_entry_layout_index_to_text_index (CtkEntry *entry,
8304 gint layout_index)
8305{
8306 CtkEntryPrivate *priv;
8307 PangoLayout *layout;
8308 const gchar *text;
8309 gint cursor_index;
8310
8311 g_return_val_if_fail (CTK_IS_ENTRY (entry), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (0); } } while (0)
;
8312
8313 priv = entry->priv;
8314
8315 layout = ctk_entry_ensure_layout (entry, TRUE(!(0)));
8316 text = pango_layout_get_text (layout);
8317 cursor_index = g_utf8_offset_to_pointer (text, priv->current_pos) - text;
8318
8319 if (layout_index >= cursor_index && priv->preedit_length)
8320 {
8321 if (layout_index >= cursor_index + priv->preedit_length)
8322 layout_index -= priv->preedit_length;
8323 else
8324 layout_index = cursor_index;
8325 }
8326
8327 return layout_index;
8328}
8329
8330/**
8331 * ctk_entry_text_index_to_layout_index:
8332 * @entry: a #CtkEntry
8333 * @text_index: byte index into the entry contents
8334 *
8335 * Converts from a position in the entry contents (returned
8336 * by ctk_entry_get_text()) to a position in the
8337 * entry’s #PangoLayout (returned by ctk_entry_get_layout(),
8338 * with text retrieved via pango_layout_get_text()).
8339 *
8340 * Returns: byte index into the entry layout text
8341 **/
8342gint
8343ctk_entry_text_index_to_layout_index (CtkEntry *entry,
8344 gint text_index)
8345{
8346 CtkEntryPrivate *priv;
8347 PangoLayout *layout;
8348 const gchar *text;
8349 gint cursor_index;
8350
8351 g_return_val_if_fail (CTK_IS_ENTRY (entry), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (0); } } while (0)
;
8352
8353 priv = entry->priv;
8354
8355 layout = ctk_entry_ensure_layout (entry, TRUE(!(0)));
8356 text = pango_layout_get_text (layout);
8357 cursor_index = g_utf8_offset_to_pointer (text, priv->current_pos) - text;
8358
8359 if (text_index > cursor_index)
8360 text_index += priv->preedit_length;
8361
8362 return text_index;
8363}
8364
8365/**
8366 * ctk_entry_get_layout_offsets:
8367 * @entry: a #CtkEntry
8368 * @x: (out) (allow-none): location to store X offset of layout, or %NULL
8369 * @y: (out) (allow-none): location to store Y offset of layout, or %NULL
8370 *
8371 *
8372 * Obtains the position of the #PangoLayout used to render text
8373 * in the entry, in widget coordinates. Useful if you want to line
8374 * up the text in an entry with some other text, e.g. when using the
8375 * entry to implement editable cells in a sheet widget.
8376 *
8377 * Also useful to convert mouse events into coordinates inside the
8378 * #PangoLayout, e.g. to take some action if some part of the entry text
8379 * is clicked.
8380 *
8381 * Note that as the user scrolls around in the entry the offsets will
8382 * change; you’ll need to connect to the “notify::scroll-offset”
8383 * signal to track this. Remember when using the #PangoLayout
8384 * functions you need to convert to and from pixels using
8385 * PANGO_PIXELS() or #PANGO_SCALE.
8386 *
8387 * Keep in mind that the layout text may contain a preedit string, so
8388 * ctk_entry_layout_index_to_text_index() and
8389 * ctk_entry_text_index_to_layout_index() are needed to convert byte
8390 * indices in the layout to byte indices in the entry contents.
8391 **/
8392void
8393ctk_entry_get_layout_offsets (CtkEntry *entry,
8394 gint *x,
8395 gint *y)
8396{
8397 CtkEntryPrivate *priv;
8398 CtkAllocation allocation;
8399
8400 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
8401
8402 priv = entry->priv;
8403 ctk_widget_get_allocation (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, &allocation);
8404
8405 /* this gets coords relative to text area */
8406 get_layout_position (entry, x, y);
8407
8408 /* convert to widget coords */
8409 if (x)
8410 *x += priv->text_allocation.x - allocation.x;
8411
8412 if (y)
8413 *y += priv->text_allocation.y - allocation.y;
8414}
8415
8416
8417/**
8418 * ctk_entry_set_alignment:
8419 * @entry: a #CtkEntry
8420 * @xalign: The horizontal alignment, from 0 (left) to 1 (right).
8421 * Reversed for RTL layouts
8422 *
8423 * Sets the alignment for the contents of the entry. This controls
8424 * the horizontal positioning of the contents when the displayed
8425 * text is shorter than the width of the entry.
8426 *
8427 * Since: 2.4
8428 **/
8429void
8430ctk_entry_set_alignment (CtkEntry *entry, gfloat xalign)
8431{
8432 CtkEntryPrivate *priv;
8433
8434 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
8435
8436 priv = entry->priv;
8437
8438 if (xalign < 0.0)
8439 xalign = 0.0;
8440 else if (xalign > 1.0)
8441 xalign = 1.0;
8442
8443 if (xalign != priv->xalign)
8444 {
8445 priv->xalign = xalign;
8446 ctk_entry_recompute (entry);
8447 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_XALIGN]);
8448 }
8449}
8450
8451/**
8452 * ctk_entry_get_alignment:
8453 * @entry: a #CtkEntry
8454 *
8455 * Gets the value set by ctk_entry_set_alignment().
8456 *
8457 * Returns: the alignment
8458 *
8459 * Since: 2.4
8460 **/
8461gfloat
8462ctk_entry_get_alignment (CtkEntry *entry)
8463{
8464 g_return_val_if_fail (CTK_IS_ENTRY (entry), 0.0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (0.0); } } while (0)
;
8465
8466 return entry->priv->xalign;
8467}
8468
8469/**
8470 * ctk_entry_set_icon_from_pixbuf:
8471 * @entry: a #CtkEntry
8472 * @icon_pos: Icon position
8473 * @pixbuf: (allow-none): A #GdkPixbuf, or %NULL
8474 *
8475 * Sets the icon shown in the specified position using a pixbuf.
8476 *
8477 * If @pixbuf is %NULL, no icon will be shown in the specified position.
8478 *
8479 * Since: 2.16
8480 */
8481void
8482ctk_entry_set_icon_from_pixbuf (CtkEntry *entry,
8483 CtkEntryIconPosition icon_pos,
8484 GdkPixbuf *pixbuf)
8485{
8486 CtkEntryPrivate *priv;
8487 EntryIconInfo *icon_info;
8488
8489 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
8490 g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos))do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return; } } while (0)
;
8491
8492 priv = entry->priv;
8493
8494 if ((icon_info = priv->icons[icon_pos]) == NULL((void*)0))
8495 icon_info = construct_icon_info (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, icon_pos);
8496
8497 g_object_freeze_notify (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
8498
8499 if (pixbuf)
8500 g_object_ref (pixbuf)((__typeof__ (pixbuf)) (g_object_ref) (pixbuf));
8501
8502 if (pixbuf)
8503 {
8504 _ctk_icon_helper_set_pixbuf (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
, pixbuf);
8505 _ctk_icon_helper_set_icon_size (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
,
8506 CTK_ICON_SIZE_MENU);
8507
8508 if (icon_pos == CTK_ENTRY_ICON_PRIMARY)
8509 {
8510 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_PIXBUF_PRIMARY]);
8511 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_STORAGE_TYPE_PRIMARY]);
8512 }
8513 else
8514 {
8515 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_PIXBUF_SECONDARY]);
8516 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_STORAGE_TYPE_SECONDARY]);
8517 }
8518
8519 if (ctk_widget_get_mapped (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
8520 cdk_window_show_unraised (icon_info->window);
8521
8522 g_object_unref (pixbuf);
8523 }
8524 else
8525 ctk_entry_clear_icon (entry, icon_pos);
8526
8527 if (ctk_widget_get_visible (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
8528 ctk_widget_queue_resize (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
8529
8530 g_object_thaw_notify (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
8531}
8532
8533/**
8534 * ctk_entry_set_icon_from_stock:
8535 * @entry: A #CtkEntry
8536 * @icon_pos: Icon position
8537 * @stock_id: (allow-none): The name of the stock item, or %NULL
8538 *
8539 * Sets the icon shown in the entry at the specified position from
8540 * a stock image.
8541 *
8542 * If @stock_id is %NULL, no icon will be shown in the specified position.
8543 *
8544 * Since: 2.16
8545 *
8546 * Deprecated: 3.10: Use ctk_entry_set_icon_from_icon_name() instead.
8547 */
8548void
8549ctk_entry_set_icon_from_stock (CtkEntry *entry,
8550 CtkEntryIconPosition icon_pos,
8551 const gchar *stock_id)
8552{
8553 CtkEntryPrivate *priv;
8554 EntryIconInfo *icon_info;
8555
8556 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
8557 g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos))do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return; } } while (0)
;
8558
8559 priv = entry->priv;
8560
8561 if ((icon_info = priv->icons[icon_pos]) == NULL((void*)0))
8562 icon_info = construct_icon_info (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, icon_pos);
8563
8564 g_object_freeze_notify (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
8565
8566 if (stock_id != NULL((void*)0))
8567 {
8568 _ctk_icon_helper_set_stock_id (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
, stock_id, CTK_ICON_SIZE_MENU);
8569
8570 if (icon_pos == CTK_ENTRY_ICON_PRIMARY)
8571 {
8572 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_STOCK_PRIMARY]);
8573 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_STORAGE_TYPE_PRIMARY]);
8574 }
8575 else
8576 {
8577 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_STOCK_SECONDARY]);
8578 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_STORAGE_TYPE_SECONDARY]);
8579 }
8580
8581 if (ctk_widget_get_mapped (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
8582 cdk_window_show_unraised (icon_info->window);
8583 }
8584 else
8585 ctk_entry_clear_icon (entry, icon_pos);
8586
8587 if (ctk_widget_get_visible (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
8588 ctk_widget_queue_resize (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
8589
8590 g_object_thaw_notify (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
8591}
8592
8593/**
8594 * ctk_entry_set_icon_from_icon_name:
8595 * @entry: A #CtkEntry
8596 * @icon_pos: The position at which to set the icon
8597 * @icon_name: (allow-none): An icon name, or %NULL
8598 *
8599 * Sets the icon shown in the entry at the specified position
8600 * from the current icon theme.
8601 *
8602 * If the icon name isn’t known, a “broken image” icon will be displayed
8603 * instead.
8604 *
8605 * If @icon_name is %NULL, no icon will be shown in the specified position.
8606 *
8607 * Since: 2.16
8608 */
8609void
8610ctk_entry_set_icon_from_icon_name (CtkEntry *entry,
8611 CtkEntryIconPosition icon_pos,
8612 const gchar *icon_name)
8613{
8614 CtkEntryPrivate *priv;
8615 EntryIconInfo *icon_info;
8616
8617 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
8618 g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos))do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return; } } while (0)
;
8619
8620 priv = entry->priv;
8621
8622 if ((icon_info = priv->icons[icon_pos]) == NULL((void*)0))
8623 icon_info = construct_icon_info (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, icon_pos);
8624
8625 g_object_freeze_notify (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
8626
8627
8628 if (icon_name != NULL((void*)0))
8629 {
8630 _ctk_icon_helper_set_icon_name (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
, icon_name, CTK_ICON_SIZE_MENU);
8631
8632 if (icon_pos == CTK_ENTRY_ICON_PRIMARY)
8633 {
8634 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_ICON_NAME_PRIMARY]);
8635 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_STORAGE_TYPE_PRIMARY]);
8636 }
8637 else
8638 {
8639 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_ICON_NAME_SECONDARY]);
8640 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_STORAGE_TYPE_SECONDARY]);
8641 }
8642
8643 if (ctk_widget_get_mapped (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
8644 cdk_window_show_unraised (icon_info->window);
8645 }
8646 else
8647 ctk_entry_clear_icon (entry, icon_pos);
8648
8649 if (ctk_widget_get_visible (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
8650 ctk_widget_queue_resize (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
8651
8652 g_object_thaw_notify (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
8653}
8654
8655/**
8656 * ctk_entry_set_icon_from_gicon:
8657 * @entry: A #CtkEntry
8658 * @icon_pos: The position at which to set the icon
8659 * @icon: (allow-none): The icon to set, or %NULL
8660 *
8661 * Sets the icon shown in the entry at the specified position
8662 * from the current icon theme.
8663 * If the icon isn’t known, a “broken image” icon will be displayed
8664 * instead.
8665 *
8666 * If @icon is %NULL, no icon will be shown in the specified position.
8667 *
8668 * Since: 2.16
8669 */
8670void
8671ctk_entry_set_icon_from_gicon (CtkEntry *entry,
8672 CtkEntryIconPosition icon_pos,
8673 GIcon *icon)
8674{
8675 CtkEntryPrivate *priv;
8676 EntryIconInfo *icon_info;
8677
8678 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
8679 g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos))do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return; } } while (0)
;
8680
8681 priv = entry->priv;
8682
8683 if ((icon_info = priv->icons[icon_pos]) == NULL((void*)0))
8684 icon_info = construct_icon_info (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, icon_pos);
8685
8686 g_object_freeze_notify (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
8687
8688 if (icon)
8689 {
8690 _ctk_icon_helper_set_gicon (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
, icon, CTK_ICON_SIZE_MENU);
8691
8692 if (icon_pos == CTK_ENTRY_ICON_PRIMARY)
8693 {
8694 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_GICON_PRIMARY]);
8695 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_STORAGE_TYPE_PRIMARY]);
8696 }
8697 else
8698 {
8699 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_GICON_SECONDARY]);
8700 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_STORAGE_TYPE_SECONDARY]);
8701 }
8702
8703 if (ctk_widget_get_mapped (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
8704 cdk_window_show_unraised (icon_info->window);
8705 }
8706 else
8707 ctk_entry_clear_icon (entry, icon_pos);
8708
8709 if (ctk_widget_get_visible (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
8710 ctk_widget_queue_resize (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
8711
8712 g_object_thaw_notify (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
);
8713}
8714
8715/**
8716 * ctk_entry_set_icon_activatable:
8717 * @entry: A #CtkEntry
8718 * @icon_pos: Icon position
8719 * @activatable: %TRUE if the icon should be activatable
8720 *
8721 * Sets whether the icon is activatable.
8722 *
8723 * Since: 2.16
8724 */
8725void
8726ctk_entry_set_icon_activatable (CtkEntry *entry,
8727 CtkEntryIconPosition icon_pos,
8728 gboolean activatable)
8729{
8730 CtkEntryPrivate *priv;
8731 EntryIconInfo *icon_info;
8732
8733 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
8734 g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos))do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return; } } while (0)
;
8735
8736 priv = entry->priv;
8737
8738 if ((icon_info = priv->icons[icon_pos]) == NULL((void*)0))
8739 icon_info = construct_icon_info (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, icon_pos);
8740
8741 activatable = activatable != FALSE(0);
8742
8743 if (icon_info->nonactivatable != !activatable)
8744 {
8745 icon_info->nonactivatable = !activatable;
8746
8747 if (ctk_widget_get_realized (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
8748 update_cursors (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
8749
8750 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
,
8751 entry_props[icon_pos == CTK_ENTRY_ICON_PRIMARY
8752 ? PROP_ACTIVATABLE_PRIMARY
8753 : PROP_ACTIVATABLE_SECONDARY]);
8754 }
8755}
8756
8757/**
8758 * ctk_entry_get_icon_activatable:
8759 * @entry: a #CtkEntry
8760 * @icon_pos: Icon position
8761 *
8762 * Returns whether the icon is activatable.
8763 *
8764 * Returns: %TRUE if the icon is activatable.
8765 *
8766 * Since: 2.16
8767 */
8768gboolean
8769ctk_entry_get_icon_activatable (CtkEntry *entry,
8770 CtkEntryIconPosition icon_pos)
8771{
8772 CtkEntryPrivate *priv;
8773 EntryIconInfo *icon_info;
8774
8775 g_return_val_if_fail (CTK_IS_ENTRY (entry), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return ((0)); } } while (0)
;
8776 g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), FALSE)do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return ((0)); } } while (0)
;
8777
8778 priv = entry->priv;
8779 icon_info = priv->icons[icon_pos];
8780
8781 return (!icon_info || !icon_info->nonactivatable);
8782}
8783
8784/**
8785 * ctk_entry_get_icon_pixbuf:
8786 * @entry: A #CtkEntry
8787 * @icon_pos: Icon position
8788 *
8789 * Retrieves the image used for the icon.
8790 *
8791 * Unlike the other methods of setting and getting icon data, this
8792 * method will work regardless of whether the icon was set using a
8793 * #GdkPixbuf, a #GIcon, a stock item, or an icon name.
8794 *
8795 * Returns: (transfer none) (nullable): A #GdkPixbuf, or %NULL if no icon is
8796 * set for this position.
8797 *
8798 * Since: 2.16
8799 */
8800GdkPixbuf *
8801ctk_entry_get_icon_pixbuf (CtkEntry *entry,
8802 CtkEntryIconPosition icon_pos)
8803{
8804 CtkEntryPrivate *priv;
8805 EntryIconInfo *icon_info;
8806 cairo_surface_t *surface;
8807 GdkPixbuf *pixbuf;
8808 int width, height;
8809
8810 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
8811 g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL)do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return (((void*)0)); } } while (0)
;
8812
8813 priv = entry->priv;
8814
8815 icon_info = priv->icons[icon_pos];
8816
8817 if (!icon_info)
8818 return NULL((void*)0);
8819
8820 _ctk_icon_helper_get_size (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
, &width, &height);
8821 surface = ctk_icon_helper_load_surface (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
, 1);
8822
8823 pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
8824
8825 cairo_surface_destroy (surface);
8826
8827 /* HACK: unfortunately this is transfer none, so we attach it somehwere
8828 * convenient.
8829 */
8830 if (pixbuf)
8831 {
8832 g_object_set_data_full (G_OBJECT (icon_info->gadget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (((GType) ((20) << (2)))))
)))
,
8833 "ctk-entry-pixbuf",
8834 pixbuf,
8835 g_object_unref);
8836 }
8837
8838 return pixbuf;
8839}
8840
8841/**
8842 * ctk_entry_get_icon_gicon:
8843 * @entry: A #CtkEntry
8844 * @icon_pos: Icon position
8845 *
8846 * Retrieves the #GIcon used for the icon, or %NULL if there is
8847 * no icon or if the icon was set by some other method (e.g., by
8848 * stock, pixbuf, or icon name).
8849 *
8850 * Returns: (transfer none) (nullable): A #GIcon, or %NULL if no icon is set
8851 * or if the icon is not a #GIcon
8852 *
8853 * Since: 2.16
8854 */
8855GIcon *
8856ctk_entry_get_icon_gicon (CtkEntry *entry,
8857 CtkEntryIconPosition icon_pos)
8858{
8859 CtkEntryPrivate *priv;
8860 EntryIconInfo *icon_info;
8861
8862 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
8863 g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL)do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return (((void*)0)); } } while (0)
;
8864
8865 priv = entry->priv;
8866 icon_info = priv->icons[icon_pos];
8867
8868 if (!icon_info)
8869 return NULL((void*)0);
8870
8871 return _ctk_icon_helper_peek_gicon (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
);
8872}
8873
8874/**
8875 * ctk_entry_get_icon_stock:
8876 * @entry: A #CtkEntry
8877 * @icon_pos: Icon position
8878 *
8879 * Retrieves the stock id used for the icon, or %NULL if there is
8880 * no icon or if the icon was set by some other method (e.g., by
8881 * pixbuf, icon name or gicon).
8882 *
8883 * Returns: A stock id, or %NULL if no icon is set or if the icon
8884 * wasn’t set from a stock id
8885 *
8886 * Since: 2.16
8887 *
8888 * Deprecated: 3.10: Use ctk_entry_get_icon_name() instead.
8889 */
8890const gchar *
8891ctk_entry_get_icon_stock (CtkEntry *entry,
8892 CtkEntryIconPosition icon_pos)
8893{
8894 CtkEntryPrivate *priv;
8895 EntryIconInfo *icon_info;
8896
8897 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
8898 g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL)do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return (((void*)0)); } } while (0)
;
8899
8900 priv = entry->priv;
8901 icon_info = priv->icons[icon_pos];
8902
8903 if (!icon_info)
8904 return NULL((void*)0);
8905
8906 return _ctk_icon_helper_get_stock_id (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
);
8907}
8908
8909/**
8910 * ctk_entry_get_icon_name:
8911 * @entry: A #CtkEntry
8912 * @icon_pos: Icon position
8913 *
8914 * Retrieves the icon name used for the icon, or %NULL if there is
8915 * no icon or if the icon was set by some other method (e.g., by
8916 * pixbuf, stock or gicon).
8917 *
8918 * Returns: (nullable): An icon name, or %NULL if no icon is set or if the icon
8919 * wasn’t set from an icon name
8920 *
8921 * Since: 2.16
8922 */
8923const gchar *
8924ctk_entry_get_icon_name (CtkEntry *entry,
8925 CtkEntryIconPosition icon_pos)
8926{
8927 CtkEntryPrivate *priv;
8928 EntryIconInfo *icon_info;
8929
8930 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
8931 g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL)do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return (((void*)0)); } } while (0)
;
8932
8933 priv = entry->priv;
8934 icon_info = priv->icons[icon_pos];
8935
8936 if (!icon_info)
8937 return NULL((void*)0);
8938
8939 return _ctk_icon_helper_get_icon_name (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
);
8940}
8941
8942/**
8943 * ctk_entry_set_icon_sensitive:
8944 * @entry: A #CtkEntry
8945 * @icon_pos: Icon position
8946 * @sensitive: Specifies whether the icon should appear
8947 * sensitive or insensitive
8948 *
8949 * Sets the sensitivity for the specified icon.
8950 *
8951 * Since: 2.16
8952 */
8953void
8954ctk_entry_set_icon_sensitive (CtkEntry *entry,
8955 CtkEntryIconPosition icon_pos,
8956 gboolean sensitive)
8957{
8958 CtkEntryPrivate *priv;
8959 EntryIconInfo *icon_info;
8960
8961 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
8962 g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos))do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return; } } while (0)
;
8963
8964 priv = entry->priv;
8965
8966 if ((icon_info = priv->icons[icon_pos]) == NULL((void*)0))
8967 icon_info = construct_icon_info (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, icon_pos);
8968
8969 if (icon_info->insensitive != !sensitive)
8970 {
8971 icon_info->insensitive = !sensitive;
8972
8973 icon_info->pressed = FALSE(0);
8974 icon_info->prelight = FALSE(0);
8975
8976 if (ctk_widget_get_realized (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
8977 update_cursors (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
8978
8979 update_icon_state (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, icon_pos);
8980
8981 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
,
8982 entry_props[icon_pos == CTK_ENTRY_ICON_PRIMARY
8983 ? PROP_SENSITIVE_PRIMARY
8984 : PROP_SENSITIVE_SECONDARY]);
8985 }
8986}
8987
8988/**
8989 * ctk_entry_get_icon_sensitive:
8990 * @entry: a #CtkEntry
8991 * @icon_pos: Icon position
8992 *
8993 * Returns whether the icon appears sensitive or insensitive.
8994 *
8995 * Returns: %TRUE if the icon is sensitive.
8996 *
8997 * Since: 2.16
8998 */
8999gboolean
9000ctk_entry_get_icon_sensitive (CtkEntry *entry,
9001 CtkEntryIconPosition icon_pos)
9002{
9003 CtkEntryPrivate *priv;
9004 EntryIconInfo *icon_info;
9005
9006 g_return_val_if_fail (CTK_IS_ENTRY (entry), TRUE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return ((!(0))); } } while (0)
;
9007 g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), TRUE)do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return ((!(0))); } } while (0)
;
9008
9009 priv = entry->priv;
9010
9011 icon_info = priv->icons[icon_pos];
9012
9013 return (!icon_info || !icon_info->insensitive);
9014
9015}
9016
9017/**
9018 * ctk_entry_get_icon_storage_type:
9019 * @entry: a #CtkEntry
9020 * @icon_pos: Icon position
9021 *
9022 * Gets the type of representation being used by the icon
9023 * to store image data. If the icon has no image data,
9024 * the return value will be %CTK_IMAGE_EMPTY.
9025 *
9026 * Returns: image representation being used
9027 *
9028 * Since: 2.16
9029 **/
9030CtkImageType
9031ctk_entry_get_icon_storage_type (CtkEntry *entry,
9032 CtkEntryIconPosition icon_pos)
9033{
9034 CtkEntryPrivate *priv;
9035 EntryIconInfo *icon_info;
9036
9037 g_return_val_if_fail (CTK_IS_ENTRY (entry), CTK_IMAGE_EMPTY)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (CTK_IMAGE_EMPTY); } } while
(0)
;
9038 g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), CTK_IMAGE_EMPTY)do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return (CTK_IMAGE_EMPTY); } } while (0)
;
9039
9040 priv = entry->priv;
9041
9042 icon_info = priv->icons[icon_pos];
9043
9044 if (!icon_info)
9045 return CTK_IMAGE_EMPTY;
9046
9047 return _ctk_icon_helper_get_storage_type (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
);
9048}
9049
9050/**
9051 * ctk_entry_get_icon_at_pos:
9052 * @entry: a #CtkEntry
9053 * @x: the x coordinate of the position to find
9054 * @y: the y coordinate of the position to find
9055 *
9056 * Finds the icon at the given position and return its index. The
9057 * position’s coordinates are relative to the @entry’s top left corner.
9058 * If @x, @y doesn’t lie inside an icon, -1 is returned.
9059 * This function is intended for use in a #CtkWidget::query-tooltip
9060 * signal handler.
9061 *
9062 * Returns: the index of the icon at the given position, or -1
9063 *
9064 * Since: 2.16
9065 */
9066gint
9067ctk_entry_get_icon_at_pos (CtkEntry *entry,
9068 gint x,
9069 gint y)
9070{
9071 CtkEntryPrivate *priv;
9072 guint i;
9073
9074 g_return_val_if_fail (CTK_IS_ENTRY (entry), -1)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (-1); } } while (0)
;
9075
9076 priv = entry->priv;
9077
9078 for (i = 0; i < MAX_ICONS2; i++)
9079 {
9080 EntryIconInfo *icon_info = priv->icons[i];
9081
9082 if (icon_info == NULL((void*)0))
9083 continue;
9084
9085 if (ctk_css_gadget_border_box_contains_point (icon_info->gadget, x, y))
9086 return i;
9087 }
9088
9089 return -1;
9090}
9091
9092/**
9093 * ctk_entry_set_icon_drag_source:
9094 * @entry: a #CtkEntry
9095 * @icon_pos: icon position
9096 * @target_list: the targets (data formats) in which the data can be provided
9097 * @actions: a bitmask of the allowed drag actions
9098 *
9099 * Sets up the icon at the given position so that CTK+ will start a drag
9100 * operation when the user clicks and drags the icon.
9101 *
9102 * To handle the drag operation, you need to connect to the usual
9103 * #CtkWidget::drag-data-get (or possibly #CtkWidget::drag-data-delete)
9104 * signal, and use ctk_entry_get_current_icon_drag_source() in
9105 * your signal handler to find out if the drag was started from
9106 * an icon.
9107 *
9108 * By default, CTK+ uses the icon as the drag icon. You can use the
9109 * #CtkWidget::drag-begin signal to set a different icon. Note that you
9110 * have to use g_signal_connect_after() to ensure that your signal handler
9111 * gets executed after the default handler.
9112 *
9113 * Since: 2.16
9114 */
9115void
9116ctk_entry_set_icon_drag_source (CtkEntry *entry,
9117 CtkEntryIconPosition icon_pos,
9118 CtkTargetList *target_list,
9119 CdkDragAction actions)
9120{
9121 CtkEntryPrivate *priv;
9122 EntryIconInfo *icon_info;
9123
9124 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
9125 g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos))do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return; } } while (0)
;
9126
9127 priv = entry->priv;
9128
9129 if ((icon_info = priv->icons[icon_pos]) == NULL((void*)0))
9130 icon_info = construct_icon_info (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, icon_pos);
9131
9132 if (icon_info->target_list)
9133 ctk_target_list_unref (icon_info->target_list);
9134 icon_info->target_list = target_list;
9135 if (icon_info->target_list)
9136 ctk_target_list_ref (icon_info->target_list);
9137
9138 icon_info->actions = actions;
9139}
9140
9141/**
9142 * ctk_entry_get_current_icon_drag_source:
9143 * @entry: a #CtkEntry
9144 *
9145 * Returns the index of the icon which is the source of the current
9146 * DND operation, or -1.
9147 *
9148 * This function is meant to be used in a #CtkWidget::drag-data-get
9149 * callback.
9150 *
9151 * Returns: index of the icon which is the source of the current
9152 * DND operation, or -1.
9153 *
9154 * Since: 2.16
9155 */
9156gint
9157ctk_entry_get_current_icon_drag_source (CtkEntry *entry)
9158{
9159 CtkEntryPrivate *priv;
9160 EntryIconInfo *icon_info = NULL((void*)0);
9161 gint i;
9162
9163 g_return_val_if_fail (CTK_IS_ENTRY (entry), -1)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (-1); } } while (0)
;
9164
9165 priv = entry->priv;
9166
9167 for (i = 0; i < MAX_ICONS2; i++)
9168 {
9169 if ((icon_info = priv->icons[i]))
9170 {
9171 if (icon_info->in_drag)
9172 return i;
9173 }
9174 }
9175
9176 return -1;
9177}
9178
9179/**
9180 * ctk_entry_get_icon_area:
9181 * @entry: A #CtkEntry
9182 * @icon_pos: Icon position
9183 * @icon_area: (out): Return location for the icon’s area
9184 *
9185 * Gets the area where entry’s icon at @icon_pos is drawn.
9186 * This function is useful when drawing something to the
9187 * entry in a draw callback.
9188 *
9189 * If the entry is not realized or has no icon at the given position,
9190 * @icon_area is filled with zeros. Otherwise, @icon_area will be filled
9191 * with the icon’s allocation, relative to @entry’s allocation.
9192 *
9193 * See also ctk_entry_get_text_area()
9194 *
9195 * Since: 3.0
9196 */
9197void
9198ctk_entry_get_icon_area (CtkEntry *entry,
9199 CtkEntryIconPosition icon_pos,
9200 CdkRectangle *icon_area)
9201{
9202 CtkEntryPrivate *priv;
9203 EntryIconInfo *icon_info;
9204
9205 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
9206 g_return_if_fail (icon_area != NULL)do { if ((icon_area != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "icon_area != NULL"); return
; } } while (0)
;
9207
9208 priv = entry->priv;
9209
9210 icon_info = priv->icons[icon_pos];
9211
9212 if (icon_info)
9213 {
9214 CtkAllocation widget_allocation;
9215 ctk_widget_get_allocation (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, &widget_allocation);
9216 ctk_css_gadget_get_border_allocation (icon_info->gadget, icon_area, NULL((void*)0));
9217 icon_area->x -= widget_allocation.x;
9218 icon_area->y -= widget_allocation.y;
9219 }
9220 else
9221 {
9222 icon_area->x = 0;
9223 icon_area->y = 0;
9224 icon_area->width = 0;
9225 icon_area->height = 0;
9226 }
9227}
9228
9229static void
9230ensure_has_tooltip (CtkEntry *entry)
9231{
9232 gchar *text = ctk_widget_get_tooltip_text (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
9233 gboolean has_tooltip = text != NULL((void*)0);
9234
9235 if (!has_tooltip)
9236 {
9237 CtkEntryPrivate *priv = entry->priv;
9238 int i;
9239
9240 for (i = 0; i < MAX_ICONS2; i++)
9241 {
9242 EntryIconInfo *icon_info = priv->icons[i];
9243
9244 if (icon_info != NULL((void*)0) && icon_info->tooltip != NULL((void*)0))
9245 {
9246 has_tooltip = TRUE(!(0));
9247 break;
9248 }
9249 }
9250 }
9251 else
9252 {
9253 g_free (text);
9254 }
9255
9256 ctk_widget_set_has_tooltip (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, has_tooltip);
9257}
9258
9259/**
9260 * ctk_entry_get_icon_tooltip_text:
9261 * @entry: a #CtkEntry
9262 * @icon_pos: the icon position
9263 *
9264 * Gets the contents of the tooltip on the icon at the specified
9265 * position in @entry.
9266 *
9267 * Returns: (nullable): the tooltip text, or %NULL. Free the returned
9268 * string with g_free() when done.
9269 *
9270 * Since: 2.16
9271 */
9272gchar *
9273ctk_entry_get_icon_tooltip_text (CtkEntry *entry,
9274 CtkEntryIconPosition icon_pos)
9275{
9276 CtkEntryPrivate *priv;
9277 EntryIconInfo *icon_info;
9278 gchar *text = NULL((void*)0);
9279
9280 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
9281 g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL)do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return (((void*)0)); } } while (0)
;
9282
9283 priv = entry->priv;
9284
9285 icon_info = priv->icons[icon_pos];
9286
9287 if (!icon_info)
9288 return NULL((void*)0);
9289
9290 if (icon_info->tooltip &&
9291 !pango_parse_markup (icon_info->tooltip, -1, 0, NULL((void*)0), &text, NULL((void*)0), NULL((void*)0)))
9292 g_assert (NULL == text)do { if (((void*)0) == text) ; else g_assertion_message_expr (
"Ctk", "ctkentry.c", 9292, ((const char*) (__func__)), "NULL == text"
); } while (0)
; /* text should still be NULL in case of markup errors */
9293
9294 return text;
9295}
9296
9297/**
9298 * ctk_entry_set_icon_tooltip_text:
9299 * @entry: a #CtkEntry
9300 * @icon_pos: the icon position
9301 * @tooltip: (allow-none): the contents of the tooltip for the icon, or %NULL
9302 *
9303 * Sets @tooltip as the contents of the tooltip for the icon
9304 * at the specified position.
9305 *
9306 * Use %NULL for @tooltip to remove an existing tooltip.
9307 *
9308 * See also ctk_widget_set_tooltip_text() and
9309 * ctk_entry_set_icon_tooltip_markup().
9310 *
9311 * If you unset the widget tooltip via ctk_widget_set_tooltip_text() or
9312 * ctk_widget_set_tooltip_markup(), this sets CtkWidget:has-tooltip to %FALSE,
9313 * which suppresses icon tooltips too. You can resolve this by then calling
9314 * ctk_widget_set_has_tooltip() to set CtkWidget:has-tooltip back to %TRUE, or
9315 * setting at least one non-empty tooltip on any icon achieves the same result.
9316 *
9317 * Since: 2.16
9318 */
9319void
9320ctk_entry_set_icon_tooltip_text (CtkEntry *entry,
9321 CtkEntryIconPosition icon_pos,
9322 const gchar *tooltip)
9323{
9324 CtkEntryPrivate *priv;
9325 EntryIconInfo *icon_info;
9326
9327 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
9328 g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos))do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return; } } while (0)
;
9329
9330 priv = entry->priv;
9331
9332 if ((icon_info = priv->icons[icon_pos]) == NULL((void*)0))
9333 icon_info = construct_icon_info (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, icon_pos);
9334
9335 g_free (icon_info->tooltip);
9336
9337 /* Treat an empty string as a NULL string,
9338 * because an empty string would be useless for a tooltip:
9339 */
9340 if (tooltip && tooltip[0] == '\0')
9341 tooltip = NULL((void*)0);
9342
9343 icon_info->tooltip = tooltip ? g_markup_escape_text (tooltip, -1) : NULL((void*)0);
9344
9345 ensure_has_tooltip (entry);
9346
9347 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
,
9348 entry_props[icon_pos == CTK_ENTRY_ICON_PRIMARY
9349 ? PROP_TOOLTIP_TEXT_PRIMARY
9350 : PROP_TOOLTIP_TEXT_SECONDARY]);
9351}
9352
9353/**
9354 * ctk_entry_get_icon_tooltip_markup:
9355 * @entry: a #CtkEntry
9356 * @icon_pos: the icon position
9357 *
9358 * Gets the contents of the tooltip on the icon at the specified
9359 * position in @entry.
9360 *
9361 * Returns: (nullable): the tooltip text, or %NULL. Free the returned
9362 * string with g_free() when done.
9363 *
9364 * Since: 2.16
9365 */
9366gchar *
9367ctk_entry_get_icon_tooltip_markup (CtkEntry *entry,
9368 CtkEntryIconPosition icon_pos)
9369{
9370 CtkEntryPrivate *priv;
9371 EntryIconInfo *icon_info;
9372
9373 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
9374 g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL)do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return (((void*)0)); } } while (0)
;
9375
9376 priv = entry->priv;
9377
9378 icon_info = priv->icons[icon_pos];
9379
9380 if (!icon_info)
9381 return NULL((void*)0);
9382
9383 return g_strdup (icon_info->tooltip)g_strdup_inline (icon_info->tooltip);
9384}
9385
9386/**
9387 * ctk_entry_set_icon_tooltip_markup:
9388 * @entry: a #CtkEntry
9389 * @icon_pos: the icon position
9390 * @tooltip: (allow-none): the contents of the tooltip for the icon, or %NULL
9391 *
9392 * Sets @tooltip as the contents of the tooltip for the icon at
9393 * the specified position. @tooltip is assumed to be marked up with
9394 * the [Pango text markup language][PangoMarkupFormat].
9395 *
9396 * Use %NULL for @tooltip to remove an existing tooltip.
9397 *
9398 * See also ctk_widget_set_tooltip_markup() and
9399 * ctk_entry_set_icon_tooltip_text().
9400 *
9401 * Since: 2.16
9402 */
9403void
9404ctk_entry_set_icon_tooltip_markup (CtkEntry *entry,
9405 CtkEntryIconPosition icon_pos,
9406 const gchar *tooltip)
9407{
9408 CtkEntryPrivate *priv;
9409 EntryIconInfo *icon_info;
9410
9411 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
9412 g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos))do { if ((((icon_pos) == CTK_ENTRY_ICON_PRIMARY || (icon_pos)
== CTK_ENTRY_ICON_SECONDARY))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "IS_VALID_ICON_POSITION (icon_pos)"
); return; } } while (0)
;
9413
9414 priv = entry->priv;
9415
9416 if ((icon_info = priv->icons[icon_pos]) == NULL((void*)0))
9417 icon_info = construct_icon_info (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, icon_pos);
9418
9419 g_free (icon_info->tooltip);
9420
9421 /* Treat an empty string as a NULL string,
9422 * because an empty string would be useless for a tooltip:
9423 */
9424 if (tooltip && tooltip[0] == '\0')
9425 tooltip = NULL((void*)0);
9426
9427 icon_info->tooltip = g_strdup (tooltip)g_strdup_inline (tooltip);
9428
9429 ensure_has_tooltip (entry);
9430
9431 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
,
9432 entry_props[icon_pos == CTK_ENTRY_ICON_PRIMARY
9433 ? PROP_TOOLTIP_MARKUP_PRIMARY
9434 : PROP_TOOLTIP_MARKUP_SECONDARY]);
9435}
9436
9437static gboolean
9438ctk_entry_query_tooltip (CtkWidget *widget,
9439 gint x,
9440 gint y,
9441 gboolean keyboard_tip,
9442 CtkTooltip *tooltip)
9443{
9444 CtkEntry *entry;
9445 CtkEntryPrivate *priv;
9446 EntryIconInfo *icon_info;
9447 gint icon_pos;
9448
9449 entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
9450 priv = entry->priv;
9451
9452 if (!keyboard_tip)
9453 {
9454 icon_pos = ctk_entry_get_icon_at_pos (entry, x, y);
9455 if (icon_pos != -1)
9456 {
9457 if ((icon_info = priv->icons[icon_pos]) != NULL((void*)0))
9458 {
9459 if (icon_info->tooltip)
9460 {
9461 ctk_tooltip_set_markup (tooltip, icon_info->tooltip);
9462 return TRUE(!(0));
9463 }
9464
9465 return FALSE(0);
9466 }
9467 }
9468 }
9469
9470 return CTK_WIDGET_CLASS (ctk_entry_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_entry_parent_class)), ((ctk_widget_get_type ()))))))
->query_tooltip (widget,
9471 x, y,
9472 keyboard_tip,
9473 tooltip);
9474}
9475
9476
9477/* Quick hack of a popup menu
9478 */
9479static void
9480activate_cb (CtkWidget *menuitem,
9481 CtkEntry *entry)
9482{
9483 const gchar *signal;
9484
9485 signal = g_object_get_qdata (G_OBJECT (menuitem)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menuitem)), (((GType) ((20) << (2))))))))
, quark_ctk_signal);
9486 g_signal_emit_by_name (entry, signal);
9487}
9488
9489
9490static gboolean
9491ctk_entry_mnemonic_activate (CtkWidget *widget,
9492 gboolean group_cycling G_GNUC_UNUSED__attribute__ ((__unused__)))
9493{
9494 ctk_widget_grab_focus (widget);
9495 return CDK_EVENT_STOP((!(0)));
9496}
9497
9498static void
9499check_undo_icon_grab (CtkEntry *entry,
9500 EntryIconInfo *info)
9501{
9502 if (!info->device ||
9503 !ctk_widget_device_is_shadowed (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, info->device))
9504 return;
9505
9506 info->pressed = FALSE(0);
9507 info->current_sequence = NULL((void*)0);
9508 info->device = NULL((void*)0);
9509}
9510
9511static void
9512ctk_entry_grab_notify (CtkWidget *widget,
9513 gboolean was_grabbed G_GNUC_UNUSED__attribute__ ((__unused__)))
9514{
9515 CtkEntryPrivate *priv;
9516 gint i;
9517
9518 priv = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
->priv;
9519
9520 for (i = 0; i < MAX_ICONS2; i++)
9521 {
9522 if (priv->icons[i])
9523 check_undo_icon_grab (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
, priv->icons[i]);
9524 }
9525}
9526
9527static void
9528append_action_signal (CtkEntry *entry,
9529 CtkWidget *menu,
9530 const gchar *label,
9531 const gchar *signal,
9532 gboolean sensitive)
9533{
9534 CtkWidget *menuitem = ctk_menu_item_new_with_mnemonic (label);
9535
9536 g_object_set_qdata (G_OBJECT (menuitem)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menuitem)), (((GType) ((20) << (2))))))))
, quark_ctk_signal, (char *)signal);
9537 g_signal_connect (menuitem, "activate",g_signal_connect_data ((menuitem), ("activate"), (((GCallback
) (activate_cb))), (entry), ((void*)0), (GConnectFlags) 0)
9538 G_CALLBACK (activate_cb), entry)g_signal_connect_data ((menuitem), ("activate"), (((GCallback
) (activate_cb))), (entry), ((void*)0), (GConnectFlags) 0)
;
9539
9540 ctk_widget_set_sensitive (menuitem, sensitive);
9541
9542 ctk_widget_show (menuitem);
9543 ctk_menu_shell_append (CTK_MENU_SHELL (menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_menu_shell_get_type ()))))))
, menuitem);
9544}
9545
9546static void
9547popup_menu_detach (CtkWidget *attach_widget,
9548 CtkMenu *menu G_GNUC_UNUSED__attribute__ ((__unused__)))
9549{
9550 CtkEntry *entry_attach = CTK_ENTRY (attach_widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((attach_widget)), ((ctk_entry_get_type ()))))))
;
9551 CtkEntryPrivate *priv_attach = entry_attach->priv;
9552
9553 priv_attach->popup_menu = NULL((void*)0);
9554}
9555
9556typedef struct
9557{
9558 CtkEntry *entry;
9559 CdkEvent *trigger_event;
9560} PopupInfo;
9561
9562static void
9563popup_targets_received (CtkClipboard *clipboard G_GNUC_UNUSED__attribute__ ((__unused__)),
9564 CtkSelectionData *data,
9565 gpointer user_data)
9566{
9567 PopupInfo *info = user_data;
9568 CtkEntry *entry = info->entry;
9569 CtkEntryPrivate *info_entry_priv = entry->priv;
9570 CdkRectangle rect = { 0, 0, 1, 0 };
9571
9572 if (ctk_widget_get_realized (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
9573 {
9574 DisplayMode mode;
9575 gboolean clipboard_contains_text;
9576 CtkWidget *menu;
9577 CtkWidget *menuitem;
9578
9579 clipboard_contains_text = ctk_selection_data_targets_include_text (data);
9580 if (info_entry_priv->popup_menu)
9581 ctk_widget_destroy (info_entry_priv->popup_menu);
9582
9583 info_entry_priv->popup_menu = menu = ctk_menu_new ();
9584 ctk_style_context_add_class (ctk_widget_get_style_context (menu),
9585 CTK_STYLE_CLASS_CONTEXT_MENU"context-menu");
9586
9587 ctk_menu_attach_to_widget (CTK_MENU (menu)((((CtkMenu*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_menu_get_type ()))))))
, CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, popup_menu_detach);
9588
9589 mode = ctk_entry_get_display_mode (entry);
9590 append_action_signal (entry, menu, _("Cu_t")((char *) g_dgettext ("ctk30", "Cu_t")), "cut-clipboard",
9591 info_entry_priv->editable && mode == DISPLAY_NORMAL &&
9592 info_entry_priv->current_pos != info_entry_priv->selection_bound);
9593
9594 append_action_signal (entry, menu, _("_Copy")((char *) g_dgettext ("ctk30", "_Copy")), "copy-clipboard",
9595 mode == DISPLAY_NORMAL &&
9596 info_entry_priv->current_pos != info_entry_priv->selection_bound);
9597
9598 append_action_signal (entry, menu, _("_Paste")((char *) g_dgettext ("ctk30", "_Paste")), "paste-clipboard",
9599 info_entry_priv->editable && clipboard_contains_text);
9600
9601 menuitem = ctk_menu_item_new_with_mnemonic (_("_Delete")((char *) g_dgettext ("ctk30", "_Delete")));
9602 ctk_widget_set_sensitive (menuitem, info_entry_priv->editable && info_entry_priv->current_pos != info_entry_priv->selection_bound);
9603 g_signal_connect_swapped (menuitem, "activate",g_signal_connect_data ((menuitem), ("activate"), (((GCallback
) (ctk_entry_delete_cb))), (entry), ((void*)0), G_CONNECT_SWAPPED
)
9604 G_CALLBACK (ctk_entry_delete_cb), entry)g_signal_connect_data ((menuitem), ("activate"), (((GCallback
) (ctk_entry_delete_cb))), (entry), ((void*)0), G_CONNECT_SWAPPED
)
;
9605 ctk_widget_show (menuitem);
9606 ctk_menu_shell_append (CTK_MENU_SHELL (menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_menu_shell_get_type ()))))))
, menuitem);
9607
9608 menuitem = ctk_separator_menu_item_new ();
9609 ctk_widget_show (menuitem);
9610 ctk_menu_shell_append (CTK_MENU_SHELL (menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_menu_shell_get_type ()))))))
, menuitem);
9611
9612 menuitem = ctk_menu_item_new_with_mnemonic (_("Select _All")((char *) g_dgettext ("ctk30", "Select _All")));
9613 ctk_widget_set_sensitive (menuitem, ctk_entry_buffer_get_length (info_entry_priv->buffer) > 0);
9614 g_signal_connect_swapped (menuitem, "activate",g_signal_connect_data ((menuitem), ("activate"), (((GCallback
) (ctk_entry_select_all))), (entry), ((void*)0), G_CONNECT_SWAPPED
)
9615 G_CALLBACK (ctk_entry_select_all), entry)g_signal_connect_data ((menuitem), ("activate"), (((GCallback
) (ctk_entry_select_all))), (entry), ((void*)0), G_CONNECT_SWAPPED
)
;
9616 ctk_widget_show (menuitem);
9617 ctk_menu_shell_append (CTK_MENU_SHELL (menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_menu_shell_get_type ()))))))
, menuitem);
9618
9619 if (info_entry_priv->show_emoji_icon ||
9620 (ctk_entry_get_input_hints (entry) & CTK_INPUT_HINT_NO_EMOJI) == 0)
9621 {
9622 menuitem = ctk_menu_item_new_with_mnemonic (_("Insert _Emoji")((char *) g_dgettext ("ctk30", "Insert _Emoji")));
9623 ctk_widget_set_sensitive (menuitem,
9624 mode == DISPLAY_NORMAL &&
9625 info_entry_priv->editable);
9626 g_signal_connect_swapped (menuitem, "activate",g_signal_connect_data ((menuitem), ("activate"), (((GCallback
) (ctk_entry_insert_emoji))), (entry), ((void*)0), G_CONNECT_SWAPPED
)
9627 G_CALLBACK (ctk_entry_insert_emoji), entry)g_signal_connect_data ((menuitem), ("activate"), (((GCallback
) (ctk_entry_insert_emoji))), (entry), ((void*)0), G_CONNECT_SWAPPED
)
;
9628 ctk_widget_show (menuitem);
9629 ctk_menu_shell_append (CTK_MENU_SHELL (menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_menu_shell_get_type ()))))))
, menuitem);
9630 }
9631
9632 g_signal_emit (entry, signals[POPULATE_POPUP], 0, menu);
9633
9634 if (info->trigger_event && cdk_event_triggers_context_menu (info->trigger_event))
9635 ctk_menu_popup_at_pointer (CTK_MENU (menu)((((CtkMenu*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_menu_get_type ()))))))
, info->trigger_event);
9636 else
9637 {
9638 ctk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &rect.x, NULL((void*)0));
9639 rect.x -= info_entry_priv->scroll_offset;
9640 rect.height = cdk_window_get_height (info_entry_priv->text_area);
9641
9642 ctk_menu_popup_at_rect (CTK_MENU (menu)((((CtkMenu*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_menu_get_type ()))))))
,
9643 info_entry_priv->text_area,
9644 &rect,
9645 CDK_GRAVITY_SOUTH_EAST,
9646 CDK_GRAVITY_NORTH_WEST,
9647 info->trigger_event);
9648
9649 ctk_menu_shell_select_first (CTK_MENU_SHELL (menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_menu_shell_get_type ()))))))
, FALSE(0));
9650 }
9651 }
9652
9653 g_clear_pointer (&info->trigger_event, cdk_event_free)do { _Static_assert (sizeof *(&info->trigger_event) ==
sizeof (gpointer), "Expression evaluates to false"); __typeof__
((&info->trigger_event)) _pp = (&info->trigger_event
); __typeof__ (*(&info->trigger_event)) _ptr = *_pp; *
_pp = ((void*)0); if (_ptr) (cdk_event_free) (_ptr); } while (
0)
;
9654 g_object_unref (entry);
9655 g_slice_free (PopupInfo, info)do { if (1) g_slice_free1 (sizeof (PopupInfo), (info)); else (
void) ((PopupInfo*) 0 == (info)); } while (0)
;
9656}
9657
9658static void
9659ctk_entry_do_popup (CtkEntry *entry,
9660 const CdkEvent *event)
9661{
9662 PopupInfo *info = g_slice_new (PopupInfo)((PopupInfo*) g_slice_alloc (sizeof (PopupInfo)));
9663
9664 /* In order to know what entries we should make sensitive, we
9665 * ask for the current targets of the clipboard, and when
9666 * we get them, then we actually pop up the menu.
9667 */
9668 info->entry = g_object_ref (entry)((__typeof__ (entry)) (g_object_ref) (entry));
9669 info->trigger_event = event ? cdk_event_copy (event) : ctk_get_current_event ();
9670
9671 ctk_clipboard_request_contents (ctk_widget_get_clipboard (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, CDK_SELECTION_CLIPBOARD((CdkAtom)((gpointer) (gulong) (69)))),
9672 cdk_atom_intern_static_string ("TARGETS"),
9673 popup_targets_received,
9674 info);
9675}
9676
9677static gboolean
9678ctk_entry_popup_menu (CtkWidget *widget)
9679{
9680 ctk_entry_do_popup (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
, NULL((void*)0));
9681 return CDK_EVENT_STOP((!(0)));
9682}
9683
9684static void
9685show_or_hide_handles (CtkWidget *popover,
9686 GParamSpec *pspec G_GNUC_UNUSED__attribute__ ((__unused__)),
9687 CtkEntry *entry)
9688{
9689 gboolean visible;
9690 CtkTextHandle *handle;
9691 CtkTextHandleMode mode;
9692
9693 visible = ctk_widget_get_visible (popover);
9694
9695 handle = entry->priv->text_handle;
9696 mode = _ctk_text_handle_get_mode (handle);
9697
9698 if (mode == CTK_TEXT_HANDLE_MODE_CURSOR)
9699 {
9700 _ctk_text_handle_set_visible (handle, CTK_TEXT_HANDLE_POSITION_CURSOR, !visible);
9701 }
9702 else if (mode == CTK_TEXT_HANDLE_MODE_SELECTION)
9703 {
9704 _ctk_text_handle_set_visible (handle, CTK_TEXT_HANDLE_POSITION_SELECTION_START, !visible);
9705 _ctk_text_handle_set_visible (handle, CTK_TEXT_HANDLE_POSITION_SELECTION_END, !visible);
9706 }
9707}
9708
9709static void
9710activate_bubble_cb (CtkWidget *item,
9711 CtkEntry *entry)
9712{
9713 const gchar *signal;
9714
9715 signal = g_object_get_qdata (G_OBJECT (item)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((item)), (((GType) ((20) << (2))))))))
, quark_ctk_signal);
9716 ctk_widget_hide (entry->priv->selection_bubble);
9717 if (strcmp (signal, "select-all") == 0)
9718 ctk_entry_select_all (entry);
9719 else
9720 g_signal_emit_by_name (entry, signal);
9721}
9722
9723static void
9724append_bubble_action (CtkEntry *entry,
9725 CtkWidget *toolbar,
9726 const gchar *label,
9727 const gchar *icon_name,
9728 const gchar *signal,
9729 gboolean sensitive)
9730{
9731 CtkWidget *item, *image;
9732
9733 item = ctk_button_new ();
9734 ctk_widget_set_focus_on_click (item, FALSE(0));
9735 image = ctk_image_new_from_icon_name (icon_name, CTK_ICON_SIZE_MENU);
9736 ctk_widget_show (image);
9737 ctk_container_add (CTK_CONTAINER (item)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((item)), ((ctk_container_get_type ()))))))
, image);
9738 ctk_widget_set_tooltip_text (item, label);
9739 ctk_style_context_add_class (ctk_widget_get_style_context (item), "image-button");
9740 g_object_set_qdata (G_OBJECT (item)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((item)), (((GType) ((20) << (2))))))))
, quark_ctk_signal, (char *)signal);
9741 g_signal_connect (item, "clicked", G_CALLBACK (activate_bubble_cb), entry)g_signal_connect_data ((item), ("clicked"), (((GCallback) (activate_bubble_cb
))), (entry), ((void*)0), (GConnectFlags) 0)
;
9742 ctk_widget_set_sensitive (CTK_WIDGET (item)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((item)), ((ctk_widget_get_type ()))))))
, sensitive);
9743 ctk_widget_show (CTK_WIDGET (item)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((item)), ((ctk_widget_get_type ()))))))
);
9744 ctk_container_add (CTK_CONTAINER (toolbar)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toolbar)), ((ctk_container_get_type ()))))))
, item);
9745}
9746
9747static void
9748bubble_targets_received (CtkClipboard *clipboard G_GNUC_UNUSED__attribute__ ((__unused__)),
9749 CtkSelectionData *data,
9750 gpointer user_data)
9751{
9752 CtkEntry *entry = user_data;
9753 CtkEntryPrivate *priv = entry->priv;
9754 cairo_rectangle_int_t rect;
9755 CtkAllocation allocation;
9756 gint start_x, end_x;
9757 gboolean has_selection;
9758 gboolean has_clipboard;
9759 gboolean all_selected;
9760 DisplayMode mode;
9761 CtkWidget *box;
9762 CtkWidget *toolbar;
9763 gint length, start, end;
9764
9765 has_selection = ctk_editable_get_selection_bounds (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, &start, &end);
9766 length = ctk_entry_buffer_get_length (get_buffer (entry));
9767 all_selected = (start == 0) && (end == length);
9768
9769 if (!has_selection && !priv->editable)
9770 {
9771 priv->selection_bubble_timeout_id = 0;
9772 return;
9773 }
9774
9775 if (priv->selection_bubble)
9776 ctk_widget_destroy (priv->selection_bubble);
9777
9778 priv->selection_bubble = ctk_popover_new (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
9779 ctk_style_context_add_class (ctk_widget_get_style_context (priv->selection_bubble),
9780 CTK_STYLE_CLASS_TOUCH_SELECTION"touch-selection");
9781 ctk_popover_set_position (CTK_POPOVER (priv->selection_bubble)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->selection_bubble)), ((ctk_popover_get_type ()))
))))
, CTK_POS_BOTTOM);
9782 ctk_popover_set_modal (CTK_POPOVER (priv->selection_bubble)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->selection_bubble)), ((ctk_popover_get_type ()))
))))
, FALSE(0));
9783 g_signal_connect (priv->selection_bubble, "notify::visible",g_signal_connect_data ((priv->selection_bubble), ("notify::visible"
), (((GCallback) (show_or_hide_handles))), (entry), ((void*)0
), (GConnectFlags) 0)
9784 G_CALLBACK (show_or_hide_handles), entry)g_signal_connect_data ((priv->selection_bubble), ("notify::visible"
), (((GCallback) (show_or_hide_handles))), (entry), ((void*)0
), (GConnectFlags) 0)
;
9785
9786 box = ctk_box_new (CTK_ORIENTATION_VERTICAL, 5);
9787 g_object_set (box, "margin", 10, NULL((void*)0));
9788 ctk_widget_show (box);
9789 toolbar = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 5);
9790 ctk_widget_show (toolbar);
9791 ctk_container_add (CTK_CONTAINER (priv->selection_bubble)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->selection_bubble)), ((ctk_container_get_type ()
))))))
, box);
9792 ctk_container_add (CTK_CONTAINER (box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_container_get_type ()))))))
, toolbar);
9793
9794 has_clipboard = ctk_selection_data_targets_include_text (data);
9795 mode = ctk_entry_get_display_mode (entry);
9796
9797 if (mode == DISPLAY_NORMAL)
9798 append_bubble_action (entry, toolbar, _("Select all")((char *) g_dgettext ("ctk30", "Select all")), "edit-select-all-symbolic", "select-all", !all_selected);
9799
9800 if (priv->editable && has_selection && mode == DISPLAY_NORMAL)
9801 append_bubble_action (entry, toolbar, _("Cut")((char *) g_dgettext ("ctk30", "Cut")), "edit-cut-symbolic", "cut-clipboard", TRUE(!(0)));
9802
9803 if (has_selection && mode == DISPLAY_NORMAL)
9804 append_bubble_action (entry, toolbar, _("Copy")((char *) g_dgettext ("ctk30", "Copy")), "edit-copy-symbolic", "copy-clipboard", TRUE(!(0)));
9805
9806 if (priv->editable)
9807 append_bubble_action (entry, toolbar, _("Paste")((char *) g_dgettext ("ctk30", "Paste")), "edit-paste-symbolic", "paste-clipboard", has_clipboard);
9808
9809 if (priv->populate_all)
9810 g_signal_emit (entry, signals[POPULATE_POPUP], 0, box);
9811
9812 ctk_widget_get_allocation (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, &allocation);
9813
9814 ctk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &start_x, NULL((void*)0));
9815
9816 start_x -= priv->scroll_offset;
9817 start_x = CLAMP (start_x, 0, priv->text_allocation.width)(((start_x) > (priv->text_allocation.width)) ? (priv->
text_allocation.width) : (((start_x) < (0)) ? (0) : (start_x
)))
;
9818 rect.y = priv->text_allocation.y - allocation.y;
9819 rect.height = priv->text_allocation.height;
9820
9821 if (has_selection)
9822 {
9823 end_x = ctk_entry_get_selection_bound_location (entry) - priv->scroll_offset;
9824 end_x = CLAMP (end_x, 0, priv->text_allocation.width)(((end_x) > (priv->text_allocation.width)) ? (priv->
text_allocation.width) : (((end_x) < (0)) ? (0) : (end_x))
)
;
9825
9826 rect.x = priv->text_allocation.x - allocation.x + MIN (start_x, end_x)(((start_x) < (end_x)) ? (start_x) : (end_x));
9827 rect.width = ABS (end_x - start_x)(((end_x - start_x) < 0) ? -(end_x - start_x) : (end_x - start_x
))
;
9828 }
9829 else
9830 {
9831 rect.x = priv->text_allocation.x - allocation.x + start_x;
9832 rect.width = 0;
9833 }
9834
9835 rect.x -= 5;
9836 rect.y -= 5;
9837 rect.width += 10;
9838 rect.height += 10;
9839
9840 ctk_popover_set_pointing_to (CTK_POPOVER (priv->selection_bubble)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->selection_bubble)), ((ctk_popover_get_type ()))
))))
, &rect);
9841 ctk_widget_show (priv->selection_bubble);
9842
9843 priv->selection_bubble_timeout_id = 0;
9844}
9845
9846static gboolean
9847ctk_entry_selection_bubble_popup_show (gpointer user_data)
9848{
9849 CtkEntry *entry = user_data;
9850
9851 ctk_clipboard_request_contents (ctk_widget_get_clipboard (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, CDK_SELECTION_CLIPBOARD((CdkAtom)((gpointer) (gulong) (69)))),
9852 cdk_atom_intern_static_string ("TARGETS"),
9853 bubble_targets_received,
9854 entry);
9855 return G_SOURCE_REMOVE(0);
9856}
9857
9858static void
9859ctk_entry_selection_bubble_popup_unset (CtkEntry *entry)
9860{
9861 CtkEntryPrivate *priv;
9862
9863 priv = entry->priv;
9864
9865 if (priv->selection_bubble)
9866 ctk_widget_hide (priv->selection_bubble);
9867
9868 if (priv->selection_bubble_timeout_id)
9869 {
9870 g_source_remove (priv->selection_bubble_timeout_id);
9871 priv->selection_bubble_timeout_id = 0;
9872 }
9873}
9874
9875static void
9876ctk_entry_selection_bubble_popup_set (CtkEntry *entry)
9877{
9878 CtkEntryPrivate *priv;
9879
9880 priv = entry->priv;
9881
9882 if (priv->selection_bubble_timeout_id)
9883 g_source_remove (priv->selection_bubble_timeout_id);
9884
9885 priv->selection_bubble_timeout_id =
9886 cdk_threads_add_timeout (50, ctk_entry_selection_bubble_popup_show, entry);
9887 g_source_set_name_by_id (priv->selection_bubble_timeout_id, "[ctk+] ctk_entry_selection_bubble_popup_cb");
9888}
9889
9890static void
9891ctk_entry_drag_begin (CtkWidget *widget,
9892 CdkDragContext *context)
9893{
9894 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
9895 CtkEntryPrivate *priv = entry->priv;
9896 gchar *text;
9897 gint i;
9898
9899 for (i = 0; i < MAX_ICONS2; i++)
1
Loop condition is true. Entering loop body
4
Loop condition is true. Entering loop body
7
Loop condition is false. Execution continues on line 9915
9900 {
9901 EntryIconInfo *icon_info = priv->icons[i];
9902
9903 if (icon_info != NULL((void*)0))
2
Assuming 'icon_info' is equal to NULL
3
Taking false branch
5
Assuming 'icon_info' is equal to NULL
6
Taking false branch
9904 {
9905 if (icon_info->in_drag)
9906 {
9907 ctk_drag_set_icon_definition (context,
9908 ctk_icon_helper_get_definition (CTK_ICON_HELPER (icon_info->gadget)((((CtkIconHelper*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_info->gadget)), (ctk_icon_helper_get_type())))))
),
9909 -2, -2);
9910 return;
9911 }
9912 }
9913 }
9914
9915 text = _ctk_entry_get_selected_text (entry);
8
Calling '_ctk_entry_get_selected_text'
12
Returning from '_ctk_entry_get_selected_text'
9916
9917 if (text)
13
Assuming 'text' is non-null
14
Taking true branch
9918 {
9919 gint *ranges, n_ranges;
9920 cairo_surface_t *surface;
9921 double sx, sy;
9922
9923 surface = _ctk_text_util_create_drag_icon (widget, text, -1);
9924
9925 ctk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
15
Calling 'ctk_entry_get_pixel_ranges'
21
Returning from 'ctk_entry_get_pixel_ranges'
9926 cairo_surface_get_device_scale (surface, &sx, &sy);
9927 cairo_surface_set_device_offset (surface,
9928 -(priv->drag_start_x - ranges[0]) * sx,
22
Array access (from variable 'ranges') results in a null pointer dereference
9929 -(priv->drag_start_y) * sy);
9930 g_free (ranges);
9931
9932 ctk_drag_set_icon_surface (context, surface);
9933 cairo_surface_destroy (surface);
9934 g_free (text);
9935 }
9936}
9937
9938static void
9939ctk_entry_drag_end (CtkWidget *widget,
9940 CdkDragContext *context G_GNUC_UNUSED__attribute__ ((__unused__)))
9941{
9942 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
9943 CtkEntryPrivate *priv = entry->priv;
9944 gint i;
9945
9946 for (i = 0; i < MAX_ICONS2; i++)
9947 {
9948 EntryIconInfo *icon_info = priv->icons[i];
9949
9950 if (icon_info != NULL((void*)0))
9951 icon_info->in_drag = 0;
9952 }
9953}
9954
9955static void
9956ctk_entry_drag_leave (CtkWidget *widget,
9957 CdkDragContext *context G_GNUC_UNUSED__attribute__ ((__unused__)),
9958 guint time G_GNUC_UNUSED__attribute__ ((__unused__)))
9959{
9960 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
9961 CtkEntryPrivate *priv = entry->priv;
9962
9963 ctk_drag_unhighlight (widget);
9964 priv->dnd_position = -1;
9965 ctk_widget_queue_draw (widget);
9966}
9967
9968static gboolean
9969ctk_entry_drag_drop (CtkWidget *widget,
9970 CdkDragContext *context,
9971 gint x G_GNUC_UNUSED__attribute__ ((__unused__)),
9972 gint y G_GNUC_UNUSED__attribute__ ((__unused__)),
9973 guint time)
9974{
9975 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
9976 CtkEntryPrivate *priv = entry->priv;
9977 CdkAtom target = CDK_NONE((CdkAtom)((gpointer) (gulong) (0)));
9978
9979 if (priv->editable)
9980 target = ctk_drag_dest_find_target (widget, context, NULL((void*)0));
9981
9982 if (target != CDK_NONE((CdkAtom)((gpointer) (gulong) (0))))
9983 ctk_drag_get_data (widget, context, target, time);
9984 else
9985 ctk_drag_finish (context, FALSE(0), FALSE(0), time);
9986
9987 return TRUE(!(0));
9988}
9989
9990static gboolean
9991ctk_entry_drag_motion (CtkWidget *widget,
9992 CdkDragContext *context,
9993 gint x,
9994 gint y G_GNUC_UNUSED__attribute__ ((__unused__)),
9995 guint time)
9996{
9997 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
9998 CtkEntryPrivate *priv = entry->priv;
9999 CtkWidget *source_widget;
10000 CdkDragAction suggested_action;
10001 gint new_position, old_position;
10002 gint sel1, sel2;
10003
10004 old_position = priv->dnd_position;
10005 new_position = ctk_entry_find_position (entry, x + priv->scroll_offset);
10006
10007 if (priv->editable &&
10008 ctk_drag_dest_find_target (widget, context, NULL((void*)0)) != CDK_NONE((CdkAtom)((gpointer) (gulong) (0))))
10009 {
10010 source_widget = ctk_drag_get_source_widget (context);
10011 suggested_action = cdk_drag_context_get_suggested_action (context);
10012
10013 if (!ctk_editable_get_selection_bounds (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_editable_get_type ()))))))
, &sel1, &sel2) ||
10014 new_position < sel1 || new_position > sel2)
10015 {
10016 if (source_widget == widget)
10017 {
10018 /* Default to MOVE, unless the user has
10019 * pressed ctrl or alt to affect available actions
10020 */
10021 if ((cdk_drag_context_get_actions (context) & CDK_ACTION_MOVE) != 0)
10022 suggested_action = CDK_ACTION_MOVE;
10023 }
10024
10025 priv->dnd_position = new_position;
10026 }
10027 else
10028 {
10029 if (source_widget == widget)
10030 suggested_action = 0; /* Can't drop in selection where drag started */
10031
10032 priv->dnd_position = -1;
10033 }
10034 }
10035 else
10036 {
10037 /* Entry not editable, or no text */
10038 suggested_action = 0;
10039 priv->dnd_position = -1;
10040 }
10041
10042 if (show_placeholder_text (entry))
10043 priv->dnd_position = -1;
10044
10045 cdk_drag_status (context, suggested_action, time);
10046 if (suggested_action == 0)
10047 ctk_drag_unhighlight (widget);
10048 else
10049 ctk_drag_highlight (widget);
10050
10051 if (priv->dnd_position != old_position)
10052 ctk_widget_queue_draw (widget);
10053
10054 return TRUE(!(0));
10055}
10056
10057static void
10058ctk_entry_drag_data_received (CtkWidget *widget,
10059 CdkDragContext *context,
10060 gint x,
10061 gint y G_GNUC_UNUSED__attribute__ ((__unused__)),
10062 CtkSelectionData *selection_data,
10063 guint info G_GNUC_UNUSED__attribute__ ((__unused__)),
10064 guint time)
10065{
10066 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
10067 CtkEntryPrivate *priv = entry->priv;
10068 CtkEditable *editable = CTK_EDITABLE (widget)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_editable_get_type ()))))))
;
10069 gchar *str;
10070
10071 str = (gchar *) ctk_selection_data_get_text (selection_data);
10072
10073 if (str && priv->editable)
10074 {
10075 gint new_position;
10076 gint sel1, sel2;
10077 gint length = -1;
10078
10079 if (priv->truncate_multiline)
10080 length = truncate_multiline (str);
10081
10082 new_position = ctk_entry_find_position (entry, x + priv->scroll_offset);
10083
10084 if (!ctk_editable_get_selection_bounds (editable, &sel1, &sel2) ||
10085 new_position < sel1 || new_position > sel2)
10086 {
10087 ctk_editable_insert_text (editable, str, length, &new_position);
10088 }
10089 else
10090 {
10091 /* Replacing selection */
10092 begin_change (entry);
10093 ctk_editable_delete_text (editable, sel1, sel2);
10094 ctk_editable_insert_text (editable, str, length, &sel1);
10095 end_change (entry);
10096 }
10097
10098 ctk_drag_finish (context, TRUE(!(0)), cdk_drag_context_get_selected_action (context) == CDK_ACTION_MOVE, time);
10099 }
10100 else
10101 {
10102 /* Drag and drop didn't happen! */
10103 ctk_drag_finish (context, FALSE(0), FALSE(0), time);
10104 }
10105
10106 g_free (str);
10107}
10108
10109static void
10110ctk_entry_drag_data_get (CtkWidget *widget,
10111 CdkDragContext *context G_GNUC_UNUSED__attribute__ ((__unused__)),
10112 CtkSelectionData *selection_data,
10113 guint info G_GNUC_UNUSED__attribute__ ((__unused__)),
10114 guint time G_GNUC_UNUSED__attribute__ ((__unused__)))
10115{
10116 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
10117 CtkEntryPrivate *priv = entry->priv;
10118 CtkEditable *editable = CTK_EDITABLE (widget)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_editable_get_type ()))))))
;
10119 gint sel_start, sel_end;
10120 gint i;
10121
10122 /* If there is an icon drag going on, exit early. */
10123 for (i = 0; i < MAX_ICONS2; i++)
10124 {
10125 EntryIconInfo *icon_info = priv->icons[i];
10126
10127 if (icon_info != NULL((void*)0))
10128 {
10129 if (icon_info->in_drag)
10130 return;
10131 }
10132 }
10133
10134 if (ctk_editable_get_selection_bounds (editable, &sel_start, &sel_end))
10135 {
10136 gchar *str = _ctk_entry_get_display_text (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
, sel_start, sel_end);
10137
10138 ctk_selection_data_set_text (selection_data, str, -1);
10139
10140 g_free (str);
10141 }
10142
10143}
10144
10145static void
10146ctk_entry_drag_data_delete (CtkWidget *widget,
10147 CdkDragContext *context G_GNUC_UNUSED__attribute__ ((__unused__)))
10148{
10149 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
10150 CtkEntryPrivate *priv = entry->priv;
10151 CtkEditable *editable = CTK_EDITABLE (widget)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_editable_get_type ()))))))
;
10152 gint sel_start, sel_end;
10153 gint i;
10154
10155 /* If there is an icon drag going on, exit early. */
10156 for (i = 0; i < MAX_ICONS2; i++)
10157 {
10158 EntryIconInfo *icon_info = priv->icons[i];
10159
10160 if (icon_info != NULL((void*)0))
10161 {
10162 if (icon_info->in_drag)
10163 return;
10164 }
10165 }
10166
10167 if (priv->editable &&
10168 ctk_editable_get_selection_bounds (editable, &sel_start, &sel_end))
10169 ctk_editable_delete_text (editable, sel_start, sel_end);
10170}
10171
10172/* We display the cursor when
10173 *
10174 * - the selection is empty, AND
10175 * - the widget has focus
10176 */
10177
10178#define CURSOR_ON_MULTIPLIER2 2
10179#define CURSOR_OFF_MULTIPLIER1 1
10180#define CURSOR_PEND_MULTIPLIER3 3
10181#define CURSOR_DIVIDER3 3
10182
10183static gboolean
10184cursor_blinks (CtkEntry *entry)
10185{
10186 CtkEntryPrivate *priv = entry->priv;
10187
10188 if (ctk_widget_has_focus (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
) &&
10189 priv->editable &&
10190 priv->selection_bound == priv->current_pos)
10191 {
10192 CtkSettings *settings;
10193 gboolean blink;
10194
10195 settings = ctk_widget_get_settings (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
10196 g_object_get (settings, "ctk-cursor-blink", &blink, NULL((void*)0));
10197
10198 return blink;
10199 }
10200 else
10201 return FALSE(0);
10202}
10203
10204static gboolean
10205get_middle_click_paste (CtkEntry *entry)
10206{
10207 CtkSettings *settings;
10208 gboolean paste;
10209
10210 settings = ctk_widget_get_settings (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
10211 g_object_get (settings, "ctk-enable-primary-paste", &paste, NULL((void*)0));
10212
10213 return paste;
10214}
10215
10216static gint
10217get_cursor_time (CtkEntry *entry)
10218{
10219 CtkSettings *settings = ctk_widget_get_settings (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
10220 gint time;
10221
10222 g_object_get (settings, "ctk-cursor-blink-time", &time, NULL((void*)0));
10223
10224 return time;
10225}
10226
10227static gint
10228get_cursor_blink_timeout (CtkEntry *entry)
10229{
10230 CtkSettings *settings = ctk_widget_get_settings (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
10231 gint timeout;
10232
10233 g_object_get (settings, "ctk-cursor-blink-timeout", &timeout, NULL((void*)0));
10234
10235 return timeout;
10236}
10237
10238static void
10239show_cursor (CtkEntry *entry)
10240{
10241 CtkEntryPrivate *priv = entry->priv;
10242 CtkWidget *widget;
10243
10244 if (!priv->cursor_visible)
10245 {
10246 priv->cursor_visible = TRUE(!(0));
10247
10248 widget = CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
;
10249 if (ctk_widget_has_focus (widget) && priv->selection_bound == priv->current_pos)
10250 ctk_widget_queue_draw (widget);
10251 }
10252}
10253
10254static void
10255hide_cursor (CtkEntry *entry)
10256{
10257 CtkEntryPrivate *priv = entry->priv;
10258 CtkWidget *widget;
10259
10260 if (priv->cursor_visible)
10261 {
10262 priv->cursor_visible = FALSE(0);
10263
10264 widget = CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
;
10265 if (ctk_widget_has_focus (widget) && priv->selection_bound == priv->current_pos)
10266 ctk_widget_queue_draw (widget);
10267 }
10268}
10269
10270/*
10271 * Blink!
10272 */
10273static gint
10274blink_cb (gpointer data)
10275{
10276 CtkEntry *entry;
10277 CtkEntryPrivate *priv;
10278 gint blink_timeout;
10279
10280 entry = CTK_ENTRY (data)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((ctk_entry_get_type ()))))))
;
10281 priv = entry->priv;
10282
10283 if (!ctk_widget_has_focus (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
))
10284 {
10285 g_warning ("CtkEntry - did not receive focus-out-event. If you\n"
10286 "connect a handler to this signal, it must return\n"
10287 "CDK_EVENT_PROPAGATE so the entry gets the event as well");
10288
10289 ctk_entry_check_cursor_blink (entry);
10290
10291 return G_SOURCE_REMOVE(0);
10292 }
10293
10294 g_assert (priv->selection_bound == priv->current_pos)do { if (priv->selection_bound == priv->current_pos) ; else
g_assertion_message_expr ("Ctk", "ctkentry.c", 10294, ((const
char*) (__func__)), "priv->selection_bound == priv->current_pos"
); } while (0)
;
10295
10296 blink_timeout = get_cursor_blink_timeout (entry);
10297 if (priv->blink_time > 1000 * blink_timeout &&
10298 blink_timeout < G_MAXINT2147483647/1000)
10299 {
10300 /* we've blinked enough without the user doing anything, stop blinking */
10301 show_cursor (entry);
10302 priv->blink_timeout = 0;
10303 }
10304 else if (priv->cursor_visible)
10305 {
10306 hide_cursor (entry);
10307 priv->blink_timeout = cdk_threads_add_timeout (get_cursor_time (entry) * CURSOR_OFF_MULTIPLIER1 / CURSOR_DIVIDER3,
10308 blink_cb,
10309 entry);
10310 g_source_set_name_by_id (priv->blink_timeout, "[ctk+] blink_cb");
10311 }
10312 else
10313 {
10314 show_cursor (entry);
10315 priv->blink_time += get_cursor_time (entry);
10316 priv->blink_timeout = cdk_threads_add_timeout (get_cursor_time (entry) * CURSOR_ON_MULTIPLIER2 / CURSOR_DIVIDER3,
10317 blink_cb,
10318 entry);
10319 g_source_set_name_by_id (priv->blink_timeout, "[ctk+] blink_cb");
10320 }
10321
10322 return G_SOURCE_REMOVE(0);
10323}
10324
10325static void
10326ctk_entry_check_cursor_blink (CtkEntry *entry)
10327{
10328 CtkEntryPrivate *priv = entry->priv;
10329
10330 if (cursor_blinks (entry))
10331 {
10332 if (!priv->blink_timeout)
10333 {
10334 show_cursor (entry);
10335 priv->blink_timeout = cdk_threads_add_timeout (get_cursor_time (entry) * CURSOR_ON_MULTIPLIER2 / CURSOR_DIVIDER3,
10336 blink_cb,
10337 entry);
10338 g_source_set_name_by_id (priv->blink_timeout, "[ctk+] blink_cb");
10339 }
10340 }
10341 else
10342 {
10343 if (priv->blink_timeout)
10344 {
10345 g_source_remove (priv->blink_timeout);
10346 priv->blink_timeout = 0;
10347 }
10348
10349 priv->cursor_visible = TRUE(!(0));
10350 }
10351}
10352
10353static void
10354ctk_entry_pend_cursor_blink (CtkEntry *entry)
10355{
10356 CtkEntryPrivate *priv = entry->priv;
10357
10358 if (cursor_blinks (entry))
10359 {
10360 if (priv->blink_timeout != 0)
10361 g_source_remove (priv->blink_timeout);
10362
10363 priv->blink_timeout = cdk_threads_add_timeout (get_cursor_time (entry) * CURSOR_PEND_MULTIPLIER3 / CURSOR_DIVIDER3,
10364 blink_cb,
10365 entry);
10366 g_source_set_name_by_id (priv->blink_timeout, "[ctk+] blink_cb");
10367 show_cursor (entry);
10368 }
10369}
10370
10371static void
10372ctk_entry_reset_blink_time (CtkEntry *entry)
10373{
10374 CtkEntryPrivate *priv = entry->priv;
10375
10376 priv->blink_time = 0;
10377}
10378
10379/**
10380 * ctk_entry_set_completion:
10381 * @entry: A #CtkEntry
10382 * @completion: (allow-none): The #CtkEntryCompletion or %NULL
10383 *
10384 * Sets @completion to be the auxiliary completion object to use with @entry.
10385 * All further configuration of the completion mechanism is done on
10386 * @completion using the #CtkEntryCompletion API. Completion is disabled if
10387 * @completion is set to %NULL.
10388 *
10389 * Since: 2.4
10390 */
10391void
10392ctk_entry_set_completion (CtkEntry *entry,
10393 CtkEntryCompletion *completion)
10394{
10395 CtkEntryCompletion *old;
10396
10397 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
10398 g_return_if_fail (!completion || CTK_IS_ENTRY_COMPLETION (completion))do { if ((!completion || (((__extension__ ({ GTypeInstance *__inst
= (GTypeInstance*) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "!completion || CTK_IS_ENTRY_COMPLETION (completion)"
); return; } } while (0)
;
10399
10400 old = ctk_entry_get_completion (entry);
10401
10402 if (old == completion)
10403 return;
10404
10405 if (old)
10406 {
10407 _ctk_entry_completion_disconnect (old);
10408 g_object_unref (old);
10409 }
10410
10411 if (!completion)
10412 {
10413 g_object_set_qdata (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, quark_entry_completion, NULL((void*)0));
10414 return;
10415 }
10416
10417 /* hook into the entry */
10418 g_object_ref (completion)((__typeof__ (completion)) (g_object_ref) (completion));
10419
10420 _ctk_entry_completion_connect (completion, entry);
10421
10422 g_object_set_qdata (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, quark_entry_completion, completion);
10423
10424 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_COMPLETION]);
10425}
10426
10427/**
10428 * ctk_entry_get_completion:
10429 * @entry: A #CtkEntry
10430 *
10431 * Returns the auxiliary completion object currently in use by @entry.
10432 *
10433 * Returns: (transfer none): The auxiliary completion object currently
10434 * in use by @entry.
10435 *
10436 * Since: 2.4
10437 */
10438CtkEntryCompletion *
10439ctk_entry_get_completion (CtkEntry *entry)
10440{
10441 CtkEntryCompletion *completion;
10442
10443 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
10444
10445 completion = CTK_ENTRY_COMPLETION (g_object_get_qdata (G_OBJECT (entry), quark_entry_completion))((((CtkEntryCompletion*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((g_object_get_qdata (((((GObject*) (void *)
g_type_check_instance_cast ((GTypeInstance*) ((entry)), (((GType
) ((20) << (2)))))))), quark_entry_completion))), ((ctk_entry_completion_get_type
()))))))
;
10446
10447 return completion;
10448}
10449
10450/**
10451 * ctk_entry_set_cursor_hadjustment:
10452 * @entry: a #CtkEntry
10453 * @adjustment: (nullable): an adjustment which should be adjusted when the cursor
10454 * is moved, or %NULL
10455 *
10456 * Hooks up an adjustment to the cursor position in an entry, so that when
10457 * the cursor is moved, the adjustment is scrolled to show that position.
10458 * See ctk_scrolled_window_get_hadjustment() for a typical way of obtaining
10459 * the adjustment.
10460 *
10461 * The adjustment has to be in pixel units and in the same coordinate system
10462 * as the entry.
10463 *
10464 * Since: 2.12
10465 */
10466void
10467ctk_entry_set_cursor_hadjustment (CtkEntry *entry,
10468 CtkAdjustment *adjustment)
10469{
10470 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
10471 if (adjustment)
10472 g_return_if_fail (CTK_IS_ADJUSTMENT (adjustment))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((adjustment)); GType __t = ((ctk_adjustment_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; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_ADJUSTMENT (adjustment)"); return; } }
while (0)
;
10473
10474 if (adjustment)
10475 g_object_ref (adjustment)((__typeof__ (adjustment)) (g_object_ref) (adjustment));
10476
10477 g_object_set_qdata_full (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
,
10478 quark_cursor_hadjustment,
10479 adjustment,
10480 g_object_unref);
10481}
10482
10483/**
10484 * ctk_entry_get_cursor_hadjustment:
10485 * @entry: a #CtkEntry
10486 *
10487 * Retrieves the horizontal cursor adjustment for the entry.
10488 * See ctk_entry_set_cursor_hadjustment().
10489 *
10490 * Returns: (transfer none) (nullable): the horizontal cursor adjustment, or %NULL
10491 * if none has been set.
10492 *
10493 * Since: 2.12
10494 */
10495CtkAdjustment*
10496ctk_entry_get_cursor_hadjustment (CtkEntry *entry)
10497{
10498 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
10499
10500 return g_object_get_qdata (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, quark_cursor_hadjustment);
10501}
10502
10503static gboolean
10504tick_cb (CtkWidget *widget,
10505 CdkFrameClock *frame_clock,
10506 gpointer user_data G_GNUC_UNUSED__attribute__ ((__unused__)))
10507{
10508 CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_entry_get_type ()))))))
;
10509 CtkEntryPrivate *priv = entry->priv;
10510 gint64 frame_time;
10511 gdouble iteration, pulse_iterations, current_iterations, fraction;
10512
10513 if (priv->pulse2 == 0 && priv->pulse1 == 0)
10514 return G_SOURCE_CONTINUE(!(0));
10515
10516 frame_time = cdk_frame_clock_get_frame_time (frame_clock);
10517 ctk_progress_tracker_advance_frame (&priv->tracker, frame_time);
10518
10519 g_assert (priv->pulse2 > priv->pulse1)do { if (priv->pulse2 > priv->pulse1) ; else g_assertion_message_expr
("Ctk", "ctkentry.c", 10519, ((const char*) (__func__)), "priv->pulse2 > priv->pulse1"
); } while (0)
;
10520
10521 pulse_iterations = (priv->pulse2 - priv->pulse1) / (gdouble) G_USEC_PER_SEC1000000;
10522 current_iterations = (frame_time - priv->pulse1) / (gdouble) G_USEC_PER_SEC1000000;
10523
10524 iteration = ctk_progress_tracker_get_iteration (&priv->tracker);
10525 /* Determine the fraction to move the block from one frame
10526 * to the next when pulse_fraction is how far the block should
10527 * move between two calls to ctk_entry_progress_pulse().
10528 */
10529 fraction = priv->progress_pulse_fraction * (iteration - priv->last_iteration) / MAX (pulse_iterations, current_iterations)(((pulse_iterations) > (current_iterations)) ? (pulse_iterations
) : (current_iterations))
;
10530 priv->last_iteration = iteration;
10531
10532 if (current_iterations > 3 * pulse_iterations)
10533 return G_SOURCE_CONTINUE(!(0));
10534
10535 /* advance the block */
10536 if (priv->progress_pulse_way_back)
10537 {
10538 priv->progress_pulse_current -= fraction;
10539
10540 if (priv->progress_pulse_current < 0.0)
10541 {
10542 priv->progress_pulse_current = 0.0;
10543 priv->progress_pulse_way_back = FALSE(0);
10544 }
10545 }
10546 else
10547 {
10548 priv->progress_pulse_current += fraction;
10549
10550 if (priv->progress_pulse_current > 1.0 - priv->progress_pulse_fraction)
10551 {
10552 priv->progress_pulse_current = 1.0 - priv->progress_pulse_fraction;
10553 priv->progress_pulse_way_back = TRUE(!(0));
10554 }
10555 }
10556
10557 ctk_widget_queue_allocate (widget);
10558
10559 return G_SOURCE_CONTINUE(!(0));
10560}
10561
10562static void
10563ctk_entry_ensure_progress_gadget (CtkEntry *entry)
10564{
10565 CtkEntryPrivate *priv = entry->priv;
10566
10567 if (priv->progress_gadget)
10568 return;
10569
10570 priv->progress_gadget = ctk_css_custom_gadget_new ("progress",
10571 CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
,
10572 priv->gadget,
10573 NULL((void*)0),
10574 NULL((void*)0),
10575 NULL((void*)0),
10576 NULL((void*)0),
10577 NULL((void*)0),
10578 NULL((void*)0));
10579 ctk_css_gadget_set_state (priv->progress_gadget,
10580 ctk_css_node_get_state (ctk_widget_get_css_node (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
)));
10581
10582 update_node_ordering (entry);
10583}
10584
10585static void
10586ctk_entry_start_pulse_mode (CtkEntry *entry)
10587{
10588 CtkEntryPrivate *priv = entry->priv;
10589
10590 if (priv->progress_pulse_mode)
10591 return;
10592
10593 ctk_entry_ensure_progress_gadget (entry);
10594 ctk_css_gadget_set_visible (priv->progress_gadget, TRUE(!(0)));
10595 ctk_css_gadget_add_class (priv->progress_gadget, CTK_STYLE_CLASS_PULSE"pulse");
10596
10597 priv->progress_pulse_mode = TRUE(!(0));
10598 /* How long each pulse should last depends on calls to ctk_entry_progress_pulse.
10599 * Just start the tracker to repeat forever with iterations every second. */
10600 ctk_progress_tracker_start (&priv->tracker, G_USEC_PER_SEC1000000, 0, INFINITY(__builtin_inff ()));
10601 priv->tick_id = ctk_widget_add_tick_callback (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, tick_cb, NULL((void*)0), NULL((void*)0));
10602
10603 priv->progress_fraction = 0.0;
10604 priv->progress_pulse_way_back = FALSE(0);
10605 priv->progress_pulse_current = 0.0;
10606
10607 priv->pulse2 = 0;
10608 priv->pulse1 = 0;
10609 priv->last_iteration = 0;
10610}
10611
10612static void
10613ctk_entry_stop_pulse_mode (CtkEntry *entry)
10614{
10615 CtkEntryPrivate *priv = entry->priv;
10616
10617 if (priv->progress_pulse_mode)
10618 {
10619 ctk_css_gadget_set_visible (priv->progress_gadget, FALSE(0));
10620 ctk_css_gadget_remove_class (priv->progress_gadget, CTK_STYLE_CLASS_PULSE"pulse");
10621
10622 priv->progress_pulse_mode = FALSE(0);
10623 ctk_widget_remove_tick_callback (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, priv->tick_id);
10624 priv->tick_id = 0;
10625 }
10626}
10627
10628static void
10629ctk_entry_update_pulse (CtkEntry *entry)
10630{
10631 CtkEntryPrivate *priv = entry->priv;
10632 gint64 pulse_time = g_get_monotonic_time ();
10633
10634 if (priv->pulse2 == pulse_time)
10635 return;
10636
10637 priv->pulse1 = priv->pulse2;
10638 priv->pulse2 = pulse_time;
10639}
10640
10641/**
10642 * ctk_entry_set_progress_fraction:
10643 * @entry: a #CtkEntry
10644 * @fraction: fraction of the task that’s been completed
10645 *
10646 * Causes the entry’s progress indicator to “fill in” the given
10647 * fraction of the bar. The fraction should be between 0.0 and 1.0,
10648 * inclusive.
10649 *
10650 * Since: 2.16
10651 */
10652void
10653ctk_entry_set_progress_fraction (CtkEntry *entry,
10654 gdouble fraction)
10655{
10656 CtkWidget *widget;
10657 CtkEntryPrivate *private;
10658 gdouble old_fraction;
10659
10660 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
10661
10662 widget = CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
;
10663 private = entry->priv;
10664
10665 if (private->progress_pulse_mode)
10666 old_fraction = -1;
10667 else
10668 old_fraction = private->progress_fraction;
10669
10670 ctk_entry_stop_pulse_mode (entry);
10671
10672 ctk_entry_ensure_progress_gadget (entry);
10673
10674 fraction = CLAMP (fraction, 0.0, 1.0)(((fraction) > (1.0)) ? (1.0) : (((fraction) < (0.0)) ?
(0.0) : (fraction)))
;
10675 private->progress_fraction = fraction;
10676 private->progress_pulse_current = 0.0;
10677
10678 if (fraction != old_fraction)
10679 {
10680 ctk_css_gadget_set_visible (private->progress_gadget, fraction > 0);
10681
10682 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_PROGRESS_FRACTION]);
10683 ctk_widget_queue_allocate (widget);
10684 }
10685}
10686
10687/**
10688 * ctk_entry_get_progress_fraction:
10689 * @entry: a #CtkEntry
10690 *
10691 * Returns the current fraction of the task that’s been completed.
10692 * See ctk_entry_set_progress_fraction().
10693 *
10694 * Returns: a fraction from 0.0 to 1.0
10695 *
10696 * Since: 2.16
10697 */
10698gdouble
10699ctk_entry_get_progress_fraction (CtkEntry *entry)
10700{
10701 g_return_val_if_fail (CTK_IS_ENTRY (entry), 0.0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (0.0); } } while (0)
;
10702
10703 return entry->priv->progress_fraction;
10704}
10705
10706/**
10707 * ctk_entry_set_progress_pulse_step:
10708 * @entry: a #CtkEntry
10709 * @fraction: fraction between 0.0 and 1.0
10710 *
10711 * Sets the fraction of total entry width to move the progress
10712 * bouncing block for each call to ctk_entry_progress_pulse().
10713 *
10714 * Since: 2.16
10715 */
10716void
10717ctk_entry_set_progress_pulse_step (CtkEntry *entry,
10718 gdouble fraction)
10719{
10720 CtkEntryPrivate *private;
10721
10722 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
10723
10724 private = entry->priv;
10725
10726 fraction = CLAMP (fraction, 0.0, 1.0)(((fraction) > (1.0)) ? (1.0) : (((fraction) < (0.0)) ?
(0.0) : (fraction)))
;
10727
10728 if (fraction != private->progress_pulse_fraction)
10729 {
10730 private->progress_pulse_fraction = fraction;
10731 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_PROGRESS_PULSE_STEP]);
10732 }
10733}
10734
10735/**
10736 * ctk_entry_get_progress_pulse_step:
10737 * @entry: a #CtkEntry
10738 *
10739 * Retrieves the pulse step set with ctk_entry_set_progress_pulse_step().
10740 *
10741 * Returns: a fraction from 0.0 to 1.0
10742 *
10743 * Since: 2.16
10744 */
10745gdouble
10746ctk_entry_get_progress_pulse_step (CtkEntry *entry)
10747{
10748 g_return_val_if_fail (CTK_IS_ENTRY (entry), 0.0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (0.0); } } while (0)
;
10749
10750 return entry->priv->progress_pulse_fraction;
10751}
10752
10753/**
10754 * ctk_entry_progress_pulse:
10755 * @entry: a #CtkEntry
10756 *
10757 * Indicates that some progress is made, but you don’t know how much.
10758 * Causes the entry’s progress indicator to enter “activity mode,”
10759 * where a block bounces back and forth. Each call to
10760 * ctk_entry_progress_pulse() causes the block to move by a little bit
10761 * (the amount of movement per pulse is determined by
10762 * ctk_entry_set_progress_pulse_step()).
10763 *
10764 * Since: 2.16
10765 */
10766void
10767ctk_entry_progress_pulse (CtkEntry *entry)
10768{
10769 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
10770
10771 ctk_entry_start_pulse_mode (entry);
10772 ctk_entry_update_pulse (entry);
10773}
10774
10775/**
10776 * ctk_entry_set_placeholder_text:
10777 * @entry: a #CtkEntry
10778 * @text: (nullable): a string to be displayed when @entry is empty and unfocused, or %NULL
10779 *
10780 * Sets text to be displayed in @entry when it is empty and unfocused.
10781 * This can be used to give a visual hint of the expected contents of
10782 * the #CtkEntry.
10783 *
10784 * Note that since the placeholder text gets removed when the entry
10785 * received focus, using this feature is a bit problematic if the entry
10786 * is given the initial focus in a window. Sometimes this can be
10787 * worked around by delaying the initial focus setting until the
10788 * first key event arrives.
10789 *
10790 * Since: 3.2
10791 **/
10792void
10793ctk_entry_set_placeholder_text (CtkEntry *entry,
10794 const gchar *text)
10795{
10796 CtkEntryPrivate *priv;
10797
10798 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
10799
10800 priv = entry->priv;
10801
10802 if (g_strcmp0 (priv->placeholder_text, text) == 0)
10803 return;
10804
10805 g_free (priv->placeholder_text);
10806 priv->placeholder_text = g_strdup (text)g_strdup_inline (text);
10807
10808 ctk_entry_recompute (entry);
10809
10810 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_PLACEHOLDER_TEXT]);
10811}
10812
10813/**
10814 * ctk_entry_get_placeholder_text:
10815 * @entry: a #CtkEntry
10816 *
10817 * Retrieves the text that will be displayed when @entry is empty and unfocused
10818 *
10819 * Returns: a pointer to the placeholder text as a string. This string points to internally allocated
10820 * storage in the widget and must not be freed, modified or stored.
10821 *
10822 * Since: 3.2
10823 **/
10824const gchar *
10825ctk_entry_get_placeholder_text (CtkEntry *entry)
10826{
10827 CtkEntryPrivate *priv;
10828
10829 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
10830
10831 priv = entry->priv;
10832
10833 return priv->placeholder_text;
10834}
10835
10836/* Caps Lock warning for password entries */
10837
10838static void
10839show_capslock_feedback (CtkEntry *entry,
10840 const gchar *text)
10841{
10842 CtkEntryPrivate *priv = entry->priv;
10843
10844 if (ctk_entry_get_icon_storage_type (entry, CTK_ENTRY_ICON_SECONDARY) == CTK_IMAGE_EMPTY)
10845 {
10846 ctk_entry_set_icon_from_icon_name (entry, CTK_ENTRY_ICON_SECONDARY, "caps-lock-symbolic");
10847 ctk_entry_set_icon_activatable (entry, CTK_ENTRY_ICON_SECONDARY, FALSE(0));
10848 priv->caps_lock_warning_shown = TRUE(!(0));
10849 }
10850
10851 if (priv->caps_lock_warning_shown)
10852 ctk_entry_set_icon_tooltip_text (entry, CTK_ENTRY_ICON_SECONDARY, text);
10853 else
10854 g_warning ("Can't show Caps Lock warning, since secondary icon is set");
10855}
10856
10857static void
10858remove_capslock_feedback (CtkEntry *entry)
10859{
10860 CtkEntryPrivate *priv = entry->priv;
10861
10862 if (priv->caps_lock_warning_shown)
10863 {
10864 ctk_entry_set_icon_from_icon_name (entry, CTK_ENTRY_ICON_SECONDARY, NULL((void*)0));
10865 priv->caps_lock_warning_shown = FALSE(0);
10866 }
10867}
10868
10869static void
10870keymap_state_changed (CdkKeymap *keymap,
10871 CtkEntry *entry)
10872{
10873 CtkEntryPrivate *priv = entry->priv;
10874 char *text = NULL((void*)0);
10875
10876 if (ctk_entry_get_display_mode (entry) != DISPLAY_NORMAL && priv->caps_lock_warning)
10877 {
10878 if (cdk_keymap_get_caps_lock_state (keymap))
10879 text = _("Caps Lock is on")((char *) g_dgettext ("ctk30", "Caps Lock is on"));
10880 }
10881
10882 if (text)
10883 show_capslock_feedback (entry, text);
10884 else
10885 remove_capslock_feedback (entry);
10886}
10887
10888/**
10889 * ctk_entry_set_input_purpose:
10890 * @entry: a #CtkEntry
10891 * @purpose: the purpose
10892 *
10893 * Sets the #CtkEntry:input-purpose property which
10894 * can be used by on-screen keyboards and other input
10895 * methods to adjust their behaviour.
10896 *
10897 * Since: 3.6
10898 */
10899void
10900ctk_entry_set_input_purpose (CtkEntry *entry,
10901 CtkInputPurpose purpose)
10902
10903{
10904 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
10905
10906 if (ctk_entry_get_input_purpose (entry) != purpose)
10907 {
10908 g_object_set (G_OBJECT (entry->priv->im_context)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry->priv->im_context)), (((GType) ((20) <<
(2))))))))
,
10909 "input-purpose", purpose,
10910 NULL((void*)0));
10911
10912 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_INPUT_PURPOSE]);
10913 }
10914}
10915
10916/**
10917 * ctk_entry_get_input_purpose:
10918 * @entry: a #CtkEntry
10919 *
10920 * Gets the value of the #CtkEntry:input-purpose property.
10921 *
10922 * Since: 3.6
10923 */
10924CtkInputPurpose
10925ctk_entry_get_input_purpose (CtkEntry *entry)
10926{
10927 CtkInputPurpose purpose;
10928
10929 g_return_val_if_fail (CTK_IS_ENTRY (entry), CTK_INPUT_PURPOSE_FREE_FORM)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (CTK_INPUT_PURPOSE_FREE_FORM
); } } while (0)
;
10930
10931 g_object_get (G_OBJECT (entry->priv->im_context)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry->priv->im_context)), (((GType) ((20) <<
(2))))))))
,
10932 "input-purpose", &purpose,
10933 NULL((void*)0));
10934
10935 return purpose;
10936}
10937
10938/**
10939 * ctk_entry_set_input_hints:
10940 * @entry: a #CtkEntry
10941 * @hints: the hints
10942 *
10943 * Sets the #CtkEntry:input-hints property, which
10944 * allows input methods to fine-tune their behaviour.
10945 *
10946 * Since: 3.6
10947 */
10948void
10949ctk_entry_set_input_hints (CtkEntry *entry,
10950 CtkInputHints hints)
10951
10952{
10953 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
10954
10955 if (ctk_entry_get_input_hints (entry) != hints)
10956 {
10957 g_object_set (G_OBJECT (entry->priv->im_context)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry->priv->im_context)), (((GType) ((20) <<
(2))))))))
,
10958 "input-hints", hints,
10959 NULL((void*)0));
10960
10961 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_INPUT_HINTS]);
10962 }
10963}
10964
10965/**
10966 * ctk_entry_get_input_hints:
10967 * @entry: a #CtkEntry
10968 *
10969 * Gets the value of the #CtkEntry:input-hints property.
10970 *
10971 * Since: 3.6
10972 */
10973CtkInputHints
10974ctk_entry_get_input_hints (CtkEntry *entry)
10975{
10976 CtkInputHints hints;
10977
10978 g_return_val_if_fail (CTK_IS_ENTRY (entry), CTK_INPUT_HINT_NONE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (CTK_INPUT_HINT_NONE); } }
while (0)
;
10979
10980 g_object_get (G_OBJECT (entry->priv->im_context)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry->priv->im_context)), (((GType) ((20) <<
(2))))))))
,
10981 "input-hints", &hints,
10982 NULL((void*)0));
10983
10984 return hints;
10985}
10986
10987/**
10988 * ctk_entry_set_attributes:
10989 * @entry: a #CtkEntry
10990 * @attrs: a #PangoAttrList
10991 *
10992 * Sets a #PangoAttrList; the attributes in the list are applied to the
10993 * entry text.
10994 *
10995 * Since: 3.6
10996 */
10997void
10998ctk_entry_set_attributes (CtkEntry *entry,
10999 PangoAttrList *attrs)
11000{
11001 CtkEntryPrivate *priv = entry->priv;
11002 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
11003
11004 if (attrs)
11005 pango_attr_list_ref (attrs);
11006
11007 if (priv->attrs)
11008 pango_attr_list_unref (priv->attrs);
11009 priv->attrs = attrs;
11010
11011 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_ATTRIBUTES]);
11012
11013 ctk_entry_recompute (entry);
11014 ctk_widget_queue_resize (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
11015}
11016
11017/**
11018 * ctk_entry_get_attributes:
11019 * @entry: a #CtkEntry
11020 *
11021 * Gets the attribute list that was set on the entry using
11022 * ctk_entry_set_attributes(), if any.
11023 *
11024 * Returns: (transfer none) (nullable): the attribute list, or %NULL
11025 * if none was set.
11026 *
11027 * Since: 3.6
11028 */
11029PangoAttrList *
11030ctk_entry_get_attributes (CtkEntry *entry)
11031{
11032 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
11033
11034 return entry->priv->attrs;
11035}
11036
11037/**
11038 * ctk_entry_set_tabs:
11039 * @entry: a #CtkEntry
11040 * @tabs: a #PangoTabArray
11041 *
11042 * Sets a #PangoTabArray; the tabstops in the array are applied to the entry
11043 * text.
11044 *
11045 * Since: 3.10
11046 */
11047
11048void
11049ctk_entry_set_tabs (CtkEntry *entry,
11050 PangoTabArray *tabs)
11051{
11052 CtkEntryPrivate *priv;
11053 g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return; } } while (0)
;
11054
11055 priv = entry->priv;
11056 if (priv->tabs)
11057 pango_tab_array_free(priv->tabs);
11058
11059 if (tabs)
11060 priv->tabs = pango_tab_array_copy (tabs);
11061 else
11062 priv->tabs = NULL((void*)0);
11063
11064 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_TABS]);
11065
11066 ctk_entry_recompute (entry);
11067 ctk_widget_queue_resize (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
11068}
11069
11070/**
11071 * ctk_entry_get_tabs:
11072 * @entry: a #CtkEntry
11073 *
11074 * Gets the tabstops that were set on the entry using ctk_entry_set_tabs(), if
11075 * any.
11076 *
11077 * Returns: (nullable) (transfer none): the tabstops, or %NULL if none was set.
11078 *
11079 * Since: 3.10
11080 */
11081
11082PangoTabArray *
11083ctk_entry_get_tabs (CtkEntry *entry)
11084{
11085 g_return_val_if_fail (CTK_IS_ENTRY (entry), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_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; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_ENTRY (entry)"); return (((void*)0)); } } while (
0)
;
11086
11087 return entry->priv->tabs;
11088}
11089
11090static void
11091ctk_entry_insert_emoji (CtkEntry *entry)
11092{
11093 CtkWidget *chooser;
11094 CdkRectangle rect;
11095
11096 if (ctk_entry_get_input_hints (entry) & CTK_INPUT_HINT_NO_EMOJI)
11097 return;
11098
11099 if (ctk_widget_get_ancestor (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
, CTK_TYPE_EMOJI_CHOOSER(ctk_emoji_chooser_get_type ())) != NULL((void*)0))
11100 return;
11101
11102 chooser = CTK_WIDGET (g_object_get_data (G_OBJECT (entry), "ctk-emoji-chooser"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((entry)), (((GType) ((20) << (2))))
)))), "ctk-emoji-chooser"))), ((ctk_widget_get_type ()))))))
;
11103 if (!chooser)
11104 {
11105 chooser = ctk_emoji_chooser_new ();
11106 g_object_set_data (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, "ctk-emoji-chooser", chooser);
11107
11108 ctk_popover_set_relative_to (CTK_POPOVER (chooser)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), ((ctk_popover_get_type ()))))))
, CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
11109 if (entry->priv->show_emoji_icon)
11110 {
11111 ctk_entry_get_icon_area (entry, CTK_ENTRY_ICON_SECONDARY, &rect);
11112 ctk_popover_set_pointing_to (CTK_POPOVER (chooser)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), ((ctk_popover_get_type ()))))))
, &rect);
11113 }
11114 g_signal_connect_swapped (chooser, "emoji-picked", G_CALLBACK (ctk_entry_enter_text), entry)g_signal_connect_data ((chooser), ("emoji-picked"), (((GCallback
) (ctk_entry_enter_text))), (entry), ((void*)0), G_CONNECT_SWAPPED
)
;
11115 }
11116
11117 ctk_popover_popup (CTK_POPOVER (chooser)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), ((ctk_popover_get_type ()))))))
);
11118}
11119
11120static void
11121pick_emoji (CtkEntry *entry,
11122 int icon,
11123 CdkEvent *event G_GNUC_UNUSED__attribute__ ((__unused__)),
11124 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
11125{
11126 if (icon == CTK_ENTRY_ICON_SECONDARY)
11127 ctk_entry_insert_emoji (entry);
11128}
11129
11130static void
11131set_show_emoji_icon (CtkEntry *entry,
11132 gboolean value)
11133{
11134 CtkEntryPrivate *priv = entry->priv;
11135
11136 if (priv->show_emoji_icon == value)
11137 return;
11138
11139 priv->show_emoji_icon = value;
11140
11141 if (priv->show_emoji_icon)
11142 {
11143 ctk_entry_set_icon_from_icon_name (entry,
11144 CTK_ENTRY_ICON_SECONDARY,
11145 "face-smile-symbolic");
11146
11147 ctk_entry_set_icon_sensitive (entry,
11148 CTK_ENTRY_ICON_SECONDARY,
11149 TRUE(!(0)));
11150
11151 ctk_entry_set_icon_activatable (entry,
11152 CTK_ENTRY_ICON_SECONDARY,
11153 TRUE(!(0)));
11154
11155 ctk_entry_set_icon_tooltip_text (entry,
11156 CTK_ENTRY_ICON_SECONDARY,
11157 _("Insert Emoji")((char *) g_dgettext ("ctk30", "Insert Emoji")));
11158
11159 g_signal_connect (entry, "icon-press", G_CALLBACK (pick_emoji), NULL)g_signal_connect_data ((entry), ("icon-press"), (((GCallback)
(pick_emoji))), (((void*)0)), ((void*)0), (GConnectFlags) 0)
;
11160 }
11161 else
11162 {
11163 g_signal_handlers_disconnect_by_func (entry, pick_emoji, NULL)g_signal_handlers_disconnect_matched ((entry), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (pick_emoji), (((void*)0)))
;
11164
11165 ctk_entry_set_icon_from_icon_name (entry,
11166 CTK_ENTRY_ICON_SECONDARY,
11167 NULL((void*)0));
11168
11169 ctk_entry_set_icon_tooltip_text (entry,
11170 CTK_ENTRY_ICON_SECONDARY,
11171 NULL((void*)0));
11172 }
11173
11174 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_SHOW_EMOJI_ICON]);
11175 ctk_widget_queue_resize (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_widget_get_type ()))))))
);
11176}
11177
11178static void
11179set_enable_emoji_completion (CtkEntry *entry,
11180 gboolean value)
11181{
11182 CtkEntryPrivate *priv = ctk_entry_get_instance_private (entry);
11183
11184 if (priv->enable_emoji_completion == value)
11185 return;
11186
11187 priv->enable_emoji_completion = value;
11188
11189 if (priv->enable_emoji_completion)
11190 g_object_set_data (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, "emoji-completion-popup",
11191 ctk_emoji_completion_new (entry));
11192 else
11193 g_object_set_data (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, "emoji-completion-popup", NULL((void*)0));
11194
11195 g_object_notify_by_pspec (G_OBJECT (entry)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), (((GType) ((20) << (2))))))))
, entry_props[PROP_ENABLE_EMOJI_COMPLETION]);
11196}