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