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