Signal mechanism in GTK
[Copyright, infringement must be investment Tan.zhenhua]
First, in order to facilitate the user, define the following macro
/ * - Easy macro definition * /
#define g_signal_connect (Instance, Detailed_Signal, C_Handler, Data) /
g_signal_connect_data (instance), (Detailed_Signal), (C_Handler), (DATA), NULL, (GConnectFlags) 0)
#define g_signal_connect_after (Instance, Detailed_Signal, C_Handler, Data) /
g_signal_connect_data (instance), (Detailed_Signal), (C_Handler), (DATA), NULL, G_CONNECT_AFTER
#define g_signal_connect_swapped (Instance, Detailed_Signal, C_Handler, Data) /
G_Signal_Connect_Data (Instance), (Detailed_Signal), (C_Handler), (DATA), NULL, G_CONNECT_SWAPPED
#define g_signal_handlers_disconnect_by_func (Instance, Func, Data) /
g_signal_handlers_disconnect_match ((instance), /
(GSIGNALMATCHTYPE) (g_signal_match_func | g_signal_match_data), /
0, 0, NULL, (FUNC), (DATA))
#define g_signal_handlers_block_by_func (Instance, Func, Data) /
g_signal_handlers_block_matched ((instance), /
(GSIGNALMATCHTYPE) (g_signal_match_func | g_signal_match_data), /
0, 0, NULL, (FUNC), (DATA))
#define g_signal_handlers_unblock_by_func (Instance, Func, Data) /
g_signal_handlers_unblock_matched ((instance), /
(GSIGNALMATCHTYPE) (g_signal_match_func | g_signal_match_data), /
0, 0, NULL, (FUNC), (DATA))
Second, / * Signal connection implementation function * /
gulong
g_signal_connect_data (GPOINTER Instance, // Send Signal Object)
Const gchar * detailed_signal, // signal name
GCallback c_handler, // callback function
Gpointer Data, / / Parameters pass to the callback function
GClosureNotify Destroy_Data, // Destroy data function
GConnectFlags Connect_Flags) // Signal connection options
{
(1) / **************** For security reasons, do the following check ***************** /
/ / Check if the object of the transmitted signal exists
g_return_val_if_fail (g_type_check_instance (instance), 0);
/ / Check if the transmitted signal exists
g_return_val_if_fail (Detailed_Signal! = NULL, 0);
/ / Check if the callback function exists
g_return_val_if_fail (c_handler! = null, 0);
(2) / / obtain the signal ID according to the signal name
Signal_id = Signal_Parse_name (Detailed_Signal, ITYPE, & DETAIL, TRUE);
(3) / / Obtain signal node according to signal ID
SignalNode * node = lookup_signal_node (signal_id);
(4) / / determine the validity of the signal according to the signal node
IF (Detail &&! (Node-> Flags & g_signal_detailed))
g_warning ("% s: Signal`% S 'Does Not Support Details ", g_strloc, detailed_signal;
Else if (! g_type_is_a (itype, node-> iodes))
g_warning ("% s: Signal`% S 'IS Invalid for instance `p'", g_strloc, detailed_signal, instance);
Else
{
(5) // Generate a signal processor
Handler * handler = handler_new (after);
// Signal processor serial number
Handler_seq_no = handler-> sequential_number;
Handler-> detail = detail;
// signal processing function
Handler-> closure = g_closure_ref ((swapped? g_cclosure_new_swap: g_cclosure_new) (c_handler, data, destroy_data);
g_closure_sink (Handler-> Closure);
(6) // According to the signal ID, the signal is issued, the signal processor is inserted into the signal processor list.
Handler_Insert (Signal_ID, Instance, Handler);
}
Third, the trigger of the signal (execution of the signal processor)
GTK_MAIN () enters the event loop to generate a gmainloop object,
Manage GmainContext objects by gmainloop, and GmainContext is managed all event sources! When the corresponding event occurs, look up the signal processor list and then execute.