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