GtkWidget* ctk_display_device_new(CtrlTarget *ctrl_target, CtkConfig *ctk_config, CtkEvent *ctk_event, CtkEvent *ctk_event_gpu, char *name, char *typeBaseName, ParsedAttribute *p) { GObject *object; CtkDisplayDevice *ctk_object; GtkWidget *banner; GtkWidget *hbox, *tmpbox; GtkWidget *alignment; GtkWidget *notebook; GtkWidget *nbox; GtkWidget *align; GtkWidget *label; GtkWidget *hseparator; GtkWidget *button; gchar *str; int i; object = g_object_new(CTK_TYPE_DISPLAY_DEVICE, NULL); if (!object) return NULL; ctk_object = CTK_DISPLAY_DEVICE(object); ctk_object->ctrl_target = ctrl_target; ctk_object->ctk_event = ctk_event; ctk_object->ctk_event_gpu = ctk_event_gpu; ctk_object->ctk_config = ctk_config; ctk_object->name = g_strdup(name); ctk_object->color_correction_available = FALSE; gtk_box_set_spacing(GTK_BOX(object), 10); /* Banner */ if (strcmp(typeBaseName, "CRT") == 0) { banner = ctk_banner_image_new(BANNER_ARTWORK_CRT); } else { banner = ctk_banner_image_new(BANNER_ARTWORK_DFP); } gtk_box_pack_start(GTK_BOX(object), banner, FALSE, FALSE, 0); /* Create tabbed notebook for widget */ notebook = gtk_notebook_new(); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP); gtk_box_pack_start(GTK_BOX(object), notebook, TRUE, TRUE, 0); /* Create first tab for device info */ nbox = gtk_vbox_new(FALSE, FRAME_PADDING); gtk_container_set_border_width(GTK_CONTAINER(nbox), FRAME_PADDING); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), nbox, gtk_label_new("Information")); /* Device info */ hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(nbox), hbox, FALSE, FALSE, 0); label = gtk_label_new("Display Device Information"); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); hseparator = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(hbox), hseparator, TRUE, TRUE, 5); /* create the hbox to store device info */ hbox = gtk_hbox_new(FALSE, FRAME_PADDING); gtk_box_pack_start(GTK_BOX(nbox), hbox, FALSE, FALSE, FRAME_PADDING); /* * insert a vbox between the frame and the widgets, so that the * widgets don't expand to fill all of the space within the * frame */ tmpbox = gtk_vbox_new(FALSE, FRAME_PADDING); gtk_container_set_border_width(GTK_CONTAINER(tmpbox), FRAME_PADDING); gtk_container_add(GTK_CONTAINER(hbox), tmpbox); /* Create and add the information widgets */ ctk_object->num_info_entries = ARRAY_LEN(__info_entry_data); ctk_object->info_entries = calloc(ctk_object->num_info_entries, sizeof(InfoEntry)); if (!ctk_object->info_entries) { ctk_object->num_info_entries = 0; } for (i = 0; i < ctk_object->num_info_entries; i++) { InfoEntryData *entryData = __info_entry_data+i; InfoEntry *entry = ctk_object->info_entries+i; gchar *str; entry->ctk_object = ctk_object; str = g_strconcat(entryData->str, ":", NULL); entry->label = gtk_label_new(str); g_free(str); entry->txt = gtk_label_new(""); gtk_misc_set_alignment(GTK_MISC(entry->label), 0.0f, 0.5f); gtk_misc_set_alignment(GTK_MISC(entry->txt), 0.0f, 0.5f); ctk_config_set_tooltip(ctk_config, entry->label, *(entryData->tooltip)); ctk_config_set_tooltip(ctk_config, entry->txt, *(entryData->tooltip)); entry->hbox = gtk_hbox_new(FALSE, FRAME_PADDING); gtk_box_pack_start(GTK_BOX(entry->hbox), entry->label, FALSE, TRUE, FRAME_PADDING); gtk_box_pack_start(GTK_BOX(entry->hbox), entry->txt, FALSE, TRUE, FRAME_PADDING); gtk_box_pack_start(GTK_BOX(tmpbox), entry->hbox, FALSE, FALSE, 0); } /* pack the EDID button */ ctk_object->edid = ctk_edid_new(ctrl_target, ctk_object->ctk_config, ctk_object->ctk_event, ctk_object->name); hbox = gtk_hbox_new(FALSE, 0); align = gtk_alignment_new(0, 1, 1, 1); gtk_container_add(GTK_CONTAINER(align), hbox); gtk_box_pack_end(GTK_BOX(nbox), align, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), ctk_object->edid, TRUE, TRUE, 0); /* * Create layout for second tab for controls but don't add the tab until we * make sure it's required */ nbox = gtk_vbox_new(FALSE, FRAME_PADDING); gtk_container_set_border_width(GTK_CONTAINER(nbox), FRAME_PADDING); /* pack the reset button */ button = gtk_button_new_with_label("Reset Hardware Defaults"); str = ctk_help_create_reset_hardware_defaults_text(typeBaseName, name); ctk_config_set_tooltip(ctk_config, button, str); ctk_object->reset_button = button; alignment = gtk_alignment_new(1, 1, 0, 0); gtk_container_add(GTK_CONTAINER(alignment), button); gtk_box_pack_end(GTK_BOX(nbox), alignment, FALSE, FALSE, 0); /* pack the color controls */ ctk_object->color_controls = ctk_color_controls_new(ctrl_target, ctk_config, ctk_event, ctk_object->reset_button, name); if (ctk_object->color_controls) { gtk_box_pack_start(GTK_BOX(nbox), ctk_object->color_controls, FALSE, FALSE, 0); } /* pack the dithering controls */ ctk_object->dithering_controls = ctk_dithering_controls_new(ctrl_target, ctk_config, ctk_event, ctk_object->reset_button, name); if (ctk_object->dithering_controls) { gtk_box_pack_start(GTK_BOX(nbox), ctk_object->dithering_controls, FALSE, FALSE, 0); } /* pack the image sliders */ ctk_object->image_sliders = ctk_image_sliders_new(ctrl_target, ctk_config, ctk_event, ctk_object->reset_button, name); if (ctk_object->image_sliders) { gtk_box_pack_start(GTK_BOX(nbox), ctk_object->image_sliders, FALSE, FALSE, 0); } /* If no controls are created, don't add a controls tab */ if (ctk_object->color_controls || ctk_object->dithering_controls || ctk_object->image_sliders) { gtk_notebook_append_page(GTK_NOTEBOOK(notebook), nbox, gtk_label_new("Controls")); } /* * Show all widgets on this page so far. After this, the color correction * tab and other widgets can control their own visibility. */ gtk_widget_show_all(GTK_WIDGET(object)); /* add the color correction tab if RandR is available */ add_color_correction_tab(ctk_object, ctk_config, ctk_event, notebook, p); /* Update the GUI */ display_device_setup(ctk_object); /* Listen to events */ g_signal_connect(G_OBJECT(ctk_object->reset_button), "clicked", G_CALLBACK(reset_button_clicked), (gpointer) ctk_object); g_signal_connect(G_OBJECT(ctk_event_gpu), CTK_EVENT_NAME(NV_CTRL_ENABLED_DISPLAYS), G_CALLBACK(enabled_displays_received), (gpointer) ctk_object); for (i = 0; i < ctk_object->num_info_entries; i++) { InfoEntryData *entryData = __info_entry_data+i; InfoEntry *entry = ctk_object->info_entries+i; if (entryData->register_events_func) { entryData->register_events_func(entry); } } return GTK_WIDGET(object); } /* ctk_display_device_new() */
GtkWidget* ctk_display_device_tv_new(NvCtrlAttributeHandle *handle, CtkConfig *ctk_config, CtkEvent *ctk_event, char *name) { GObject *object; CtkDisplayDeviceTv *ctk_display_device_tv; GtkWidget *banner; GtkWidget *frame; GtkWidget *eventbox; GtkWidget *tmpbox; GtkWidget *hbox; GtkWidget *alignment; object = g_object_new(CTK_TYPE_DISPLAY_DEVICE_TV, NULL); if (!object) return NULL; ctk_display_device_tv = CTK_DISPLAY_DEVICE_TV(object); ctk_display_device_tv->handle = handle; ctk_display_device_tv->ctk_config = ctk_config; ctk_display_device_tv->ctk_event = ctk_event; ctk_display_device_tv->name = g_strdup(name); gtk_box_set_spacing(GTK_BOX(object), 10); /* banner */ banner = ctk_banner_image_new(BANNER_ARTWORK_TV); gtk_box_pack_start(GTK_BOX(object), banner, FALSE, FALSE, 0); /* Information */ frame = gtk_frame_new(NULL); gtk_box_pack_start(GTK_BOX(object), frame, FALSE, FALSE, 0); ctk_display_device_tv->info_frame = frame; hbox = gtk_hbox_new(FALSE, FRAME_PADDING); gtk_container_set_border_width(GTK_CONTAINER(hbox), FRAME_PADDING); gtk_container_add(GTK_CONTAINER(frame), hbox); tmpbox = gtk_vbox_new(FALSE, 5); gtk_container_add(GTK_CONTAINER(hbox), tmpbox); ctk_display_device_tv->txt_encoder_name = gtk_label_new(""); ctk_display_device_tv->txt_refresh_rate = gtk_label_new(""); /* pack the Refresh Rate Label */ { typedef struct { GtkWidget *label; GtkWidget *txt; const gchar *tooltip; } TextLineInfo; TextLineInfo lines[] = { { gtk_label_new("TV Encoder:"), ctk_display_device_tv->txt_encoder_name, __tv_encoder_name_help, }, { gtk_label_new("TV Refresh Rate:"), ctk_display_device_tv->txt_refresh_rate, __tv_refresh_rate_help, }, { NULL, NULL, NULL } }; int i; GtkRequisition req; int max_width; /* Compute max width of lables and setup text alignments */ max_width = 0; for (i = 0; lines[i].label; i++) { gtk_misc_set_alignment(GTK_MISC(lines[i].label), 0.0f, 0.5f); gtk_misc_set_alignment(GTK_MISC(lines[i].txt), 0.0f, 0.5f); gtk_widget_size_request(lines[i].label, &req); if (max_width < req.width) { max_width = req.width; } } /* Pack labels */ for (i = 0; lines[i].label; i++) { GtkWidget *tmphbox; /* Add separators */ if (i == 1) { GtkWidget *separator = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(tmpbox), separator, FALSE, FALSE, 0); } /* Set the label's width */ gtk_widget_set_size_request(lines[i].label, max_width, -1); /* add the widgets for this line */ tmphbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(tmphbox), lines[i].label, FALSE, TRUE, 5); gtk_box_pack_start(GTK_BOX(tmphbox), lines[i].txt, FALSE, TRUE, 5); /* Include tooltips */ if (!lines[i].tooltip) { gtk_box_pack_start(GTK_BOX(tmpbox), tmphbox, FALSE, FALSE, 0); } else { eventbox = gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(eventbox), tmphbox); ctk_config_set_tooltip(ctk_config, eventbox, lines[i].tooltip); gtk_box_pack_start(GTK_BOX(tmpbox), eventbox, FALSE, FALSE, 0); } } } /* NV_CTRL_REFRESH_RATE */ g_signal_connect(G_OBJECT(ctk_event), CTK_EVENT_NAME(NV_CTRL_REFRESH_RATE), G_CALLBACK(info_update_received), (gpointer) ctk_display_device_tv); /* NV_CTRL_TV_OVERSCAN */ ctk_display_device_tv->overscan = add_scale(ctk_display_device_tv, NV_CTRL_TV_OVERSCAN, "TV OverScan", __tv_overscan_help); g_signal_connect(G_OBJECT(ctk_event), CTK_EVENT_NAME(NV_CTRL_TV_OVERSCAN), G_CALLBACK(value_received), (gpointer) ctk_display_device_tv); /* NV_CTRL_TV_FLICKER_FILTER */ ctk_display_device_tv->flicker_filter = add_scale(ctk_display_device_tv, NV_CTRL_TV_FLICKER_FILTER, "TV Flicker Filter", __tv_flicker_filter_help); g_signal_connect(G_OBJECT(ctk_event), CTK_EVENT_NAME(NV_CTRL_TV_FLICKER_FILTER), G_CALLBACK(value_received), (gpointer) ctk_display_device_tv); /* NV_CTRL_TV_BRIGHTNESS */ ctk_display_device_tv->brightness = add_scale(ctk_display_device_tv, NV_CTRL_TV_BRIGHTNESS, "TV Brightness", __tv_brightness_help); g_signal_connect(G_OBJECT(ctk_event), CTK_EVENT_NAME(NV_CTRL_TV_BRIGHTNESS), G_CALLBACK(value_received), (gpointer) ctk_display_device_tv); /* NV_CTRL_TV_HUE */ ctk_display_device_tv->hue = add_scale(ctk_display_device_tv, NV_CTRL_TV_HUE, "TV Hue", __tv_hue_help); g_signal_connect(G_OBJECT(ctk_event), CTK_EVENT_NAME(NV_CTRL_TV_HUE), G_CALLBACK(value_received), (gpointer) ctk_display_device_tv); /* NV_CTRL_TV_CONTRAST */ ctk_display_device_tv->contrast = add_scale(ctk_display_device_tv, NV_CTRL_TV_CONTRAST, "TV Contrast", __tv_contrast_help); g_signal_connect(G_OBJECT(ctk_event), CTK_EVENT_NAME(NV_CTRL_TV_CONTRAST), G_CALLBACK(value_received), (gpointer) ctk_display_device_tv); /* NV_CTRL_TV_SATURATION */ ctk_display_device_tv->saturation = add_scale(ctk_display_device_tv, NV_CTRL_TV_SATURATION, "TV Saturation", __tv_saturation_help); g_signal_connect(G_OBJECT(ctk_event), CTK_EVENT_NAME(NV_CTRL_TV_SATURATION), G_CALLBACK(value_received), (gpointer) ctk_display_device_tv); /* Create the reset button here so it can be used by the image sliders */ ctk_display_device_tv->reset_button = gtk_button_new_with_label("Reset TV Hardware Defaults"); /* create and pack the image sliders */ ctk_display_device_tv->image_sliders = ctk_image_sliders_new(handle, ctk_config, ctk_event, ctk_display_device_tv->reset_button, name); if (ctk_display_device_tv->image_sliders) { gtk_box_pack_start(GTK_BOX(object), ctk_display_device_tv->image_sliders, FALSE, FALSE, 0); } /* reset button */ g_signal_connect(G_OBJECT(ctk_display_device_tv->reset_button), "clicked", G_CALLBACK(reset_button_clicked), (gpointer) ctk_display_device_tv); alignment = gtk_alignment_new(1, 1, 0, 0); gtk_container_add(GTK_CONTAINER(alignment), ctk_display_device_tv->reset_button); gtk_box_pack_end(GTK_BOX(object), alignment, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(ctk_event), CTK_EVENT_NAME(NV_CTRL_TV_RESET_SETTINGS), G_CALLBACK(value_received), (gpointer) ctk_display_device_tv); ctk_config_set_tooltip(ctk_config, ctk_display_device_tv->reset_button, ctk_help_create_reset_hardware_defaults_text("TV", name)); /* EDID button box */ ctk_display_device_tv->edid = ctk_edid_new(ctk_display_device_tv->handle, ctk_display_device_tv->ctk_config, ctk_display_device_tv->ctk_event, ctk_display_device_tv->name); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), ctk_display_device_tv->edid, TRUE, TRUE, 0); /* finally, display the widget */ gtk_widget_show_all(GTK_WIDGET(object)); /* update the GUI */ update_display_enabled_flag(ctk_display_device_tv->handle, &ctk_display_device_tv->display_enabled); ctk_display_device_tv_setup(ctk_display_device_tv); /* handle enable/disable events on the display device */ g_signal_connect(G_OBJECT(ctk_event), CTK_EVENT_NAME(NV_CTRL_ENABLED_DISPLAYS), G_CALLBACK(enabled_displays_received), (gpointer) ctk_display_device_tv); return GTK_WIDGET(object); } /* ctk_display_device_tv_new() */