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.Main; 26 27 private import gdk.Device; 28 private import gdk.Event; 29 private import gdk.Threads; 30 private import glib.ErrorG; 31 private import glib.GException; 32 private import glib.OptionGroup; 33 private import glib.Str; 34 private import gobject.ObjectG; 35 private import gtk.Widget; 36 private import gtk.c.functions; 37 public import gtk.c.types; 38 public import gtkc.gtktypes; 39 private import pango.PgLanguage; 40 41 42 /** */ 43 public struct Main 44 { 45 /** 46 * This initiates GtkD to supports multi threaded programs. 47 * read full documantation at http://gtk.org/faq/#AEN482 48 * from the FAQ: 49 * "There is a single global lock that you must acquire with 50 * gdk_threads_enter() before making any GDK calls, 51 * and release with gdk_threads_leave() afterwards throughout your code." 52 * This is to be used on any call to GDK not executed from the main thread. 53 */ 54 public static void initMultiThread(string[] args) 55 { 56 threadsInit(); 57 init(args); 58 } 59 60 /** 61 */ 62 63 /** 64 * Adds a GTK+ grab on @device, so all the events on @device and its 65 * associated pointer or keyboard (if any) are delivered to @widget. 66 * If the @block_others parameter is %TRUE, any other devices will be 67 * unable to interact with @widget during the grab. 68 * 69 * Params: 70 * widget = a #GtkWidget 71 * device = a #GdkDevice to grab on. 72 * blockOthers = %TRUE to prevent other devices to interact with @widget. 73 * 74 * Since: 3.0 75 */ 76 public static void deviceGrabAdd(Widget widget, Device device, bool blockOthers) 77 { 78 gtk_device_grab_add((widget is null) ? null : widget.getWidgetStruct(), (device is null) ? null : device.getDeviceStruct(), blockOthers); 79 } 80 81 /** 82 * Removes a device grab from the given widget. 83 * 84 * You have to pair calls to gtk_device_grab_add() and 85 * gtk_device_grab_remove(). 86 * 87 * Params: 88 * widget = a #GtkWidget 89 * device = a #GdkDevice 90 * 91 * Since: 3.0 92 */ 93 public static void deviceGrabRemove(Widget widget, Device device) 94 { 95 gtk_device_grab_remove((widget is null) ? null : widget.getWidgetStruct(), (device is null) ? null : device.getDeviceStruct()); 96 } 97 98 /** 99 * Prevents gtk_init(), gtk_init_check(), gtk_init_with_args() and 100 * gtk_parse_args() from automatically 101 * calling `setlocale (LC_ALL, "")`. You would 102 * want to use this function if you wanted to set the locale for 103 * your program to something other than the user’s locale, or if 104 * you wanted to set different values for different locale categories. 105 * 106 * Most programs should not need to call this function. 107 */ 108 public static void disableSetlocale() 109 { 110 gtk_disable_setlocale(); 111 } 112 113 /** 114 * Checks if any events are pending. 115 * 116 * This can be used to update the UI and invoke timeouts etc. 117 * while doing some time intensive computation. 118 * 119 * ## Updating the UI during a long computation 120 * 121 * |[<!-- language="C" --> 122 * // computation going on... 123 * 124 * while (gtk_events_pending ()) 125 * gtk_main_iteration (); 126 * 127 * // ...computation continued 128 * ]| 129 * 130 * Returns: %TRUE if any events are pending, %FALSE otherwise 131 */ 132 public static bool eventsPending() 133 { 134 return gtk_events_pending() != 0; 135 } 136 137 /** 138 * Obtains a copy of the event currently being processed by GTK+. 139 * 140 * For example, if you are handling a #GtkButton::clicked signal, 141 * the current event will be the #GdkEventButton that triggered 142 * the ::clicked signal. 143 * 144 * Returns: a copy of the current event, or 145 * %NULL if there is no current event. The returned event must be 146 * freed with gdk_event_free(). 147 */ 148 public static Event getCurrentEvent() 149 { 150 auto p = gtk_get_current_event(); 151 152 if(p is null) 153 { 154 return null; 155 } 156 157 return ObjectG.getDObject!(Event)(cast(GdkEvent*) p, true); 158 } 159 160 /** 161 * If there is a current event and it has a device, return that 162 * device, otherwise return %NULL. 163 * 164 * Returns: a #GdkDevice, or %NULL 165 */ 166 public static Device getCurrentEventDevice() 167 { 168 auto p = gtk_get_current_event_device(); 169 170 if(p is null) 171 { 172 return null; 173 } 174 175 return ObjectG.getDObject!(Device)(cast(GdkDevice*) p); 176 } 177 178 /** 179 * If there is a current event and it has a state field, place 180 * that state field in @state and return %TRUE, otherwise return 181 * %FALSE. 182 * 183 * Params: 184 * state = a location to store the state of the current event 185 * 186 * Returns: %TRUE if there was a current event and it 187 * had a state field 188 */ 189 public static bool getCurrentEventState(out GdkModifierType state) 190 { 191 return gtk_get_current_event_state(&state) != 0; 192 } 193 194 /** 195 * If there is a current event and it has a timestamp, 196 * return that timestamp, otherwise return %GDK_CURRENT_TIME. 197 * 198 * Returns: the timestamp from the current event, 199 * or %GDK_CURRENT_TIME. 200 */ 201 public static uint getCurrentEventTime() 202 { 203 return gtk_get_current_event_time(); 204 } 205 206 /** 207 * Returns the GTK+ debug flags. 208 * 209 * This function is intended for GTK+ modules that want 210 * to adjust their debug output based on GTK+ debug flags. 211 * 212 * Returns: the GTK+ debug flags. 213 */ 214 public static uint getDebugFlags() 215 { 216 return gtk_get_debug_flags(); 217 } 218 219 /** 220 * Returns the #PangoLanguage for the default language currently in 221 * effect. (Note that this can change over the life of an 222 * application.) The default language is derived from the current 223 * locale. It determines, for example, whether GTK+ uses the 224 * right-to-left or left-to-right text direction. 225 * 226 * This function is equivalent to pango_language_get_default(). 227 * See that function for details. 228 * 229 * Returns: the default language as a #PangoLanguage, 230 * must not be freed 231 */ 232 public static PgLanguage getDefaultLanguage() 233 { 234 auto p = gtk_get_default_language(); 235 236 if(p is null) 237 { 238 return null; 239 } 240 241 return ObjectG.getDObject!(PgLanguage)(cast(PangoLanguage*) p); 242 } 243 244 /** 245 * If @event is %NULL or the event was not associated with any widget, 246 * returns %NULL, otherwise returns the widget that received the event 247 * originally. 248 * 249 * Params: 250 * event = a #GdkEvent 251 * 252 * Returns: the widget that originally 253 * received @event, or %NULL 254 */ 255 public static Widget getEventWidget(Event event) 256 { 257 auto p = gtk_get_event_widget((event is null) ? null : event.getEventStruct()); 258 259 if(p is null) 260 { 261 return null; 262 } 263 264 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 265 } 266 267 /** 268 * Get the direction of the current locale. This is the expected 269 * reading direction for text and UI. 270 * 271 * This function depends on the current locale being set with 272 * setlocale() and will default to setting the %GTK_TEXT_DIR_LTR 273 * direction otherwise. %GTK_TEXT_DIR_NONE will never be returned. 274 * 275 * GTK+ sets the default text direction according to the locale 276 * during gtk_init(), and you should normally use 277 * gtk_widget_get_direction() or gtk_widget_get_default_direction() 278 * to obtain the current direcion. 279 * 280 * This function is only needed rare cases when the locale is 281 * changed after GTK+ has already been initialized. In this case, 282 * you can use it to update the default text direction as follows: 283 * 284 * |[<!-- language="C" --> 285 * setlocale (LC_ALL, new_locale); 286 * direction = gtk_get_locale_direction (); 287 * gtk_widget_set_default_direction (direction); 288 * ]| 289 * 290 * Returns: the #GtkTextDirection of the current locale 291 * 292 * Since: 3.12 293 */ 294 public static GtkTextDirection getLocaleDirection() 295 { 296 return gtk_get_locale_direction(); 297 } 298 299 /** 300 * Returns a #GOptionGroup for the commandline arguments recognized 301 * by GTK+ and GDK. 302 * 303 * You should add this group to your #GOptionContext 304 * with g_option_context_add_group(), if you are using 305 * g_option_context_parse() to parse your commandline arguments. 306 * 307 * Params: 308 * openDefaultDisplay = whether to open the default display 309 * when parsing the commandline arguments 310 * 311 * Returns: a #GOptionGroup for the commandline 312 * arguments recognized by GTK+ 313 * 314 * Since: 2.6 315 */ 316 public static OptionGroup getOptionGroup(bool openDefaultDisplay) 317 { 318 auto p = gtk_get_option_group(openDefaultDisplay); 319 320 if(p is null) 321 { 322 return null; 323 } 324 325 return new OptionGroup(cast(GOptionGroup*) p, true); 326 } 327 328 /** 329 * Queries the current grab of the default window group. 330 * 331 * Returns: The widget which currently 332 * has the grab or %NULL if no grab is active 333 */ 334 public static Widget grabGetCurrent() 335 { 336 auto p = gtk_grab_get_current(); 337 338 if(p is null) 339 { 340 return null; 341 } 342 343 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 344 } 345 346 /** 347 * Call this function before using any other GTK+ functions in your GUI 348 * applications. It will initialize everything needed to operate the 349 * toolkit and parses some standard command line options. 350 * 351 * Although you are expected to pass the @argc, @argv parameters from main() to 352 * this function, it is possible to pass %NULL if @argv is not available or 353 * commandline handling is not required. 354 * 355 * @argc and @argv are adjusted accordingly so your own code will 356 * never see those standard arguments. 357 * 358 * Note that there are some alternative ways to initialize GTK+: 359 * if you are calling gtk_parse_args(), gtk_init_check(), 360 * gtk_init_with_args() or g_option_context_parse() with 361 * the option group returned by gtk_get_option_group(), 362 * you don’t have to call gtk_init(). 363 * 364 * And if you are using #GtkApplication, you don't have to call any of the 365 * initialization functions either; the #GtkApplication::startup handler 366 * does it for you. 367 * 368 * This function will terminate your program if it was unable to 369 * initialize the windowing system for some reason. If you want 370 * your program to fall back to a textual interface you want to 371 * call gtk_init_check() instead. 372 * 373 * Since 2.18, GTK+ calls `signal (SIGPIPE, SIG_IGN)` 374 * during initialization, to ignore SIGPIPE signals, since these are 375 * almost never wanted in graphical applications. If you do need to 376 * handle SIGPIPE for some reason, reset the handler after gtk_init(), 377 * but notice that other libraries (e.g. libdbus or gvfs) might do 378 * similar things. 379 * 380 * Params: 381 * argv = Address of the 382 * `argv` parameter of main(), or %NULL. Any options 383 * understood by GTK+ are stripped before return. 384 */ 385 public static void init(ref string[] argv) 386 { 387 int argc = cast(int)argv.length; 388 char** outargv = Str.toStringzArray(argv); 389 390 gtk_init(&argc, &outargv); 391 392 argv = Str.toStringArray(outargv, argc); 393 } 394 395 /** 396 * This function does the same work as gtk_init() with only a single 397 * change: It does not terminate the program if the commandline 398 * arguments couldn’t be parsed or the windowing system can’t be 399 * initialized. Instead it returns %FALSE on failure. 400 * 401 * This way the application can fall back to some other means of 402 * communication with the user - for example a curses or command line 403 * interface. 404 * 405 * Params: 406 * argv = Address of the 407 * `argv` parameter of main(), or %NULL. Any options 408 * understood by GTK+ are stripped before return. 409 * 410 * Returns: %TRUE if the commandline arguments (if any) were valid and 411 * the windowing system has been successfully initialized, %FALSE 412 * otherwise 413 */ 414 public static bool initCheck(ref string[] argv) 415 { 416 int argc = cast(int)argv.length; 417 char** outargv = Str.toStringzArray(argv); 418 419 auto p = gtk_init_check(&argc, &outargv) != 0; 420 421 argv = Str.toStringArray(outargv, argc); 422 423 return p; 424 } 425 426 /** 427 * This function does the same work as gtk_init_check(). 428 * Additionally, it allows you to add your own commandline options, 429 * and it automatically generates nicely formatted 430 * `--help` output. Note that your program will 431 * be terminated after writing out the help output. 432 * 433 * Params: 434 * argv = Address of the 435 * `argv` parameter of main(), or %NULL. Any options 436 * understood by GTK+ are stripped before return. 437 * parameterString = a string which is displayed in 438 * the first line of `--help` output, after 439 * `programname [OPTION...]` 440 * entries = a %NULL-terminated array 441 * of #GOptionEntrys describing the options of your program 442 * translationDomain = a translation domain to use for translating 443 * the `--help` output for the options in @entries 444 * and the @parameter_string with gettext(), or %NULL 445 * 446 * Returns: %TRUE if the commandline arguments (if any) were valid and 447 * if the windowing system has been successfully initialized, 448 * %FALSE otherwise 449 * 450 * Since: 2.6 451 * 452 * Throws: GException on failure. 453 */ 454 public static bool initWithArgs(ref string[] argv, string parameterString, GOptionEntry[] entries, string translationDomain) 455 { 456 int argc = cast(int)argv.length; 457 char** outargv = Str.toStringzArray(argv); 458 GError* err = null; 459 460 auto p = gtk_init_with_args(&argc, &outargv, Str.toStringz(parameterString), entries.ptr, Str.toStringz(translationDomain), &err) != 0; 461 462 if (err !is null) 463 { 464 throw new GException( new ErrorG(err) ); 465 } 466 467 argv = Str.toStringArray(outargv, argc); 468 469 return p; 470 } 471 472 /** 473 * Installs a key snooper function, which will get called on all 474 * key events before delivering them normally. 475 * 476 * Deprecated: Key snooping should not be done. Events should 477 * be handled by widgets. 478 * 479 * Params: 480 * snooper = a #GtkKeySnoopFunc 481 * funcData = data to pass to @snooper 482 * 483 * Returns: a unique id for this key snooper for use with 484 * gtk_key_snooper_remove(). 485 */ 486 public static uint keySnooperInstall(GtkKeySnoopFunc snooper, void* funcData) 487 { 488 return gtk_key_snooper_install(snooper, funcData); 489 } 490 491 /** 492 * Removes the key snooper function with the given id. 493 * 494 * Deprecated: Key snooping should not be done. Events should 495 * be handled by widgets. 496 * 497 * Params: 498 * snooperHandlerId = Identifies the key snooper to remove 499 */ 500 public static void keySnooperRemove(uint snooperHandlerId) 501 { 502 gtk_key_snooper_remove(snooperHandlerId); 503 } 504 505 /** 506 * Runs the main loop until gtk_main_quit() is called. 507 * 508 * You can nest calls to gtk_main(). In that case gtk_main_quit() 509 * will make the innermost invocation of the main loop return. 510 */ 511 public static void run() 512 { 513 gtk_main(); 514 } 515 516 /** 517 * Processes a single GDK event. 518 * 519 * This is public only to allow filtering of events between GDK and GTK+. 520 * You will not usually need to call this function directly. 521 * 522 * While you should not call this function directly, you might want to 523 * know how exactly events are handled. So here is what this function 524 * does with the event: 525 * 526 * 1. Compress enter/leave notify events. If the event passed build an 527 * enter/leave pair together with the next event (peeked from GDK), both 528 * events are thrown away. This is to avoid a backlog of (de-)highlighting 529 * widgets crossed by the pointer. 530 * 531 * 2. Find the widget which got the event. If the widget can’t be determined 532 * the event is thrown away unless it belongs to a INCR transaction. 533 * 534 * 3. Then the event is pushed onto a stack so you can query the currently 535 * handled event with gtk_get_current_event(). 536 * 537 * 4. The event is sent to a widget. If a grab is active all events for widgets 538 * that are not in the contained in the grab widget are sent to the latter 539 * with a few exceptions: 540 * - Deletion and destruction events are still sent to the event widget for 541 * obvious reasons. 542 * - Events which directly relate to the visual representation of the event 543 * widget. 544 * - Leave events are delivered to the event widget if there was an enter 545 * event delivered to it before without the paired leave event. 546 * - Drag events are not redirected because it is unclear what the semantics 547 * of that would be. 548 * Another point of interest might be that all key events are first passed 549 * through the key snooper functions if there are any. Read the description 550 * of gtk_key_snooper_install() if you need this feature. 551 * 552 * 5. After finishing the delivery the event is popped from the event stack. 553 * 554 * Params: 555 * event = An event to process (normally passed by GDK) 556 */ 557 public static void doEvent(Event event) 558 { 559 gtk_main_do_event((event is null) ? null : event.getEventStruct()); 560 } 561 562 /** 563 * Runs a single iteration of the mainloop. 564 * 565 * If no events are waiting to be processed GTK+ will block 566 * until the next event is noticed. If you don’t want to block 567 * look at gtk_main_iteration_do() or check if any events are 568 * pending with gtk_events_pending() first. 569 * 570 * Returns: %TRUE if gtk_main_quit() has been called for the 571 * innermost mainloop 572 */ 573 public static bool iteration() 574 { 575 return gtk_main_iteration() != 0; 576 } 577 578 /** 579 * Runs a single iteration of the mainloop. 580 * If no events are available either return or block depending on 581 * the value of @blocking. 582 * 583 * Params: 584 * blocking = %TRUE if you want GTK+ to block if no events are pending 585 * 586 * Returns: %TRUE if gtk_main_quit() has been called for the 587 * innermost mainloop 588 */ 589 public static bool iterationDo(bool blocking) 590 { 591 return gtk_main_iteration_do(blocking) != 0; 592 } 593 594 /** 595 * Asks for the current nesting level of the main loop. 596 * 597 * Returns: the nesting level of the current invocation 598 * of the main loop 599 */ 600 public static uint level() 601 { 602 return gtk_main_level(); 603 } 604 605 /** 606 * Makes the innermost invocation of the main loop return 607 * when it regains control. 608 */ 609 public static void quit() 610 { 611 gtk_main_quit(); 612 } 613 614 /** 615 * Parses command line arguments, and initializes global 616 * attributes of GTK+, but does not actually open a connection 617 * to a display. (See gdk_display_open(), gdk_get_display_arg_name()) 618 * 619 * Any arguments used by GTK+ or GDK are removed from the array and 620 * @argc and @argv are updated accordingly. 621 * 622 * There is no need to call this function explicitly if you are using 623 * gtk_init(), or gtk_init_check(). 624 * 625 * Note that many aspects of GTK+ require a display connection to 626 * function, so this way of initializing GTK+ is really only useful 627 * for specialized use cases. 628 * 629 * Params: 630 * argv = a pointer to the array of 631 * command line arguments 632 * 633 * Returns: %TRUE if initialization succeeded, otherwise %FALSE 634 */ 635 public static bool parseArgs(ref string[] argv) 636 { 637 int argc = cast(int)argv.length; 638 char** outargv = Str.toStringzArray(argv); 639 640 auto p = gtk_parse_args(&argc, &outargv) != 0; 641 642 argv = Str.toStringArray(outargv, argc); 643 644 return p; 645 } 646 647 /** 648 * Sends an event to a widget, propagating the event to parent widgets 649 * if the event remains unhandled. 650 * 651 * Events received by GTK+ from GDK normally begin in gtk_main_do_event(). 652 * Depending on the type of event, existence of modal dialogs, grabs, etc., 653 * the event may be propagated; if so, this function is used. 654 * 655 * gtk_propagate_event() calls gtk_widget_event() on each widget it 656 * decides to send the event to. So gtk_widget_event() is the lowest-level 657 * function; it simply emits the #GtkWidget::event and possibly an 658 * event-specific signal on a widget. gtk_propagate_event() is a bit 659 * higher-level, and gtk_main_do_event() is the highest level. 660 * 661 * All that said, you most likely don’t want to use any of these 662 * functions; synthesizing events is rarely needed. There are almost 663 * certainly better ways to achieve your goals. For example, use 664 * gdk_window_invalidate_rect() or gtk_widget_queue_draw() instead 665 * of making up expose events. 666 * 667 * Params: 668 * widget = a #GtkWidget 669 * event = an event 670 */ 671 public static void propagateEvent(Widget widget, Event event) 672 { 673 gtk_propagate_event((widget is null) ? null : widget.getWidgetStruct(), (event is null) ? null : event.getEventStruct()); 674 } 675 676 /** 677 * Sets the GTK+ debug flags. 678 */ 679 public static void setDebugFlags(uint flags) 680 { 681 gtk_set_debug_flags(flags); 682 } 683 }