Sends an event to a widget, propagating the event to parent widgets if the event remains unhandled.
Events received by GTK+ from GDK normally begin in main_do_event. Depending on the type of event, existence of modal dialogs, grabs, etc., the event may be propagated; if so, this function is used.
propagate_event calls event on each widget it decides to send the event to. So event is the lowest-level function; it simply emits the event and possibly an event-specific signal on a widget. propagate_event is a bit higher-level, and main_do_event is the highest level.
All that said, you most likely don’t want to use any of these functions; synthesizing events is rarely needed. There are almost certainly better ways to achieve your goals. For example, use invalidate_rect or queue_draw instead of making up expose events.