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 glib.MainLoop; 26 27 private import glib.ConstructionException; 28 private import glib.MainContext; 29 private import glib.Source; 30 private import glib.c.functions; 31 public import glib.c.types; 32 private import gtkd.Loader; 33 34 35 /** 36 * The `GMainLoop` struct is an opaque data type 37 * representing the main event loop of a GLib or GTK+ application. 38 */ 39 public class MainLoop 40 { 41 /** the main Gtk struct */ 42 protected GMainLoop* gMainLoop; 43 protected bool ownedRef; 44 45 /** Get the main Gtk struct */ 46 public GMainLoop* getMainLoopStruct(bool transferOwnership = false) 47 { 48 if (transferOwnership) 49 ownedRef = false; 50 return gMainLoop; 51 } 52 53 /** the main Gtk struct as a void* */ 54 protected void* getStruct() 55 { 56 return cast(void*)gMainLoop; 57 } 58 59 /** 60 * Sets our main struct and passes it to the parent class. 61 */ 62 public this (GMainLoop* gMainLoop, bool ownedRef = false) 63 { 64 this.gMainLoop = gMainLoop; 65 this.ownedRef = ownedRef; 66 } 67 68 ~this () 69 { 70 if ( Linker.isLoaded(LIBRARY_GLIB) && ownedRef ) 71 g_main_loop_unref(gMainLoop); 72 } 73 74 75 /** 76 * Creates a new #GMainLoop structure. 77 * 78 * Params: 79 * context = a #GMainContext (if %NULL, the default context will be used). 80 * isRunning = set to %TRUE to indicate that the loop is running. This 81 * is not very important since calling g_main_loop_run() will set this to 82 * %TRUE anyway. 83 * 84 * Returns: a new #GMainLoop. 85 * 86 * Throws: ConstructionException GTK+ fails to create the object. 87 */ 88 public this(MainContext context, bool isRunning) 89 { 90 auto __p = g_main_loop_new((context is null) ? null : context.getMainContextStruct(), isRunning); 91 92 if(__p is null) 93 { 94 throw new ConstructionException("null returned by new"); 95 } 96 97 this(cast(GMainLoop*) __p); 98 } 99 100 /** 101 * Returns the #GMainContext of @loop. 102 * 103 * Returns: the #GMainContext of @loop 104 */ 105 public MainContext getContext() 106 { 107 auto __p = g_main_loop_get_context(gMainLoop); 108 109 if(__p is null) 110 { 111 return null; 112 } 113 114 return new MainContext(cast(GMainContext*) __p); 115 } 116 117 /** 118 * Checks to see if the main loop is currently being run via g_main_loop_run(). 119 * 120 * Returns: %TRUE if the mainloop is currently being run. 121 */ 122 public bool isRunning() 123 { 124 return g_main_loop_is_running(gMainLoop) != 0; 125 } 126 127 /** 128 * Stops a #GMainLoop from running. Any calls to g_main_loop_run() 129 * for the loop will return. 130 * 131 * Note that sources that have already been dispatched when 132 * g_main_loop_quit() is called will still be executed. 133 */ 134 public void quit() 135 { 136 g_main_loop_quit(gMainLoop); 137 } 138 139 alias doref = ref_; 140 /** 141 * Increases the reference count on a #GMainLoop object by one. 142 * 143 * Returns: @loop 144 */ 145 public MainLoop ref_() 146 { 147 auto __p = g_main_loop_ref(gMainLoop); 148 149 if(__p is null) 150 { 151 return null; 152 } 153 154 return new MainLoop(cast(GMainLoop*) __p, true); 155 } 156 157 /** 158 * Runs a main loop until g_main_loop_quit() is called on the loop. 159 * If this is called for the thread of the loop's #GMainContext, 160 * it will process events from the loop, otherwise it will 161 * simply wait. 162 */ 163 public void run() 164 { 165 g_main_loop_run(gMainLoop); 166 } 167 168 /** 169 * Decreases the reference count on a #GMainLoop object by one. If 170 * the result is zero, free the loop and free all associated memory. 171 */ 172 public void unref() 173 { 174 g_main_loop_unref(gMainLoop); 175 } 176 177 /** 178 * Returns the currently firing source for this thread. 179 * 180 * Returns: The currently firing source or %NULL. 181 * 182 * Since: 2.12 183 */ 184 public static Source mainCurrentSource() 185 { 186 auto __p = g_main_current_source(); 187 188 if(__p is null) 189 { 190 return null; 191 } 192 193 return new Source(cast(GSource*) __p); 194 } 195 196 /** 197 * Returns the depth of the stack of calls to 198 * g_main_context_dispatch() on any #GMainContext in the current thread. 199 * That is, when called from the toplevel, it gives 0. When 200 * called from within a callback from g_main_context_iteration() 201 * (or g_main_loop_run(), etc.) it returns 1. When called from within 202 * a callback to a recursive call to g_main_context_iteration(), 203 * it returns 2. And so forth. 204 * 205 * This function is useful in a situation like the following: 206 * Imagine an extremely simple "garbage collected" system. 207 * 208 * |[<!-- language="C" --> 209 * static GList *free_list; 210 * 211 * gpointer 212 * allocate_memory (gsize size) 213 * { 214 * gpointer result = g_malloc (size); 215 * free_list = g_list_prepend (free_list, result); 216 * return result; 217 * } 218 * 219 * void 220 * free_allocated_memory (void) 221 * { 222 * GList *l; 223 * for (l = free_list; l; l = l->next); 224 * g_free (l->data); 225 * g_list_free (free_list); 226 * free_list = NULL; 227 * } 228 * 229 * [...] 230 * 231 * while (TRUE); 232 * { 233 * g_main_context_iteration (NULL, TRUE); 234 * free_allocated_memory(); 235 * } 236 * ]| 237 * 238 * This works from an application, however, if you want to do the same 239 * thing from a library, it gets more difficult, since you no longer 240 * control the main loop. You might think you can simply use an idle 241 * function to make the call to free_allocated_memory(), but that 242 * doesn't work, since the idle function could be called from a 243 * recursive callback. This can be fixed by using g_main_depth() 244 * 245 * |[<!-- language="C" --> 246 * gpointer 247 * allocate_memory (gsize size) 248 * { 249 * FreeListBlock *block = g_new (FreeListBlock, 1); 250 * block->mem = g_malloc (size); 251 * block->depth = g_main_depth (); 252 * free_list = g_list_prepend (free_list, block); 253 * return block->mem; 254 * } 255 * 256 * void 257 * free_allocated_memory (void) 258 * { 259 * GList *l; 260 * 261 * int depth = g_main_depth (); 262 * for (l = free_list; l; ); 263 * { 264 * GList *next = l->next; 265 * FreeListBlock *block = l->data; 266 * if (block->depth > depth) 267 * { 268 * g_free (block->mem); 269 * g_free (block); 270 * free_list = g_list_delete_link (free_list, l); 271 * } 272 * 273 * l = next; 274 * } 275 * } 276 * ]| 277 * 278 * There is a temptation to use g_main_depth() to solve 279 * problems with reentrancy. For instance, while waiting for data 280 * to be received from the network in response to a menu item, 281 * the menu item might be selected again. It might seem that 282 * one could make the menu item's callback return immediately 283 * and do nothing if g_main_depth() returns a value greater than 1. 284 * However, this should be avoided since the user then sees selecting 285 * the menu item do nothing. Furthermore, you'll find yourself adding 286 * these checks all over your code, since there are doubtless many, 287 * many things that the user could do. Instead, you can use the 288 * following techniques: 289 * 290 * 1. Use gtk_widget_set_sensitive() or modal dialogs to prevent 291 * the user from interacting with elements while the main 292 * loop is recursing. 293 * 294 * 2. Avoid main loop recursion in situations where you can't handle 295 * arbitrary callbacks. Instead, structure your code so that you 296 * simply return to the main loop and then get called again when 297 * there is more work to do. 298 * 299 * Returns: The main loop recursion level in the current thread 300 */ 301 public static int mainDepth() 302 { 303 return g_main_depth(); 304 } 305 306 /** 307 * Polls @fds, as with the poll() system call, but portably. (On 308 * systems that don't have poll(), it is emulated using select().) 309 * This is used internally by #GMainContext, but it can be called 310 * directly if you need to block until a file descriptor is ready, but 311 * don't want to run the full main loop. 312 * 313 * Each element of @fds is a #GPollFD describing a single file 314 * descriptor to poll. The @fd field indicates the file descriptor, 315 * and the @events field indicates the events to poll for. On return, 316 * the @revents fields will be filled with the events that actually 317 * occurred. 318 * 319 * On POSIX systems, the file descriptors in @fds can be any sort of 320 * file descriptor, but the situation is much more complicated on 321 * Windows. If you need to use g_poll() in code that has to run on 322 * Windows, the easiest solution is to construct all of your 323 * #GPollFDs with g_io_channel_win32_make_pollfd(). 324 * 325 * Params: 326 * fds = file descriptors to poll 327 * nfds = the number of file descriptors in @fds 328 * timeout = amount of time to wait, in milliseconds, or -1 to wait forever 329 * 330 * Returns: the number of entries in @fds whose @revents fields 331 * were filled in, or 0 if the operation timed out, or -1 on error or 332 * if the call was interrupted. 333 * 334 * Since: 2.20 335 */ 336 public static int poll(GPollFD* fds, uint nfds, int timeout) 337 { 338 return g_poll(fds, nfds, timeout); 339 } 340 }