1. ----------------------------------------------------------------------- 
  2. --               GtkAda - Ada95 binding for Gtk+/Gnome               -- 
  3. --                                                                   -- 
  4. --                Copyright (C) 2006-2013, AdaCore                   -- 
  5. --                                                                   -- 
  6. -- This library is free software; you can redistribute it and/or     -- 
  7. -- modify it under the terms of the GNU General Public               -- 
  8. -- License as published by the Free Software Foundation; either      -- 
  9. -- version 2 of the License, or (at your option) any later version.  -- 
  10. --                                                                   -- 
  11. -- This library is distributed in the hope that it will be useful,   -- 
  12. -- but WITHOUT ANY WARRANTY; without even the implied warranty of    -- 
  13. -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU -- 
  14. -- General Public License for more details.                          -- 
  15. --                                                                   -- 
  16. -- You should have received a copy of the GNU General Public         -- 
  17. -- License along with this library; if not, write to the             -- 
  18. -- Free Software Foundation, Inc., 59 Temple Place - Suite 330,      -- 
  19. -- Boston, MA 02111-1307, USA.                                       -- 
  20. --                                                                   -- 
  21. -- As a special exception, if other files instantiate generics from  -- 
  22. -- this unit, or you link this unit with other files to produce an   -- 
  23. -- executable, this  unit  does not  by itself cause  the resulting  -- 
  24. -- executable to be covered by the GNU General Public License. This  -- 
  25. -- exception does not however invalidate any other reasons why the   -- 
  26. -- executable file  might be covered by the  GNU Public License.     -- 
  27. ----------------------------------------------------------------------- 
  28.  
  29. --  <description> 
  30. --  This package contains low-level subprograms that are used to interact or 
  31. --  configure the main loop. 
  32. --  This loop is responsible for processing events, monitoring input sources 
  33. --  like pipes, sockets,..., and calling callbacks at given time intervals. 
  34. --  New event sources can be created. 
  35. -- 
  36. --  To allow multiple independent sets of sources to be handled in different 
  37. --  threads, each source is associated with a main context. A main context can 
  38. --  only be running in a single thread, but sources can be added to it and 
  39. --  removed from it from other threads. 
  40. -- 
  41. --  Each event source is assigned a priority. The default priority, 
  42. --  G_PRIORITY_DEFAULT, is 0. Values less than 0 denote higher priorities. 
  43. --  Values greater than 0 denote lower priorities. Events from high priority 
  44. --  sources are always processed before events from lower priority sources. 
  45. -- 
  46. --  Idle functions can also be added, and assigned a priority. These will be 
  47. --  run whenever no events with a higher priority are ready to be processed. 
  48. -- 
  49. --  The GMainLoop data type represents a main event loop. A GMainLoop is 
  50. --  created with g_main_loop_new(). After adding the initial event sources, 
  51. --  g_main_loop_run() is called. This continuously checks for new events from 
  52. --  each of the event sources and dispatches them. Finally, the processing of 
  53. --  an event from one of the sources leads to a call to g_main_loop_quit() to 
  54. --  exit the main loop, and g_main_loop_run() returns. 
  55.  
  56. --  It is possible to create new instances of GMainLoop recursively. This is 
  57. --  often used in GTK+ applications when showing modal dialog boxes. Note that 
  58. --  event sources are associated with a particular GMainContext, and will be 
  59. --  checked and dispatched for all main loops associated with that 
  60. --  GMainContext. 
  61. -- 
  62. --  Creating new sources types 
  63. --  ========================== 
  64. -- 
  65. --  One of the unusual features of the GTK+ main loop functionality is that new 
  66. --  types of event source can be created and used in addition to the builtin 
  67. --  type of event source. A new event source type is used for handling GDK 
  68. --  events. 
  69. -- 
  70. --  New source types basically interact with with the main context in two ways. 
  71. --  Their prepare function in GSourceFuncs can set a timeout to determine the 
  72. --  maximum amount of time that the main loop will sleep before checking the 
  73. --  source again. In addition, or as well, the source can add file descriptors 
  74. --  to the set that the main context checks using g_source_add_poll(). 
  75. -- 
  76. --  Ada 
  77. --  === 
  78. -- 
  79. --  Some of these features duplicate Ada builtin tasking support, but the 
  80. --  latter might be more complex to use in the context of a graphical 
  81. --  application, since most of the time the windowing system doesn't support 
  82. --  multi-threaded applications. 
  83. --  </description> 
  84. --  <c_version>glib 2.10.2</c_version> 
  85. --  <group>Glib, the general-purpose library</group> 
  86. --  <testgtk>create_sources.adb</testgtk> 
  87.  
  88. package Glib.Main is 
  89.  
  90.    -------------------- 
  91.    -- G_Main_Context -- 
  92.    -------------------- 
  93.  
  94.    type G_Main_Context is new Glib.C_Proxy; 
  95.    --  This type represents a set of sources to handled in the main loop. 
  96.    --  Basically, this represents a main loop. There might be several main 
  97.    --  loops running at the same time, although gtk+ itself has only one, 
  98.    --  identified as the default main context. 
  99.  
  100.    function Main_Context_New return G_Main_Context; 
  101.    --  Create a new context 
  102.  
  103.    procedure Main_Context_Ref   (Context : G_Main_Context); 
  104.    procedure Main_Context_Unref (Context : G_Main_Context); 
  105.    --  Increase or decreate the reference counting for Context. When this 
  106.    --  reaches 0, the memory is freed. 
  107.  
  108.    function Main_Context_Default return G_Main_Context; 
  109.    --  Returns the default main context. This is the main context used for main 
  110.    --  loop functions when a main loop is not explicitly specified. 
  111.  
  112.    procedure Wakeup (Context : G_Main_Context); 
  113.    --  If context is currently waiting in a poll(), interrupt the poll(), and 
  114.    --  continue the iteration process. 
  115.  
  116.    function Acquire (Context : G_Main_Context) return Boolean; 
  117.    --  Tries to become the owner of the specified context. If some other thread 
  118.    --  is the owner of the context, returns FALSE immediately. Ownership is 
  119.    --  properly recursive: the owner can require ownership again and will 
  120.    --  release ownership when Release() is called as many times as Acquire(). 
  121.    --  You must be the owner of a context before you can call Prepare(), 
  122.    --  Query(), Check(), Dispatch(). 
  123.  
  124.    procedure Release (Context : G_Main_Context); 
  125.    --  Releases ownership of a context previously acquired by this thread with 
  126.    --  Acquire(). If the context was acquired multiple times, the only release 
  127.    --  ownership when Release() is called as many times as it was acquired. 
  128.  
  129.    function Is_Owner (Context : G_Main_Context) return Boolean; 
  130.    --  Determines whether this thread holds the (recursive) ownership of this 
  131.    --  context. This is useful to know before waiting on another thread 
  132.    --  that may be blocking to get ownership of context. 
  133.  
  134.    procedure Dispatch (Context : G_Main_Context); 
  135.    --  Dispatches all pending sources. 
  136.  
  137.    --------------- 
  138.    -- Main loop -- 
  139.    --------------- 
  140.  
  141.    function Depth return Integer; 
  142.    --  The main loop recursion level in the current thread. It returns 0 when 
  143.    --  called from the toplevel. 
  144.  
  145.    -------------- 
  146.    -- G_Source -- 
  147.    -------------- 
  148.  
  149.    type G_Source is new Glib.C_Proxy; 
  150.    --  This type represents an event source that can be monitored by the main 
  151.    --  loop. There are various internal types of such sources, that can be 
  152.    --  configured by setting appropriate callbacks (this is not yet doable in 
  153.    --  GtkAda). See Idle_Source_New and Timeout_Source_New. 
  154.  
  155.    type G_Source_Id is new Guint; 
  156.    --  The ID of a source within the context to which it is attached. 
  157.  
  158.    No_Source_Id : constant G_Source_Id; 
  159.  
  160.    type G_Source_Func is access function return Boolean; 
  161.  
  162.    type Source_Prepare_Func is access 
  163.      function (Source : G_Source; Timeout : access Gint) return Gboolean; 
  164.    pragma Convention (C, Source_Prepare_Func); 
  165.    --  Called before all the file descriptors are polled. If the source can 
  166.    --  determine that it is ready here (without waiting for the results of the 
  167.    --  poll() call) it should return TRUE. It can also return a timeout value 
  168.    --  which should be the maximum timeout (in milliseconds) which should be 
  169.    --  passed to the poll() call. The actual timeout used will be -1 if all 
  170.    --  sources returned -1, or it will be the minimum of all the timeout_ 
  171.    --  values returned which were >= 0. 
  172.  
  173.    type Source_Check_Func is access 
  174.      function (Source : G_Source) return Gboolean; 
  175.    pragma Convention (C, Source_Check_Func); 
  176.    --  Called after all the file descriptors are polled. The source should 
  177.    --  return TRUE if it is ready to be dispatched. Note that some time may 
  178.    --  have passed since the previous prepare function was called, so the 
  179.    --  source should be checked again here. 
  180.  
  181.    type G_Source_Func_User_Data is access 
  182.      function (User_Data : System.Address) return Gboolean; 
  183.    pragma Convention (C, G_Source_Func_User_Data); 
  184.    --  A callback for a G_Source. If it returns False, the source will be 
  185.    --  removed and no longer executed. User_Data is the data passed to 
  186.    --  Set_Callback. 
  187.  
  188.    type Source_Dispatch_Func is access 
  189.      function (Source   : G_Source; 
  190.                Callback : G_Source_Func_User_Data; 
  191.                Data     : System.Address) return Gboolean; 
  192.    pragma Convention (C, Source_Dispatch_Func); 
  193.    --  Called to dispatch the event source, after it has returned TRUE in 
  194.    --  either its prepare or its check function. The dispatch function is 
  195.    --  passed in a callback function and data. The callback function may be 
  196.    --  NULL if the source was never connected to a callback using 
  197.    --  Set_Callback(). 
  198.    --  In C, the exact profile of Callback depends on the type of Source. This 
  199.    --  is not possible in Ada, which expects a precise profile. 
  200.  
  201.    function Default_Dispatch 
  202.      (Source : G_Source; Cb : G_Source_Func_User_Data; Data : System.Address) 
  203.       return Gboolean; 
  204.    pragma Convention (C, Default_Dispatch); 
  205.    --  Default implementation for the dispatch callback for sources. This 
  206.    --  simply calls Cb and pass it Data. 
  207.  
  208.    type Source_Finalize_Func is access procedure (Source : G_Source); 
  209.    pragma Convention (C, Source_Finalize_Func); 
  210.    --  Called when the source is finalized. 
  211.  
  212.    type G_Source_Type is private; 
  213.    Null_Source_Type : constant G_Source_Type; 
  214.    function G_Source_Type_New 
  215.      (Prepare  : Source_Prepare_Func; 
  216.       Check    : Source_Check_Func; 
  217.       Dispatch : Source_Dispatch_Func := Default_Dispatch'Access; 
  218.       Finalize : Source_Finalize_Func := null) return G_Source_Type; 
  219.    --  Create a new type of sources. 
  220.    --  This function is specific to GtkAda. The returned value is never 
  221.    --  freed. Most of the time, you do not need to create a new source type, 
  222.    --  or even call Source_New. Most things can be implemented through the 
  223.    --  careful use of Idle and Timeout callbacks. However, creating a new 
  224.    --  source type allows for cleaner code, by sharing the common part of the 
  225.    --  handling. 
  226.    -- 
  227.    --  For idle sources, the prepare and check functions always return TRUE to 
  228.    --  indicate that the source is always ready to be processed. The prepare 
  229.    --  function also returns a timeout value of 0 to ensure that the poll() 
  230.    --  call doesn't block (since that would be time wasted which could have 
  231.    --  been spent running the idle function). 
  232.    -- 
  233.    --  For timeout sources, the prepare and check functions both return TRUE if 
  234.    --  the timeout interval has expired. The prepare function also returns a 
  235.    --  timeout value to ensure that the poll() call doesn't block too long and 
  236.    --  miss the next timeout. 
  237.    -- 
  238.    --  For file descriptor sources, the prepare function typically returns 
  239.    --  FALSE, since it must wait until poll() has been called before it knows 
  240.    --  whether any events need to be processed. It sets the returned timeout to 
  241.    --  -1 to indicate that it doesn't mind how long the poll() call blocks. In 
  242.    --  the check function, it tests the results of the poll() call to see if 
  243.    --  the required condition has been met, and returns TRUE if so. 
  244.  
  245.    function Source_New 
  246.      (Source_Type : G_Source_Type; User_Data : System.Address) return G_Source; 
  247.    --  Creates a new GSource structure. 
  248.    -- 
  249.    --  The source will not initially be associated with any GMainContext and 
  250.    --  must be added to one with Attach() before it will be executed. 
  251.  
  252.    function Get_User_Data (Source : G_Source) return System.Address; 
  253.    --  Return the user data passed to Source_New. This only applies to sources 
  254.    --  created through that function, and returns undefined results (or even 
  255.    --  segfaults) otherwise 
  256.  
  257.    procedure Source_Ref   (Source : G_Source); 
  258.    procedure Source_Unref (Source : G_Source); 
  259.    --  Increase or decrease the reference counting for Source. When this 
  260.    --  reaches 0, the Source is destroyed 
  261.  
  262.    procedure Source_Destroy (Source : G_Source); 
  263.    --  Removes the source from its context, and mark it as destroyed (the 
  264.    --  memory is not reclaimed while the reference counting doesn't reach 0). 
  265.    --  Source cannot be added to another context. 
  266.  
  267.    function Attach 
  268.      (Source  : G_Source; 
  269.       Context : G_Main_Context := null) return G_Source_Id; 
  270.    --  Add Source to Context. The Source will be executed within that context. 
  271.    --  If context is null, the source is added to the default context. 
  272.    --  Returns the Id of the source within Context. 
  273.  
  274.    function Remove (Id : G_Source_Id) return Boolean; 
  275.    procedure Remove (Id : G_Source_Id); 
  276.    --  Removes the source with the given id from the default main context. 
  277.    --  The id of. Return True if the source was found and removed 
  278.  
  279.    type G_Priority is new Gint; 
  280.    Priority_High         : constant G_Priority := -100; 
  281.    Priority_Default      : constant G_Priority := 0; 
  282.    Priority_High_Idle    : constant G_Priority := 100; 
  283.    Priority_Default_Idle : constant G_Priority := 200; 
  284.    Priority_Low          : constant G_Priority := 300; 
  285.    --  Priority_High and Priority_Low are not used within glib or gtk+. The 
  286.    --  priority for all graphical events is Priority_Default. gtk+ uses 
  287.    --  Priority_High_Idle+10 for resizing operations, and 
  288.    --  Priority_High_Idle+20 for redrawing operations, to ensure that resizing 
  289.    --  occurs before redrawing and avoid redrawing twice. 
  290.  
  291.    procedure Set_Priority (Source : G_Source; Priority : G_Priority); 
  292.    function  Get_Priority (Source : G_Source) return G_Priority; 
  293.    --  Sets the priority of a source. While the main loop is being run, a 
  294.    --  source will be dispatched if it is ready to be dispatched and no sources 
  295.    --  at a higher (numerically smaller) priority are ready to be dispatched. 
  296.  
  297.    procedure Set_Can_Recurse (Source : G_Source; Can_Recurse : Boolean); 
  298.    function  Get_Can_Recurse (Source : G_Source) return Boolean; 
  299.    --  Sets whether a source can be called recursively. If can_recurse is TRUE, 
  300.    --  then while the source is being dispatched then this source will be 
  301.    --  processed normally. Otherwise, all processing of this source is blocked 
  302.    --  until the dispatch function returns. 
  303.  
  304.    function Get_Id (Source : G_Source) return G_Source_Id; 
  305.    --  Returns the numeric ID for a particular source. The ID of a source is 
  306.    --  positive integer which is unique within a particular main loop context. 
  307.    --  The reverse mapping from ID to source is done by Find_Source_By_Id 
  308.  
  309.    function Find_Source_By_Id 
  310.      (Id : G_Source_Id; Context : G_Main_Context := null) return G_Source; 
  311.    --  Find a source given a context and its Id. 
  312.  
  313.    function Get_Context (Source : G_Source) return G_Main_Context; 
  314.    --  Gets the context with which the source is associated. Calling this 
  315.    --  function on a destroyed source is an error. The returned value is Null 
  316.    --  for sources that haven't been attached yet 
  317.  
  318.    ---------------------- 
  319.    -- Idle and timeout -- 
  320.    ---------------------- 
  321.  
  322.    function Idle_Source_New return G_Source; 
  323.    --  Return a newly allocated idle G_Source. Such a source is polled 
  324.    --  whenever the main loop is not processing events with a higher priority. 
  325.    --  This source must be attached to a main context before it will be 
  326.    --  executed. 
  327.  
  328.    function Timeout_Source_New (Interval : Guint) return G_Source; 
  329.    --  Return a newly allocated idle G_Source. Such a source is called at 
  330.    --  regular intervals. Internval is in milliseconds. 
  331.  
  332.    function Idle_Add (Func : G_Source_Func) return G_Source_Id; 
  333.    --  Adds a function to be called whenever there are no higher priority 
  334.    --  events pending in the default main loop. This function is given the 
  335.    --  priority Priority_Default_Idle. If the function returns False, it is 
  336.    --  automatically removed from the list of event sources and will not be 
  337.    --  called again. 
  338.    --  This function returns the Id of the event source. See Find_Source_By_Id. 
  339.    --  This is implemented by using Idle_Source_New internally. 
  340.  
  341.    function Timeout_Add 
  342.      (Interval : Guint; 
  343.       Func     : G_Source_Func) return G_Source_Id; 
  344.    --  Create a new function to be called periodically until it returns False. 
  345.    -- 
  346.    --  Note that timeout functions may be delayed, due to the processing of 
  347.    --  other event sources. Thus they should not be relied on for precise 
  348.    --  timing. After each call to the timeout function, the time of the next 
  349.    --  timeout is recalculated based on the current time and the given interval 
  350.    --  (it does not try to 'catch up' time lost in delays). 
  351.  
  352.    generic 
  353.       type Data_Type (<>) is private; 
  354.    package Generic_Sources is 
  355.       type G_Source_Func is access 
  356.         function (Data : Data_Type) return Boolean; 
  357.       --  If the function returns FALSE it is automatically 
  358.       --  removed from the list of event sources and will not be called again. 
  359.  
  360.       type Destroy_Notify is access  procedure (Data : in out Data_Type); 
  361.       --  Notify is called just prior to the destruction of Data. It is also 
  362.       --  called if the idle or timeout is destroyed through a call to 
  363.       --  Remove (Id); 
  364.  
  365.       function Idle_Add 
  366.         (Func     : G_Source_Func; 
  367.          Data     : Data_Type; 
  368.          Priority : G_Priority := Priority_Default_Idle; 
  369.          Notify   : Destroy_Notify := null) return G_Source_Id; 
  370.       --  Adds a function to be called whenever there are no higher priority 
  371.       --  events pending. 
  372.  
  373.       function Timeout_Add 
  374.         (Interval : Guint; 
  375.          Func     : G_Source_Func; 
  376.          Data     : Data_Type; 
  377.          Priority : G_Priority := Priority_Default; 
  378.          Notify   : Destroy_Notify := null) return G_Source_Id; 
  379.       --  Adds a function to be called at regular intervals (in milliseconds). 
  380.  
  381.       procedure Set_Callback 
  382.         (Source   : G_Source; 
  383.          Func     : G_Source_Func; 
  384.          Data     : Data_Type; 
  385.          Notify   : Destroy_Notify := null); 
  386.       --  Sets the callback function for a source. The callback for a source is 
  387.       --  called from the source's dispatch function. 
  388.       -- 
  389.       --  The exact type of func depends on the type of source; ie. you should 
  390.       --  not count on func being called with data as its first parameter. 
  391.       -- 
  392.       --  Typically, you won't use this function. Instead use functions 
  393.       --  specific to the type of source you are using. 
  394.  
  395.    private 
  396.       procedure Free_Data (D : System.Address); 
  397.       pragma Convention (C, Free_Data); 
  398.  
  399.       function General_Cb (D : System.Address) return Gint; 
  400.       pragma Convention (C, General_Cb); 
  401.    end Generic_Sources; 
  402.  
  403. private 
  404.    No_Source_Id : constant G_Source_Id := 0; 
  405.  
  406.    type G_Source_Type is new System.Address; 
  407.    Null_Source_Type : constant G_Source_Type := 
  408.      G_Source_Type (System.Null_Address); 
  409.  
  410.    pragma Import (C, Main_Context_New,     "g_main_context_new"); 
  411.    pragma Import (C, Main_Context_Ref,     "g_main_context_ref"); 
  412.    pragma Import (C, Main_Context_Unref,   "g_main_context_unref"); 
  413.    pragma Import (C, Main_Context_Default, "g_main_context_default"); 
  414.    pragma Import (C, Wakeup,               "g_main_context_wakeup"); 
  415.    pragma Import (C, Release,              "g_main_context_release"); 
  416.    pragma Import (C, Dispatch,             "g_main_context_dispatch"); 
  417.    pragma Import (C, Source_Ref,           "g_source_ref"); 
  418.    pragma Import (C, Source_Unref,         "g_source_unref"); 
  419.    pragma Import (C, Attach,               "g_source_attach"); 
  420.    pragma Import (C, Source_Destroy,       "g_source_destroy"); 
  421.    pragma Import (C, Set_Priority,         "g_source_set_priority"); 
  422.    pragma Import (C, Get_Priority,         "g_source_get_priority"); 
  423.    pragma Import (C, Get_Id,               "g_source_get_id"); 
  424.    pragma Import (C, Get_Context,          "g_source_get_context"); 
  425.    pragma Import (C, Idle_Source_New,      "g_idle_source_new"); 
  426.    pragma Import (C, Timeout_Source_New,   "g_timeout_source_new"); 
  427.    pragma Import (C, Depth,                "g_main_depth"); 
  428.    pragma Import (C, G_Source_Type_New,    "ada_allocate_g_source_funcs"); 
  429.    pragma Import (C, Source_New,           "ada_g_source_new"); 
  430.    pragma Import (C, Get_User_Data,        "ada_g_source_get_user_data"); 
  431.  
  432.    --  No binding: g_main_context_find_source_by_user_data 
  433.    --  No binding: g_main_context_find_source_by_funcs_user_data 
  434.    --  No binding: g_idle_remove_by_data 
  435.    --  No binding: g_source_remove_by_funcs_user_data 
  436.    --  No binding: g_source_remove_by_user_data 
  437.    --  No binding: g_source_get_current_time 
  438.    --  No binding: g_source_connect_closure 
  439.    --  No binding: g_source_set_callback_indirect 
  440.    --  No binding: g_get_current_time 
  441.  
  442.    --  Bounds through ada_g_source_new 
  443.    --  No binding: g_source_new 
  444.  
  445.    --  The following functions haven't been examined closely. Most of them 
  446.    --  deal with very low-level details, for which Ada generally has better 
  447.    --  equivalents anyway. 
  448.  
  449.    --  No binding: g_child_watch_add 
  450.    --  No binding: g_child_watch_add_full 
  451.    --  No binding: g_child_watch_source_new 
  452.    --  No binding: g_main_context_add_poll 
  453.    --  No binding: g_main_context_check 
  454.    --  No binding: g_main_context_get_poll_func 
  455.    --  No binding: g_main_context_iteration 
  456.    --  No binding: g_main_context_pending 
  457.    --  No binding: g_main_context_prepare 
  458.    --  No binding: g_main_context_query 
  459.    --  No binding: g_main_context_remove_poll 
  460.    --  No binding: g_main_context_set_poll_func 
  461.    --  No binding: g_main_context_wait 
  462.    --  No binding: g_main_loop_get_context 
  463.    --  No binding: g_main_loop_is_running 
  464.    --  No binding: g_main_loop_new 
  465.    --  No binding: g_main_loop_quit 
  466.    --  No binding: g_main_loop_ref 
  467.    --  No binding: g_main_loop_run 
  468.    --  No binding: g_main_loop_unref 
  469.    --  No binding: g_source_add_poll 
  470.    --  No binding: g_source_remove_poll 
  471.  
  472. end Glib.Main;