/* ctk_event_emit_string() - Emits signal(s) on a registered ctk_event object. * This function is primarily used to simulate NV-CONTROL events such * that various parts of nvidia-settings can communicate (internally) */ void ctk_event_emit_string(CtkEvent *ctk_event, unsigned int mask, int attrib) { CtkEventStruct event; CtkEventSource *source; Display *dpy = NvCtrlGetDisplayPtr(ctk_event->handle); if (attrib > NV_CTRL_STRING_LAST_ATTRIBUTE) return; /* Find the event source */ source = event_sources; while (source) { if (source->dpy == dpy) { break; } source = source->next; } if (!source) return; /* Broadcast event to all relevant ctk_event objects */ event.attribute = attrib; event.value = 0; event.display_mask = mask; CTK_EVENT_BROADCAST(source, string_signals[attrib], &event, NvCtrlGetTargetType(ctk_event->handle), NvCtrlGetTargetId(ctk_event->handle)); } /* ctk_event_emit_string() */
/* ctk_event_emit() - Emits signal(s) on a registered ctk_event object. * This function is primarily used to simulate NV-CONTROL events such * that various parts of nvidia-settings can communicate (internally) */ void ctk_event_emit(CtkEvent *ctk_event, unsigned int mask, int attrib, int value) { CtrlEvent event; CtkEventSource *source; CtrlTarget *ctrl_target = ctk_event->ctrl_target; NvCtrlEventHandle *event_handle = NvCtrlGetEventHandle(ctrl_target); if (attrib > NV_CTRL_LAST_ATTRIBUTE) return; /* Find the event source */ source = event_sources; while (source) { if (source->event_handle == event_handle) { break; } source = source->next; } if (!source) return; /* Broadcast event to all relevant ctk_event objects */ memset(&event, 0, sizeof(CtrlEvent)); event.type = CTRL_EVENT_TYPE_INTEGER_ATTRIBUTE; event.target_type = NvCtrlGetTargetType(ctrl_target); event.target_id = NvCtrlGetTargetId(ctrl_target); event.int_attr.attribute = attrib; event.int_attr.value = value; CTK_EVENT_BROADCAST(source, signals[attrib], &event); } /* ctk_event_emit() */
/* - ctk_event_register_source() * * Keep track of event sources globally to support * dispatching events on a dpy to multiple CtkEvent * objects. Since the driver only sends out one event * notification per dpy (client), there should only be one * event source attached per unique dpy. When an event * is received, the dispatching function should then * emit a signal to every CtkEvent object that * requests event notification from the dpy for the * given target type/id (X screen, GPU etc). */ static void ctk_event_register_source(CtkEvent *ctk_event) { Display *dpy = NvCtrlGetDisplayPtr(ctk_event->handle); CtkEventSource *event_source; CtkEventNode *event_node; if (!dpy) { return; } /* Do we already have an event source for this dpy? */ event_source = event_sources; while (event_source) { if (event_source->dpy == dpy) { break; } event_source = event_source->next; } /* create a new input source */ if (!event_source) { GSource *source; static GSourceFuncs ctk_source_funcs = { ctk_event_prepare, ctk_event_check, ctk_event_dispatch, NULL, /* finalize */ NULL, /* closure_callback */ NULL, /* closure_marshal */ }; source = g_source_new(&ctk_source_funcs, sizeof(CtkEventSource)); event_source = (CtkEventSource *) source; if (!event_source) { return; } event_source->dpy = dpy; event_source->event_poll_fd.fd = ConnectionNumber(dpy); event_source->event_poll_fd.events = G_IO_IN; event_source->event_base = NvCtrlGetEventBase(ctk_event->handle); event_source->randr_event_base = NvCtrlGetXrandrEventBase(ctk_event->handle); /* add the input source to the glib main loop */ g_source_add_poll(source, &event_source->event_poll_fd); g_source_attach(source, NULL); /* add the source to the global list of sources */ event_source->next = event_sources; event_sources = event_source; } /* Add the ctk_event object to the source's list of event objects */ event_node = (CtkEventNode *)g_malloc(sizeof(CtkEventNode)); if (!event_node) { return; } event_node->ctk_event = ctk_event; event_node->target_type = NvCtrlGetTargetType(ctk_event->handle); event_node->target_id = NvCtrlGetTargetId(ctk_event->handle); event_node->next = event_source->ctk_events; event_source->ctk_events = event_node; /* * This next bit of code is to make sure that the randr_event_base * for this event source is valid in the case where a NON X Screen * target type handle is used to create the initial event source * (Resulting in randr_event_base being == -1), followed by an * X Screen target type handle registering itself to receive * XRandR events on the existing dpy/event source. */ if (event_source->randr_event_base == -1 && event_node->target_type == NV_CTRL_TARGET_TYPE_X_SCREEN) { event_source->randr_event_base = NvCtrlGetXrandrEventBase(ctk_event->handle); } } /* ctk_event_register_source() */
/* - ctk_event_register_source() * * Keep track of event sources globally to support * dispatching events on an event handle to multiple CtkEvent * objects. Since the driver only sends out one event * notification per event handle (client), there should only be one * event source attached per unique event handle. When an event * is received, the dispatching function should then * emit a signal to every CtkEvent object that * requests event notification from the event handle for the * given target type/id (X screen, GPU etc). */ static void ctk_event_register_source(CtkEvent *ctk_event) { CtrlTarget *ctrl_target = ctk_event->ctrl_target; NvCtrlEventHandle *event_handle = NvCtrlGetEventHandle(ctrl_target); CtkEventSource *event_source; CtkEventNode *event_node; if (!event_handle) { return; } /* Do we already have an event source for this event handle? */ event_source = find_event_source(event_handle); /* create a new input source */ if (!event_source) { GSource *source; int event_fd; static GSourceFuncs ctk_source_funcs = { ctk_event_prepare, ctk_event_check, ctk_event_dispatch, NULL, /* finalize */ NULL, /* closure_callback */ NULL, /* closure_marshal */ }; source = g_source_new(&ctk_source_funcs, sizeof(CtkEventSource)); event_source = (CtkEventSource *) source; if (!event_source) { return; } NvCtrlEventHandleGetFD(event_handle, &event_fd); event_source->event_handle = event_handle; event_source->event_poll_fd.fd = event_fd; event_source->event_poll_fd.events = G_IO_IN; /* add the input source to the glib main loop */ g_source_add_poll(source, &event_source->event_poll_fd); g_source_attach(source, NULL); /* add the source to the global list of sources */ event_source->next = event_sources; event_sources = event_source; } /* Add the ctk_event object to the source's list of event objects */ event_node = (CtkEventNode *)g_malloc(sizeof(CtkEventNode)); if (!event_node) { return; } event_node->ctk_event = ctk_event; event_node->target_type = NvCtrlGetTargetType(ctrl_target); event_node->target_id = NvCtrlGetTargetId(ctrl_target); event_node->next = event_source->ctk_events; event_source->ctk_events = event_node; } /* ctk_event_register_source() */