gtk中Gource注册过程和将xevent加入本地队列后处理

来源:互联网 发布:小米手机抹除数据 编辑:程序博客网 时间:2024/05/14 10:33

1、注册eventhandler

gtk_init (int *argc, char ***argv)

gtk_init_check 

gtk_parse_args

gtk_get_option_group 

g_option_group_set_parse_hooks(group,pre_parse_hook,post_parse_hook)

pre_parse_hook

do_pre_parse_initialization

gdk_event_handler_set((GdkEventFunc)gtk_main_do_event,NULL,NULL);


  1.  **/ 

  2. void 

  3. gdk_event_handler_set (GdkEventFunc   func,

  4.                        gpointer       data,

  5.                        GDestroyNotify notify)

  6. {

  7.   if (_gdk_event_notify)

  8.     (*_gdk_event_notify) (_gdk_event_data);



  9.   _gdk_event_func = func;

  10.   _gdk_event_data = data;

  11.   _gdk_event_notify = notify;

  12. }



2、注册gdk_event对应的GSource

gdk_init_check() and post_parse_hook(),and gtk_init_check(),

gdk_display_open_default_libgtk_only

gdk_display_open

gdk_events_init (display); 

g_source_attach(source, NULL);

  1. _gdk_events_init (GdkDisplay *display)

  2. {

  3.   GSource *source;

  4.   GdkDisplaySource *display_source;

  5.   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);

  6.  

  7.   int connection_number = ConnectionNumber (display_x11->xdisplay);

  8.   GDK_NOTE (MISC, g_message ("connection number: %d", connection_number));

  9.                

  10.   

  11.   source = display_x11->event_source = gdk_display_source_new (display);

  12.   display_source = (GdkDisplaySource*) source;

  13.   g_source_set_priority (source, GDK_PRIORITY_EVENTS);

  14.   

  15.   display_source->event_poll_fd.fd = connection_number;

  16.   display_source->event_poll_fd.events = G_IO_IN;

  17.   

  18.   g_source_add_poll (source, &display_source->event_poll_fd);

  19.   g_source_set_can_recurse (source, TRUE); 

  20.   g_source_attach (source, NULL);

  21.           

  22.   display_sources = g_list_prepend (display_sources,display_source);

  23.         

  24.   gdk_display_add_client_message_filter (display,

  25.                                          gdk_atom_intern_static_string ("WM_PROTOCOLS"),

  26.                                          gdk_wm_protocols_filter,

  27.                                          NULL);


3. dispatch函数


注册了gdk_event需要的GSource后,这个Source的dispatch函数会:
  1. _gdk_events_queue(display): 将XEvent transplate为GdkEvent, 同时加入本进程的display队列中
  2. 取得这个队列中的第一个event(if any)
  3. 调用事先注册好的gdk_event_func, 也就是函数gtk_main_do_event()
  1. static gboolean
  2. gdk_event_dispatch (GSource    *source,
  3.                     GSourceFunc callback,
  4.                     gpointer    user_data)
  5. {
  6.   GdkDisplay *display = ((GdkDisplaySource*)source)->display;
  7.   GdkEvent *event;
  8.   GDK_THREADS_ENTER ();
  9.   _gdk_events_queue (display);
  10.   event = _gdk_event_unqueue (display);
  11.   if (event)
  12.     {
  13.       if (_gdk_event_func)
  14.         (*_gdk_event_func) (event, _gdk_event_data);
  15.       gdk_event_free (event);
  16.     }
  17.   GDK_THREADS_LEAVE ();
  18.   return TRUE;
  19. }