1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gtk.IMContext;
26 
27 private import gdk.Window;
28 private import glib.Str;
29 private import gobject.ObjectG;
30 private import gobject.Signals;
31 private import gtk.c.functions;
32 public  import gtk.c.types;
33 public  import gtkc.gtktypes;
34 private import pango.PgAttributeList;
35 private import std.algorithm;
36 
37 
38 /**
39  * #GtkIMContext defines the interface for GTK+ input methods. An input method
40  * is used by GTK+ text input widgets like #GtkEntry to map from key events to
41  * Unicode character strings.
42  * 
43  * The default input method can be set programmatically via the
44  * #GtkSettings:gtk-im-module GtkSettings property. Alternatively, you may set
45  * the GTK_IM_MODULE environment variable as documented in
46  * [Running GTK+ Applications][gtk-running].
47  * 
48  * The #GtkEntry #GtkEntry:im-module and #GtkTextView #GtkTextView:im-module
49  * properties may also be used to set input methods for specific widget
50  * instances. For instance, a certain entry widget might be expected to contain
51  * certain characters which would be easier to input with a certain input
52  * method.
53  * 
54  * An input method may consume multiple key events in sequence and finally
55  * output the composed result. This is called preediting, and an input method
56  * may provide feedback about this process by displaying the intermediate
57  * composition states as preedit text. For instance, the default GTK+ input
58  * method implements the input of arbitrary Unicode code points by holding down
59  * the Control and Shift keys and then typing “U” followed by the hexadecimal
60  * digits of the code point.  When releasing the Control and Shift keys,
61  * preediting ends and the character is inserted as text. Ctrl+Shift+u20AC for
62  * example results in the € sign.
63  * 
64  * Additional input methods can be made available for use by GTK+ widgets as
65  * loadable modules. An input method module is a small shared library which
66  * implements a subclass of #GtkIMContext or #GtkIMContextSimple and exports
67  * these four functions:
68  * 
69  * |[<!-- language="C" -->
70  * void im_module_init(GTypeModule *module);
71  * ]|
72  * This function should register the #GType of the #GtkIMContext subclass which
73  * implements the input method by means of g_type_module_register_type(). Note
74  * that g_type_register_static() cannot be used as the type needs to be
75  * registered dynamically.
76  * 
77  * |[<!-- language="C" -->
78  * void im_module_exit(void);
79  * ]|
80  * Here goes any cleanup code your input method might require on module unload.
81  * 
82  * |[<!-- language="C" -->
83  * void im_module_list(const GtkIMContextInfo ***contexts, int *n_contexts)
84  * {
85  * *contexts = info_list;
86  * *n_contexts = G_N_ELEMENTS (info_list);
87  * }
88  * ]|
89  * This function returns the list of input methods provided by the module. The
90  * example implementation above shows a common solution and simply returns a
91  * pointer to statically defined array of #GtkIMContextInfo items for each
92  * provided input method.
93  * 
94  * |[<!-- language="C" -->
95  * GtkIMContext * im_module_create(const gchar *context_id);
96  * ]|
97  * This function should return a pointer to a newly created instance of the
98  * #GtkIMContext subclass identified by @context_id. The context ID is the same
99  * as specified in the #GtkIMContextInfo array returned by im_module_list().
100  * 
101  * After a new loadable input method module has been installed on the system,
102  * the configuration file `gtk.immodules` needs to be
103  * regenerated by [gtk-query-immodules-3.0][gtk-query-immodules-3.0],
104  * in order for the new input method to become available to GTK+ applications.
105  */
106 public class IMContext : ObjectG
107 {
108 	/** the main Gtk struct */
109 	protected GtkIMContext* gtkIMContext;
110 
111 	/** Get the main Gtk struct */
112 	public GtkIMContext* getIMContextStruct(bool transferOwnership = false)
113 	{
114 		if (transferOwnership)
115 			ownedRef = false;
116 		return gtkIMContext;
117 	}
118 
119 	/** the main Gtk struct as a void* */
120 	protected override void* getStruct()
121 	{
122 		return cast(void*)gtkIMContext;
123 	}
124 
125 	/**
126 	 * Sets our main struct and passes it to the parent class.
127 	 */
128 	public this (GtkIMContext* gtkIMContext, bool ownedRef = false)
129 	{
130 		this.gtkIMContext = gtkIMContext;
131 		super(cast(GObject*)gtkIMContext, ownedRef);
132 	}
133 
134 
135 	/** */
136 	public static GType getType()
137 	{
138 		return gtk_im_context_get_type();
139 	}
140 
141 	/**
142 	 * Asks the widget that the input context is attached to to delete
143 	 * characters around the cursor position by emitting the
144 	 * GtkIMContext::delete_surrounding signal. Note that @offset and @n_chars
145 	 * are in characters not in bytes which differs from the usage other
146 	 * places in #GtkIMContext.
147 	 *
148 	 * In order to use this function, you should first call
149 	 * gtk_im_context_get_surrounding() to get the current context, and
150 	 * call this function immediately afterwards to make sure that you
151 	 * know what you are deleting. You should also account for the fact
152 	 * that even if the signal was handled, the input context might not
153 	 * have deleted all the characters that were requested to be deleted.
154 	 *
155 	 * This function is used by an input method that wants to make
156 	 * subsitutions in the existing text in response to new input. It is
157 	 * not useful for applications.
158 	 *
159 	 * Params:
160 	 *     offset = offset from cursor position in chars;
161 	 *         a negative value means start before the cursor.
162 	 *     nChars = number of characters to delete.
163 	 *
164 	 * Returns: %TRUE if the signal was handled.
165 	 */
166 	public bool deleteSurrounding(int offset, int nChars)
167 	{
168 		return gtk_im_context_delete_surrounding(gtkIMContext, offset, nChars) != 0;
169 	}
170 
171 	/**
172 	 * Allow an input method to internally handle key press and release
173 	 * events. If this function returns %TRUE, then no further processing
174 	 * should be done for this key event.
175 	 *
176 	 * Params:
177 	 *     event = the key event
178 	 *
179 	 * Returns: %TRUE if the input method handled the key event.
180 	 */
181 	public bool filterKeypress(GdkEventKey* event)
182 	{
183 		return gtk_im_context_filter_keypress(gtkIMContext, event) != 0;
184 	}
185 
186 	/**
187 	 * Notify the input method that the widget to which this
188 	 * input context corresponds has gained focus. The input method
189 	 * may, for example, change the displayed feedback to reflect
190 	 * this change.
191 	 */
192 	public void focusIn()
193 	{
194 		gtk_im_context_focus_in(gtkIMContext);
195 	}
196 
197 	/**
198 	 * Notify the input method that the widget to which this
199 	 * input context corresponds has lost focus. The input method
200 	 * may, for example, change the displayed feedback or reset the contexts
201 	 * state to reflect this change.
202 	 */
203 	public void focusOut()
204 	{
205 		gtk_im_context_focus_out(gtkIMContext);
206 	}
207 
208 	/**
209 	 * Retrieve the current preedit string for the input context,
210 	 * and a list of attributes to apply to the string.
211 	 * This string should be displayed inserted at the insertion
212 	 * point.
213 	 *
214 	 * Params:
215 	 *     str = location to store the retrieved
216 	 *         string. The string retrieved must be freed with g_free().
217 	 *     attrs = location to store the retrieved
218 	 *         attribute list.  When you are done with this list, you
219 	 *         must unreference it with pango_attr_list_unref().
220 	 *     cursorPos = location to store position of cursor (in characters)
221 	 *         within the preedit string.
222 	 */
223 	public void getPreeditString(out string str, out PgAttributeList attrs, out int cursorPos)
224 	{
225 		char* outstr = null;
226 		PangoAttrList* outattrs = null;
227 
228 		gtk_im_context_get_preedit_string(gtkIMContext, &outstr, &outattrs, &cursorPos);
229 
230 		str = Str.toString(outstr);
231 		attrs = ObjectG.getDObject!(PgAttributeList)(outattrs);
232 	}
233 
234 	/**
235 	 * Retrieves context around the insertion point. Input methods
236 	 * typically want context in order to constrain input text based on
237 	 * existing text; this is important for languages such as Thai where
238 	 * only some sequences of characters are allowed.
239 	 *
240 	 * This function is implemented by emitting the
241 	 * GtkIMContext::retrieve_surrounding signal on the input method; in
242 	 * response to this signal, a widget should provide as much context as
243 	 * is available, up to an entire paragraph, by calling
244 	 * gtk_im_context_set_surrounding(). Note that there is no obligation
245 	 * for a widget to respond to the ::retrieve_surrounding signal, so input
246 	 * methods must be prepared to function without context.
247 	 *
248 	 * Params:
249 	 *     text = location to store a UTF-8 encoded
250 	 *         string of text holding context around the insertion point.
251 	 *         If the function returns %TRUE, then you must free the result
252 	 *         stored in this location with g_free().
253 	 *     cursorIndex = location to store byte index of the insertion
254 	 *         cursor within @text.
255 	 *
256 	 * Returns: %TRUE if surrounding text was provided; in this case
257 	 *     you must free the result stored in *text.
258 	 */
259 	public bool getSurrounding(out string text, out int cursorIndex)
260 	{
261 		char* outtext = null;
262 
263 		auto p = gtk_im_context_get_surrounding(gtkIMContext, &outtext, &cursorIndex) != 0;
264 
265 		text = Str.toString(outtext);
266 
267 		return p;
268 	}
269 
270 	/**
271 	 * Notify the input method that a change such as a change in cursor
272 	 * position has been made. This will typically cause the input
273 	 * method to clear the preedit state.
274 	 */
275 	public void reset()
276 	{
277 		gtk_im_context_reset(gtkIMContext);
278 	}
279 
280 	/**
281 	 * Set the client window for the input context; this is the
282 	 * #GdkWindow in which the input appears. This window is
283 	 * used in order to correctly position status windows, and may
284 	 * also be used for purposes internal to the input method.
285 	 *
286 	 * Params:
287 	 *     window = the client window. This may be %NULL to indicate
288 	 *         that the previous client window no longer exists.
289 	 */
290 	public void setClientWindow(Window window)
291 	{
292 		gtk_im_context_set_client_window(gtkIMContext, (window is null) ? null : window.getWindowStruct());
293 	}
294 
295 	/**
296 	 * Notify the input method that a change in cursor
297 	 * position has been made. The location is relative to the client
298 	 * window.
299 	 *
300 	 * Params:
301 	 *     area = new location
302 	 */
303 	public void setCursorLocation(GdkRectangle* area)
304 	{
305 		gtk_im_context_set_cursor_location(gtkIMContext, area);
306 	}
307 
308 	/**
309 	 * Sets surrounding context around the insertion point and preedit
310 	 * string. This function is expected to be called in response to the
311 	 * GtkIMContext::retrieve_surrounding signal, and will likely have no
312 	 * effect if called at other times.
313 	 *
314 	 * Params:
315 	 *     text = text surrounding the insertion point, as UTF-8.
316 	 *         the preedit string should not be included within
317 	 *         @text.
318 	 *     len = the length of @text, or -1 if @text is nul-terminated
319 	 *     cursorIndex = the byte index of the insertion cursor within @text.
320 	 */
321 	public void setSurrounding(string text, int len, int cursorIndex)
322 	{
323 		gtk_im_context_set_surrounding(gtkIMContext, Str.toStringz(text), len, cursorIndex);
324 	}
325 
326 	/**
327 	 * Sets whether the IM context should use the preedit string
328 	 * to display feedback. If @use_preedit is FALSE (default
329 	 * is TRUE), then the IM context may use some other method to display
330 	 * feedback, such as displaying it in a child of the root window.
331 	 *
332 	 * Params:
333 	 *     usePreedit = whether the IM context should use the preedit string.
334 	 */
335 	public void setUsePreedit(bool usePreedit)
336 	{
337 		gtk_im_context_set_use_preedit(gtkIMContext, usePreedit);
338 	}
339 
340 	protected class OnCommitDelegateWrapper
341 	{
342 		void delegate(string, IMContext) dlg;
343 		gulong handlerId;
344 
345 		this(void delegate(string, IMContext) dlg)
346 		{
347 			this.dlg = dlg;
348 			onCommitListeners ~= this;
349 		}
350 
351 		void remove(OnCommitDelegateWrapper source)
352 		{
353 			foreach(index, wrapper; onCommitListeners)
354 			{
355 				if (wrapper.handlerId == source.handlerId)
356 				{
357 					onCommitListeners[index] = null;
358 					onCommitListeners = std.algorithm.remove(onCommitListeners, index);
359 					break;
360 				}
361 			}
362 		}
363 	}
364 	OnCommitDelegateWrapper[] onCommitListeners;
365 
366 	/**
367 	 * The ::commit signal is emitted when a complete input sequence
368 	 * has been entered by the user. This can be a single character
369 	 * immediately after a key press or the final result of preediting.
370 	 *
371 	 * Params:
372 	 *     str = the completed character(s) entered by the user
373 	 */
374 	gulong addOnCommit(void delegate(string, IMContext) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
375 	{
376 		auto wrapper = new OnCommitDelegateWrapper(dlg);
377 		wrapper.handlerId = Signals.connectData(
378 			this,
379 			"commit",
380 			cast(GCallback)&callBackCommit,
381 			cast(void*)wrapper,
382 			cast(GClosureNotify)&callBackCommitDestroy,
383 			connectFlags);
384 		return wrapper.handlerId;
385 	}
386 
387 	extern(C) static void callBackCommit(GtkIMContext* imcontextStruct, char* str, OnCommitDelegateWrapper wrapper)
388 	{
389 		wrapper.dlg(Str.toString(str), wrapper.outer);
390 	}
391 
392 	extern(C) static void callBackCommitDestroy(OnCommitDelegateWrapper wrapper, GClosure* closure)
393 	{
394 		wrapper.remove(wrapper);
395 	}
396 
397 	protected class OnDeleteSurroundingDelegateWrapper
398 	{
399 		bool delegate(int, int, IMContext) dlg;
400 		gulong handlerId;
401 
402 		this(bool delegate(int, int, IMContext) dlg)
403 		{
404 			this.dlg = dlg;
405 			onDeleteSurroundingListeners ~= this;
406 		}
407 
408 		void remove(OnDeleteSurroundingDelegateWrapper source)
409 		{
410 			foreach(index, wrapper; onDeleteSurroundingListeners)
411 			{
412 				if (wrapper.handlerId == source.handlerId)
413 				{
414 					onDeleteSurroundingListeners[index] = null;
415 					onDeleteSurroundingListeners = std.algorithm.remove(onDeleteSurroundingListeners, index);
416 					break;
417 				}
418 			}
419 		}
420 	}
421 	OnDeleteSurroundingDelegateWrapper[] onDeleteSurroundingListeners;
422 
423 	/**
424 	 * The ::delete-surrounding signal is emitted when the input method
425 	 * needs to delete all or part of the context surrounding the cursor.
426 	 *
427 	 * Params:
428 	 *     offset = the character offset from the cursor position of the text
429 	 *         to be deleted. A negative value indicates a position before
430 	 *         the cursor.
431 	 *     nChars = the number of characters to be deleted
432 	 *
433 	 * Returns: %TRUE if the signal was handled.
434 	 */
435 	gulong addOnDeleteSurrounding(bool delegate(int, int, IMContext) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
436 	{
437 		auto wrapper = new OnDeleteSurroundingDelegateWrapper(dlg);
438 		wrapper.handlerId = Signals.connectData(
439 			this,
440 			"delete-surrounding",
441 			cast(GCallback)&callBackDeleteSurrounding,
442 			cast(void*)wrapper,
443 			cast(GClosureNotify)&callBackDeleteSurroundingDestroy,
444 			connectFlags);
445 		return wrapper.handlerId;
446 	}
447 
448 	extern(C) static int callBackDeleteSurrounding(GtkIMContext* imcontextStruct, int offset, int nChars, OnDeleteSurroundingDelegateWrapper wrapper)
449 	{
450 		return wrapper.dlg(offset, nChars, wrapper.outer);
451 	}
452 
453 	extern(C) static void callBackDeleteSurroundingDestroy(OnDeleteSurroundingDelegateWrapper wrapper, GClosure* closure)
454 	{
455 		wrapper.remove(wrapper);
456 	}
457 
458 	protected class OnPreeditChangedDelegateWrapper
459 	{
460 		void delegate(IMContext) dlg;
461 		gulong handlerId;
462 
463 		this(void delegate(IMContext) dlg)
464 		{
465 			this.dlg = dlg;
466 			onPreeditChangedListeners ~= this;
467 		}
468 
469 		void remove(OnPreeditChangedDelegateWrapper source)
470 		{
471 			foreach(index, wrapper; onPreeditChangedListeners)
472 			{
473 				if (wrapper.handlerId == source.handlerId)
474 				{
475 					onPreeditChangedListeners[index] = null;
476 					onPreeditChangedListeners = std.algorithm.remove(onPreeditChangedListeners, index);
477 					break;
478 				}
479 			}
480 		}
481 	}
482 	OnPreeditChangedDelegateWrapper[] onPreeditChangedListeners;
483 
484 	/**
485 	 * The ::preedit-changed signal is emitted whenever the preedit sequence
486 	 * currently being entered has changed.  It is also emitted at the end of
487 	 * a preedit sequence, in which case
488 	 * gtk_im_context_get_preedit_string() returns the empty string.
489 	 */
490 	gulong addOnPreeditChanged(void delegate(IMContext) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
491 	{
492 		auto wrapper = new OnPreeditChangedDelegateWrapper(dlg);
493 		wrapper.handlerId = Signals.connectData(
494 			this,
495 			"preedit-changed",
496 			cast(GCallback)&callBackPreeditChanged,
497 			cast(void*)wrapper,
498 			cast(GClosureNotify)&callBackPreeditChangedDestroy,
499 			connectFlags);
500 		return wrapper.handlerId;
501 	}
502 
503 	extern(C) static void callBackPreeditChanged(GtkIMContext* imcontextStruct, OnPreeditChangedDelegateWrapper wrapper)
504 	{
505 		wrapper.dlg(wrapper.outer);
506 	}
507 
508 	extern(C) static void callBackPreeditChangedDestroy(OnPreeditChangedDelegateWrapper wrapper, GClosure* closure)
509 	{
510 		wrapper.remove(wrapper);
511 	}
512 
513 	protected class OnPreeditEndDelegateWrapper
514 	{
515 		void delegate(IMContext) dlg;
516 		gulong handlerId;
517 
518 		this(void delegate(IMContext) dlg)
519 		{
520 			this.dlg = dlg;
521 			onPreeditEndListeners ~= this;
522 		}
523 
524 		void remove(OnPreeditEndDelegateWrapper source)
525 		{
526 			foreach(index, wrapper; onPreeditEndListeners)
527 			{
528 				if (wrapper.handlerId == source.handlerId)
529 				{
530 					onPreeditEndListeners[index] = null;
531 					onPreeditEndListeners = std.algorithm.remove(onPreeditEndListeners, index);
532 					break;
533 				}
534 			}
535 		}
536 	}
537 	OnPreeditEndDelegateWrapper[] onPreeditEndListeners;
538 
539 	/**
540 	 * The ::preedit-end signal is emitted when a preediting sequence
541 	 * has been completed or canceled.
542 	 */
543 	gulong addOnPreeditEnd(void delegate(IMContext) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
544 	{
545 		auto wrapper = new OnPreeditEndDelegateWrapper(dlg);
546 		wrapper.handlerId = Signals.connectData(
547 			this,
548 			"preedit-end",
549 			cast(GCallback)&callBackPreeditEnd,
550 			cast(void*)wrapper,
551 			cast(GClosureNotify)&callBackPreeditEndDestroy,
552 			connectFlags);
553 		return wrapper.handlerId;
554 	}
555 
556 	extern(C) static void callBackPreeditEnd(GtkIMContext* imcontextStruct, OnPreeditEndDelegateWrapper wrapper)
557 	{
558 		wrapper.dlg(wrapper.outer);
559 	}
560 
561 	extern(C) static void callBackPreeditEndDestroy(OnPreeditEndDelegateWrapper wrapper, GClosure* closure)
562 	{
563 		wrapper.remove(wrapper);
564 	}
565 
566 	protected class OnPreeditStartDelegateWrapper
567 	{
568 		void delegate(IMContext) dlg;
569 		gulong handlerId;
570 
571 		this(void delegate(IMContext) dlg)
572 		{
573 			this.dlg = dlg;
574 			onPreeditStartListeners ~= this;
575 		}
576 
577 		void remove(OnPreeditStartDelegateWrapper source)
578 		{
579 			foreach(index, wrapper; onPreeditStartListeners)
580 			{
581 				if (wrapper.handlerId == source.handlerId)
582 				{
583 					onPreeditStartListeners[index] = null;
584 					onPreeditStartListeners = std.algorithm.remove(onPreeditStartListeners, index);
585 					break;
586 				}
587 			}
588 		}
589 	}
590 	OnPreeditStartDelegateWrapper[] onPreeditStartListeners;
591 
592 	/**
593 	 * The ::preedit-start signal is emitted when a new preediting sequence
594 	 * starts.
595 	 */
596 	gulong addOnPreeditStart(void delegate(IMContext) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
597 	{
598 		auto wrapper = new OnPreeditStartDelegateWrapper(dlg);
599 		wrapper.handlerId = Signals.connectData(
600 			this,
601 			"preedit-start",
602 			cast(GCallback)&callBackPreeditStart,
603 			cast(void*)wrapper,
604 			cast(GClosureNotify)&callBackPreeditStartDestroy,
605 			connectFlags);
606 		return wrapper.handlerId;
607 	}
608 
609 	extern(C) static void callBackPreeditStart(GtkIMContext* imcontextStruct, OnPreeditStartDelegateWrapper wrapper)
610 	{
611 		wrapper.dlg(wrapper.outer);
612 	}
613 
614 	extern(C) static void callBackPreeditStartDestroy(OnPreeditStartDelegateWrapper wrapper, GClosure* closure)
615 	{
616 		wrapper.remove(wrapper);
617 	}
618 
619 	protected class OnRetrieveSurroundingDelegateWrapper
620 	{
621 		bool delegate(IMContext) dlg;
622 		gulong handlerId;
623 
624 		this(bool delegate(IMContext) dlg)
625 		{
626 			this.dlg = dlg;
627 			onRetrieveSurroundingListeners ~= this;
628 		}
629 
630 		void remove(OnRetrieveSurroundingDelegateWrapper source)
631 		{
632 			foreach(index, wrapper; onRetrieveSurroundingListeners)
633 			{
634 				if (wrapper.handlerId == source.handlerId)
635 				{
636 					onRetrieveSurroundingListeners[index] = null;
637 					onRetrieveSurroundingListeners = std.algorithm.remove(onRetrieveSurroundingListeners, index);
638 					break;
639 				}
640 			}
641 		}
642 	}
643 	OnRetrieveSurroundingDelegateWrapper[] onRetrieveSurroundingListeners;
644 
645 	/**
646 	 * The ::retrieve-surrounding signal is emitted when the input method
647 	 * requires the context surrounding the cursor.  The callback should set
648 	 * the input method surrounding context by calling the
649 	 * gtk_im_context_set_surrounding() method.
650 	 *
651 	 * Returns: %TRUE if the signal was handled.
652 	 */
653 	gulong addOnRetrieveSurrounding(bool delegate(IMContext) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
654 	{
655 		auto wrapper = new OnRetrieveSurroundingDelegateWrapper(dlg);
656 		wrapper.handlerId = Signals.connectData(
657 			this,
658 			"retrieve-surrounding",
659 			cast(GCallback)&callBackRetrieveSurrounding,
660 			cast(void*)wrapper,
661 			cast(GClosureNotify)&callBackRetrieveSurroundingDestroy,
662 			connectFlags);
663 		return wrapper.handlerId;
664 	}
665 
666 	extern(C) static int callBackRetrieveSurrounding(GtkIMContext* imcontextStruct, OnRetrieveSurroundingDelegateWrapper wrapper)
667 	{
668 		return wrapper.dlg(wrapper.outer);
669 	}
670 
671 	extern(C) static void callBackRetrieveSurroundingDestroy(OnRetrieveSurroundingDelegateWrapper wrapper, GClosure* closure)
672 	{
673 		wrapper.remove(wrapper);
674 	}
675 }