Example #1
0
static GtkWidget *add_table_int_row(CtkConfig *ctk_config, GtkWidget *table,
                                    const gchar *help, gchar *label1,
                                    uint64_t val, gint row,
                                    gboolean ecc_enabled)
{
    GtkWidget *hbox2, *label, *eventbox;

    gtk_table_resize(GTK_TABLE(table), row+1, 2);
    hbox2 = gtk_hbox_new(FALSE, 0);
    gtk_table_attach(GTK_TABLE(table), hbox2, 0, 1, row, row+1,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);

    label = gtk_label_new(label1);
    gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
    gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
    gtk_widget_set_sensitive(label, ecc_enabled);

    eventbox = gtk_event_box_new();
    gtk_table_attach(GTK_TABLE(table), eventbox, 1, 2, row, row+1,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);

    label = gtk_label_new(NULL);
    set_label_value(label, val);
    gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
    gtk_container_add(GTK_CONTAINER(eventbox), label);
    ctk_config_set_tooltip(ctk_config, eventbox, help);
    gtk_widget_set_sensitive(label, ecc_enabled);

    return label;
} /* add_table_int_row() */
Example #2
0
static GtkWidget * add_scale(CtkConfig *ctk_config,
                             int attribute,
                             char *name,
                             const char *help,
                             gint value_type,
                             gint default_value,
                             gpointer callback_data)
{
    GtkObject *adj;
    GtkWidget *scale;


    adj = gtk_adjustment_new(0, 0, 10, 1, 1, 0);

    g_object_set_data(G_OBJECT(adj), "attribute",
                      GINT_TO_POINTER(attribute));

    g_object_set_data(G_OBJECT(adj), "attribute name", name);

    g_object_set_data(G_OBJECT(adj), "attribute default value",
                      GINT_TO_POINTER(default_value));

    g_signal_connect(G_OBJECT(adj), "value_changed",
                     G_CALLBACK(scale_value_changed),
                     (gpointer) callback_data);

    scale = ctk_scale_new(GTK_ADJUSTMENT(adj), name, ctk_config, value_type);

    ctk_config_set_tooltip(ctk_config, CTK_SCALE_TOOLTIP_WIDGET(scale),
                           help);

    return scale;

} /* add_scale() */
Example #3
0
static GtkWidget *create_check_button(CtkXVideo *ctk_xvideo,
                                      GtkWidget *vbox,
                                      GtkWidget *button,
                                      const gchar *name,
                                      const char *help,
                                      gint attribute,
                                      unsigned int bit)
{
    GtkWidget *check_button;
    ReturnStatus ret;
    int val;
    
    /* get the attribute value */
    
    ret = NvCtrlGetAttribute(ctk_xvideo->handle, attribute, &val);
    
    if (ret != NvCtrlSuccess) return NULL;
    
    check_button = gtk_check_button_new_with_label(name);
    
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button), val);
            
    g_signal_connect(G_OBJECT(check_button), "toggled",
                     G_CALLBACK(check_button_toggled),
                     (gpointer) ctk_xvideo);

    g_signal_connect_swapped(G_OBJECT(check_button), "toggled",
                             G_CALLBACK(set_button_sensitive),
                             (gpointer) button);

    g_object_set_data(G_OBJECT(check_button), "xvideo_attribute",
                      GINT_TO_POINTER(attribute));

    ctk_config_set_tooltip(ctk_xvideo->ctk_config, check_button, name);

    gtk_box_pack_start(GTK_BOX(vbox), check_button, FALSE, FALSE, 0);
    
    ctk_xvideo->active_attributes |= bit;

    ctk_config_set_tooltip(ctk_xvideo->ctk_config, check_button, help);

    return check_button;
    
} /* create_check_button() */
Example #4
0
/*
 * Helper function to add a tooltip to a widget *and* append a section to the
 * help text for that widget, for pages which use CtkHelpDataItem lists
 */
void ctk_config_set_tooltip_and_add_help_data(CtkConfig *config,
                                              GtkWidget *widget,
                                              GList **help_data_list,
                                              const gchar *label,
                                              const gchar *help_text,
                                              const gchar *extended_help_text)
{
    ctk_help_data_list_prepend(help_data_list, label, help_text, extended_help_text); 
    ctk_config_set_tooltip(config, widget, help_text);
}
Example #5
0
/*
 * xv_sync_to_display_radio_button_enabled_add()
 */
static void xv_sync_to_display_radio_button_enabled_add(CtkXVideo *ctk_xvideo,
                                                        gint add_device_mask)
{
    GtkWidget *radio[24], *prev_radio = NULL, *b1, *b2;
    int n;
    ReturnStatus ret;
    char *name, *type;
    gchar *name_str;

    /* Get the previous radio button. */
    for (n = 0; n < 24; n++) {
        b1 = ctk_xvideo->xv_sync_to_display_buttons[n];
        if (b1 != NULL) {
            prev_radio = b1;
            break;
        }
    }
    /* Get the next index where to add button. */
    for (n = 0; n < 24; n++) {
        b2 = ctk_xvideo->xv_sync_to_display_buttons[n];
        if (b2 == NULL) break;
    }
    ret = NvCtrlGetStringDisplayAttribute(ctk_xvideo->handle, add_device_mask,
                                          NV_CTRL_STRING_DISPLAY_DEVICE_NAME,
                                          &name);

    if ((ret != NvCtrlSuccess) || (!name)) {
        name = g_strdup("Unknown");
    }
    /* get the display device type */
    type = display_device_mask_to_display_device_name(add_device_mask);
    name_str = g_strdup_printf("%s (%s)", name, type);
    XFree(name);
    free(type);

    radio[n] = xv_sync_to_display_radio_button_add(ctk_xvideo,
                                                   prev_radio, name_str,
                                                   add_device_mask, n);
    g_free(name_str);
    ctk_config_set_tooltip(ctk_xvideo->ctk_config, radio[n],
                                            __xv_sync_to_display_help);
    

} /* xv_sync_to_display_radio_button_enabled_add() */
Example #6
0
/*
 * xv_sync_to_display_radio_button_add() - create a radio button and plug it
 * into the xv_sync_display_buttons radio group.
 */
static GtkWidget *xv_sync_to_display_radio_button_add(CtkXVideo *ctk_xvideo,
                                                      GtkWidget *last_button,
                                                      gint display_id)
{
    gchar *label;
    GtkWidget *button;
    GSList *slist;

    if (display_id == NV_CTRL_XV_SYNC_TO_DISPLAY_ID_AUTO) {
        label = g_strdup("Auto");
    } else {
        label = xv_sync_to_display_radio_button_label(ctk_xvideo, display_id);
    }

    if (last_button) {
        slist = gtk_radio_button_get_group(GTK_RADIO_BUTTON(last_button));
    } else {
        slist = NULL;
    }
    button = gtk_radio_button_new_with_label(slist, label);
    g_free(label);

    gtk_box_pack_start(GTK_BOX(ctk_xvideo->xv_sync_to_display_button_box),
                       button, FALSE, FALSE, 0);

    g_object_set_data(G_OBJECT(button), "display_id",
                      GINT_TO_POINTER(display_id));

    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);

    g_signal_connect(G_OBJECT(button), "toggled",
                     G_CALLBACK(xv_sync_to_display_id_toggled),
                     (gpointer) ctk_xvideo);

    ctk_config_set_tooltip(ctk_xvideo->ctk_config, button,
                           __xv_sync_to_display_help);

    return button;
}
static GtkWidget * add_scale(CtkDisplayDeviceTv *ctk_display_device_tv,
                             int attribute, char *name, const char *help)
{
    GtkObject *adj;
    GtkWidget *scale;

   
    adj = gtk_adjustment_new(0, 0, 10, 1, 1, 0);
        
    g_object_set_data(G_OBJECT(adj), "attribute",
                      GINT_TO_POINTER(attribute));

    g_object_set_data(G_OBJECT(adj), "attribute name", name);

    g_object_set_data(G_OBJECT(adj), "attribute active",
                      GINT_TO_POINTER(0));

    g_signal_connect(G_OBJECT(adj), "value_changed",
                     G_CALLBACK(adjustment_value_changed),
                     (gpointer) ctk_display_device_tv);
        
    scale = ctk_scale_new(GTK_ADJUSTMENT(adj), name,
                          ctk_display_device_tv->ctk_config,
                          G_TYPE_INT);
        
    if (help) {
        ctk_config_set_tooltip(ctk_display_device_tv->ctk_config,
                               CTK_SCALE_TOOLTIP_WIDGET(scale), help);
    }
    
    gtk_box_pack_start(GTK_BOX(ctk_display_device_tv), scale,
                       FALSE, FALSE, 0);
    
    return scale;

} /* add_scale() */
Example #8
0
GtkWidget* ctk_ecc_new(CtrlTarget *ctrl_target,
                       CtkConfig *ctk_config,
                       CtkEvent *ctk_event)
{
    GObject *object;
    CtkEcc *ctk_ecc;
    GtkWidget *hbox, *hbox2, *vbox, *hsep, *hseparator, *table;
    GtkWidget *banner, *label, *eventbox;
    int64_t sbit_error;
    int64_t aggregate_sbit_error;
    int64_t dbit_error;
    int64_t aggregate_dbit_error;
    gint ecc_config_supported;
    gint val, row = 0;
    gboolean sbit_error_available;
    gboolean aggregate_sbit_error_available;
    gboolean dbit_error_available;
    gboolean aggregate_dbit_error_available;
    gboolean ecc_enabled;
    gboolean ecc_default_status;
    ReturnStatus ret;
    gchar *ecc_enabled_string;
    gchar *str = NULL;

    /* make sure we have a handle */

    g_return_val_if_fail((ctrl_target != NULL) &&
                         (ctrl_target->h != NULL), NULL);

    /*
     * check if ECC support available.
     */

    ret = NvCtrlGetAttribute(ctrl_target,
                             NV_CTRL_GPU_ECC_SUPPORTED,
                             &val);
    if (ret != NvCtrlSuccess || val != NV_CTRL_GPU_ECC_SUPPORTED_TRUE) {
        return NULL;
    }

    /* create the CtkEcc object */

    object = g_object_new(CTK_TYPE_ECC, NULL);

    ctk_ecc = CTK_ECC(object);
    ctk_ecc->ctrl_target = ctrl_target;
    ctk_ecc->ctk_config = ctk_config;
    ctk_ecc->ecc_toggle_warning_dlg_shown = FALSE;

    sbit_error_available = TRUE;
    dbit_error_available = TRUE;
    aggregate_sbit_error_available = TRUE;
    aggregate_dbit_error_available = TRUE;

    sbit_error = 0;
    dbit_error = 0;
    aggregate_sbit_error = 0;
    aggregate_dbit_error = 0;

    /* Query ECC Status */

    ret = NvCtrlGetAttribute(ctrl_target, NV_CTRL_GPU_ECC_STATUS,
                             &val);
    if (ret != NvCtrlSuccess || val == NV_CTRL_GPU_ECC_STATUS_DISABLED) {
        ecc_enabled = FALSE;
        ecc_enabled_string = "Disabled";
    } else {
        ecc_enabled = TRUE;
        ecc_enabled_string = "Enabled";
    }
    ctk_ecc->ecc_enabled = ecc_enabled;

    /* Query ECC Configuration */

    ret = NvCtrlGetAttribute(ctrl_target, NV_CTRL_GPU_ECC_CONFIGURATION,
                             &val);
    if (ret != NvCtrlSuccess ||
            val == NV_CTRL_GPU_ECC_CONFIGURATION_DISABLED) {
        ctk_ecc->ecc_configured = FALSE;
    } else {
        ctk_ecc->ecc_configured = TRUE;
    }

    /* get default status */
    ret = NvCtrlGetAttribute(ctrl_target,
                             NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION,
                             &val);
    if (ret != NvCtrlSuccess ||
            val == NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION_DISABLED) {
        ecc_default_status = FALSE;
    } else {
        ecc_default_status = TRUE;
    }

    /* Query ECC errors */

    ret = NvCtrlGetAttribute64(ctrl_target,
                               NV_CTRL_GPU_ECC_SINGLE_BIT_ERRORS,
                               &sbit_error);
    if (ret != NvCtrlSuccess) {
        sbit_error_available = FALSE;
    }
    ret = NvCtrlGetAttribute64(ctrl_target,
                               NV_CTRL_GPU_ECC_DOUBLE_BIT_ERRORS,
                               &dbit_error);
    if (ret != NvCtrlSuccess) {
        dbit_error_available = FALSE;
    }
    ret = NvCtrlGetAttribute64(ctrl_target,
                               NV_CTRL_GPU_ECC_AGGREGATE_SINGLE_BIT_ERRORS,
                               &aggregate_sbit_error);
    if (ret != NvCtrlSuccess) {
        aggregate_sbit_error_available = FALSE;
    }
    ret = NvCtrlGetAttribute64(ctrl_target,
                               NV_CTRL_GPU_ECC_AGGREGATE_DOUBLE_BIT_ERRORS,
                               &aggregate_dbit_error);
    if (ret != NvCtrlSuccess) {
        aggregate_dbit_error_available = FALSE;
    }
    ctk_ecc->sbit_error_available = sbit_error_available;
    ctk_ecc->aggregate_sbit_error_available = aggregate_sbit_error_available;
    ctk_ecc->dbit_error_available = dbit_error_available;
    ctk_ecc->aggregate_dbit_error_available = aggregate_dbit_error_available;
    /* Query ECC configuration supported */

    ret = NvCtrlGetAttribute(ctrl_target,
                             NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED,
                             &ecc_config_supported);
    if (ret != NvCtrlSuccess) {
        ecc_config_supported = 0;
    }

    /* set container properties for the CtkEcc widget */

    gtk_box_set_spacing(GTK_BOX(ctk_ecc), 5);

    /* banner */

    banner = ctk_banner_image_new(BANNER_ARTWORK_GPU);
    gtk_box_pack_start(GTK_BOX(object), banner, FALSE, FALSE, 0);

    vbox = gtk_vbox_new(FALSE, 5);
    gtk_box_pack_start(GTK_BOX(object), vbox, TRUE, TRUE, 0);

    hbox = gtk_hbox_new(FALSE, 0);
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);

    label = gtk_label_new("ECC Status");
    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);

    table = gtk_table_new(1, 2, FALSE);
    gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
    gtk_table_set_row_spacings(GTK_TABLE(table), 3);
    gtk_table_set_col_spacings(GTK_TABLE(table), 15);
    gtk_container_set_border_width(GTK_CONTAINER(table), 5);

    /* ECC Status */
    hbox2 = gtk_hbox_new(FALSE, 0);
    gtk_table_attach(GTK_TABLE(table), hbox2, 0, 1, row, row+1,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);

    label = gtk_label_new("ECC:");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
    gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);

    eventbox = gtk_event_box_new();
    gtk_table_attach(GTK_TABLE(table), eventbox, 1, 2, row, row+1,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);

    label = gtk_label_new(ecc_enabled_string);
    gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
    gtk_container_add(GTK_CONTAINER(eventbox), label);
    ctk_config_set_tooltip(ctk_config, eventbox, __ecc_status_help);
    ctk_ecc->status = label;

    row += 3;

    /* Add ECC Errors */

    if (sbit_error_available && dbit_error_available) {
        ctk_ecc->sbit_error =
            add_table_int_row(ctk_config, table, __sbit_error_help,
                              "Single-bit ECC Errors:", sbit_error,
                              row, ecc_enabled);
        row += 1; // add vertical padding between rows

        ctk_ecc->dbit_error =
            add_table_int_row(ctk_config, table, __dbit_error_help,
                              "Double-bit ECC Errors:", dbit_error,
                              row, ecc_enabled);
        row += 3; // add vertical padding between rows
    }

    if (aggregate_sbit_error_available && aggregate_dbit_error_available) {
        ctk_ecc->aggregate_sbit_error =
            add_table_int_row(ctk_config, table, __aggregate_sbit_error_help,
                              "Aggregate Single-bit ECC Errors:",
                              aggregate_sbit_error, row, ecc_enabled);
        row += 1; // add vertical padding between rows

        ctk_ecc->aggregate_dbit_error =
            add_table_int_row(ctk_config, table, __aggregate_dbit_error_help,
                              "Aggregate Double-bit ECC Errors:",
                              aggregate_dbit_error, row, ecc_enabled);
    }

    /* ECC configuration settings */

    hbox = gtk_hbox_new(FALSE, 0);
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);

    label = gtk_label_new("ECC Configuration");
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

    hsep = gtk_hseparator_new();
    gtk_box_pack_start(GTK_BOX(hbox), hsep, TRUE, TRUE, 5);

    hbox2 = gtk_hbox_new(FALSE, 0);
    ctk_ecc->configuration_status =
        gtk_check_button_new_with_label("Enable ECC");
    gtk_box_pack_start(GTK_BOX(hbox2),
                       ctk_ecc->configuration_status, FALSE, FALSE, 0);
    gtk_container_set_border_width(GTK_CONTAINER(hbox2), 5);
    gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ctk_ecc->configuration_status),
                                 ctk_ecc->ecc_configured);
    ctk_config_set_tooltip(ctk_config, ctk_ecc->configuration_status,
                           __configuration_status_help);
    g_signal_connect(G_OBJECT(ctk_ecc->configuration_status), "clicked",
                     G_CALLBACK(ecc_config_button_toggled),
                     (gpointer) ctk_ecc);
    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_GPU_ECC_CONFIGURATION),
                     G_CALLBACK(ecc_configuration_update_received),
                     (gpointer) ctk_ecc);
    gtk_widget_set_sensitive(ctk_ecc->configuration_status, ecc_config_supported);

    hbox = gtk_hbox_new(FALSE, 0);
    gtk_box_pack_start(GTK_BOX(ctk_ecc), hbox, FALSE, FALSE, 0);

    /* Add buttons */

    if (sbit_error_available && dbit_error_available) {
        ctk_ecc->clear_button = gtk_button_new_with_label("Clear ECC Errors");
        gtk_box_pack_end(GTK_BOX(hbox), ctk_ecc->clear_button, FALSE, FALSE, 0);
        ctk_config_set_tooltip(ctk_config, ctk_ecc->clear_button,
                               __clear_button_help);
        gtk_widget_set_sensitive(ctk_ecc->clear_button, ecc_enabled);
        g_signal_connect(G_OBJECT(ctk_ecc->clear_button), "clicked",
                         G_CALLBACK(clear_ecc_errors_button_clicked),
                         (gpointer) ctk_ecc);
    }

    if (aggregate_sbit_error_available && aggregate_dbit_error_available) {
        ctk_ecc->clear_aggregate_button =
            gtk_button_new_with_label("Clear Aggregate ECC Errors");
        gtk_box_pack_end(GTK_BOX(hbox), ctk_ecc->clear_aggregate_button,
                         FALSE, FALSE, 0);
        ctk_config_set_tooltip(ctk_config, ctk_ecc->clear_button,
                               __clear_aggregate_button_help);
        gtk_widget_set_sensitive(ctk_ecc->clear_aggregate_button, ecc_enabled);
        g_signal_connect(G_OBJECT(ctk_ecc->clear_aggregate_button),
                         "clicked",
                         G_CALLBACK(clear_aggregate_ecc_errors_button_clicked),
                         (gpointer) ctk_ecc);
    }

    ctk_ecc->reset_default_config_button =
        gtk_button_new_with_label("Reset Default Configuration");
    eventbox = gtk_event_box_new();
    gtk_container_add(GTK_CONTAINER(eventbox),
                      ctk_ecc->reset_default_config_button);
    gtk_box_pack_end(GTK_BOX(hbox), eventbox, FALSE, FALSE, 5);
    ctk_config_set_tooltip(ctk_config, ctk_ecc->reset_default_config_button,
                           __reset_default_config_button_help);
    gtk_widget_set_sensitive(ctk_ecc->reset_default_config_button,
                             ecc_config_supported &&
                             (ecc_enabled != ecc_default_status));
    g_signal_connect(G_OBJECT(ctk_ecc->reset_default_config_button),
                     "clicked",
                     G_CALLBACK(reset_default_config_button_clicked),
                     (gpointer) ctk_ecc);

    /* Register a timer callback to update Ecc status info */
    str = g_strdup_printf("ECC Settings (GPU %d)",
                          NvCtrlGetTargetId(ctrl_target));

    ctk_config_add_timer(ctk_ecc->ctk_config,
                         DEFAULT_UPDATE_ECC_STATUS_INFO_TIME_INTERVAL,
                         str,
                         (GSourceFunc) update_ecc_info,
                         (gpointer) ctk_ecc);

    g_free(str);

    gtk_widget_show_all(GTK_WIDGET(ctk_ecc));

    update_ecc_info(ctk_ecc);

    return GTK_WIDGET(ctk_ecc);
}
Example #9
0
/****
 *
 * Updates sensitivity of widgets in relation to the state
 * of overclocking.
 *
 */
static void sync_gui_sensitivity(CtkClocks *ctk_object)
{
    gboolean enabled = ctk_object->overclocking_enabled;
    gboolean probing = ctk_object->probing_optimal;
    gboolean modified = ctk_object->clocks_modified;
    gboolean moved = ctk_object->clocks_moved;


    /* Update the enable checkbox */

    g_signal_handlers_block_by_func(G_OBJECT(ctk_object->enable_checkbox),
                                    G_CALLBACK(overclocking_state_toggled),
                                    (gpointer) ctk_object);
    
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ctk_object->enable_checkbox),
                                 enabled);
    
    g_signal_handlers_unblock_by_func(G_OBJECT(ctk_object->enable_checkbox),
                                      G_CALLBACK(overclocking_state_toggled),
                                      (gpointer) ctk_object);

    gtk_widget_set_sensitive(ctk_object->enable_checkbox,
                             !probing);
    
    
    /* Update the clock selection dropdown */

    gtk_widget_set_sensitive(ctk_object->clock_menu, enabled && !probing);

    /* Update the Graphics clock slider */
    
    gtk_widget_set_sensitive(ctk_object->gpu_clk_scale, enabled && !probing);

    /* Update the Memory clock slider */

    gtk_widget_set_sensitive(ctk_object->mem_clk_scale, enabled && !probing);

    /* Update the Apply button */

    gtk_widget_set_sensitive(ctk_object->apply_button,
                             enabled && !probing && moved);


    /* Enable the Auto Detect button for 3D clocks only */

    if ( probing ) {
        gtk_button_set_label(GTK_BUTTON(ctk_object->detect_button), "Cancel Detection");
        gtk_widget_set_sensitive(ctk_object->detect_button, True);
        ctk_config_set_tooltip(ctk_object->ctk_config, ctk_object->detect_button,
                               __cancel_button_help);

    } else {
        gboolean set_sensitive;
        gtk_button_set_label(GTK_BUTTON(ctk_object->detect_button), "Auto Detect");
        set_sensitive = ((ctk_object->auto_detection_available) &&
                         (ctk_object->clocks_being_modified == CLOCKS_3D))
                        ? enabled : False;
        gtk_widget_set_sensitive(ctk_object->detect_button, set_sensitive);
        ctk_config_set_tooltip(ctk_object->ctk_config, ctk_object->detect_button,
                               __detect_button_help);
    }

    /* Update the Reset hardware defaults button */

    gtk_widget_set_sensitive(ctk_object->reset_button,
                             enabled && !probing && (moved || modified));

} /* sync_gui_sensitivity() */
Example #10
0
static GtkWidget *create_timer_list(CtkConfig *ctk_config)
{
    GtkTreeModel *model;
    GtkWidget *treeview;
    GtkCellRenderer *renderer;
    GtkTreeViewColumn *column;
    GtkWidget *sw;
    GtkWidget *vbox;
    GtkWidget *label;
    GtkWidget *alignment;
    
    sw = gtk_scrolled_window_new(NULL, NULL);
    
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);

    ctk_config->list_store =
        gtk_list_store_new(NUM_COLUMNS,
                           G_TYPE_POINTER,  /* TIMER_CONFIG_COLUMN */
                           G_TYPE_POINTER,  /* FUNCTION_COLUMN */
                           G_TYPE_POINTER,  /* DATA_COLUMN */
                           G_TYPE_UINT,     /* HANDLE_COLUMN */
                           G_TYPE_BOOLEAN); /* OWNER_ENABLE_COLUMN */
    
    model = GTK_TREE_MODEL(ctk_config->list_store);
    
    treeview = gtk_tree_view_new_with_model(model);
    
    g_object_unref(ctk_config->list_store);

    /* Enable */

    renderer = gtk_cell_renderer_toggle_new();
    g_signal_connect(renderer, "toggled",
                     G_CALLBACK(timer_enable_toggled), ctk_config);
    column = gtk_tree_view_column_new_with_attributes("Enabled", renderer,
                                                      NULL);
    
    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
    gtk_tree_view_column_set_resizable(column, FALSE);

    gtk_tree_view_column_set_cell_data_func(column,
                                            renderer,
                                            enabled_renderer_func,
                                            GINT_TO_POINTER
                                            (TIMER_CONFIG_COLUMN),
                                            NULL);

    /* Description */
    
    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes("Description",
                                                      renderer,
                                                      NULL);
    
    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
    gtk_tree_view_column_set_resizable(column, TRUE);

    gtk_tree_view_column_set_cell_data_func(column,
                                            renderer,
                                            description_renderer_func,
                                            GINT_TO_POINTER
                                            (TIMER_CONFIG_COLUMN),
                                            NULL);
    
    /* Time interval */

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes("Time Interval",
                                                      renderer,
                                                      NULL);

    g_signal_connect(renderer, "edited",
                     G_CALLBACK(time_interval_edited), ctk_config);
    
    gtk_tree_view_column_set_cell_data_func(column,
                                            renderer,
                                            time_interval_renderer_func,
                                            GINT_TO_POINTER
                                            (TIMER_CONFIG_COLUMN),
                                            NULL);
    
    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
    gtk_tree_view_column_set_resizable(column, FALSE);


    gtk_container_add(GTK_CONTAINER(sw), treeview);

    vbox = gtk_vbox_new(FALSE, 5);
    
    label = gtk_label_new("Active Timers:");
    alignment = gtk_alignment_new(0.0, 0.0, 0, 0);
    gtk_container_add(GTK_CONTAINER(alignment), label);
    gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
    
    /* create the tooltip for the treeview (can't do it per column) */
    
    ctk_config_set_tooltip(ctk_config, treeview,
                           "The Active Timers describe operations that "
                           "nvidia-settings will perform at regular "
                           "intervals.");
    
    return vbox;

} /* create_timer_list() */
Example #11
0
GtkWidget* ctk_config_new(ConfigProperties *conf, CtrlSystem *pCtrlSystem)
{
    gint i;
    GObject *object;
    CtkConfig *ctk_config;
    GtkWidget *hbox;
    GtkWidget *vbox;
    GtkWidget *banner;
    GtkWidget *label;
    GtkWidget *hseparator;
    GtkWidget *check_button;
    GtkWidget *alignment;
    gboolean b;

    struct {
        const char *label;
        unsigned int mask;
        GCallback toggled_callback;
        const char *help_text;
    } config_check_button_entries[] =
    {
        {
            "Display Status Bar",
            CONFIG_PROPERTIES_DISPLAY_STATUS_BAR,
            G_CALLBACK(display_status_bar_toggled),
            __status_bar_help
        },
        {
            "Slider Text Entries",
            CONFIG_PROPERTIES_SLIDER_TEXT_ENTRIES,
            G_CALLBACK(slider_text_entries_toggled),
            __slider_text_entries_help
        },
        {
            "Include X Display Names in the Config File",
            CONFIG_PROPERTIES_INCLUDE_DISPLAY_NAME_IN_CONFIG_FILE,
            G_CALLBACK(display_name_toggled),
            __x_display_names_help
        },
        {
            "Show \"Really Quit?\" Dialog",
            CONFIG_PROPERTIES_SHOW_QUIT_DIALOG,
            G_CALLBACK(show_quit_dialog_toggled),
            __show_quit_dialog_help
        },
        {
            "Update Rules when an Application Profile Name changes",
            CONFIG_PROPERTIES_UPDATE_RULES_ON_PROFILE_NAME_CHANGE,
            G_CALLBACK(update_rules_on_profile_name_change_toggled),
            __update_rules_on_profile_name_change_help
        },

    };

    object = g_object_new(CTK_TYPE_CONFIG, NULL);

    ctk_config = CTK_CONFIG(object);

    ctk_config->conf = conf;
    ctk_config->pCtrlSystem = pCtrlSystem;

    gtk_box_set_spacing(GTK_BOX(ctk_config), 10);
    

    /* initialize the statusbar widget */
    ctk_statusbar_init(&ctk_config->status_bar);

#ifndef CTK_GTK3
    /* initialize the tooltips widget */

    ctk_config->tooltips.object = gtk_tooltips_new();
#endif

    /* banner */

    banner = ctk_banner_image_new(BANNER_ARTWORK_CONFIG);
    gtk_box_pack_start(GTK_BOX(ctk_config), banner, FALSE, FALSE, 0);
    
    /* "nvidia-settings Configuration" */

    hbox = gtk_hbox_new (FALSE, 5);
    gtk_box_pack_start(GTK_BOX(ctk_config), hbox, FALSE, FALSE, 0);

    label = gtk_label_new("nvidia-settings Configuration");
    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, 0);
    
    /* check buttons: Enable tooltips, Display statusbar, and Display
       slider text entries */

    vbox = gtk_vbox_new(FALSE, 2);
    gtk_box_pack_start(GTK_BOX(ctk_config), vbox, FALSE, FALSE, 0);

    ctk_config->help_data = NULL;

    for (i = 0; i < ARRAY_LEN(config_check_button_entries); i++) {
        label = gtk_label_new(config_check_button_entries[i].label);

        check_button = gtk_check_button_new();
        gtk_container_add(GTK_CONTAINER(check_button), label);

        b = !!(ctk_config->conf->booleans & config_check_button_entries[i].mask);

        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button), b);
        gtk_box_pack_start(GTK_BOX(vbox), check_button, FALSE, FALSE, 0);
        g_signal_connect(G_OBJECT(check_button), "toggled",
                         config_check_button_entries[i].toggled_callback,
                         ctk_config);
        ctk_config_set_tooltip_and_add_help_data(ctk_config,
                                                 check_button,
                                                 &ctk_config->help_data,
                                                 config_check_button_entries[i].label,
                                                 config_check_button_entries[i].help_text,
                                                 NULL);
    }

    ctk_config->help_data = g_list_reverse(ctk_config->help_data);
    
    /* timer list */
    
    ctk_config->timer_list_box = gtk_hbox_new(FALSE, 0);
    ctk_config->timer_list = create_timer_list(ctk_config);
    g_object_ref(ctk_config->timer_list);
    ctk_config->timer_list_visible = FALSE;

    gtk_box_pack_start(GTK_BOX(ctk_config), ctk_config->timer_list_box,
                       TRUE, TRUE, 0); 


    /* "Save Current Configuration" button */

    label = gtk_label_new("Save Current Configuration");
    hbox  = gtk_hbox_new(FALSE, 0);
    ctk_config->button_save_rc = gtk_button_new();
    alignment = gtk_alignment_new(1, 1, 0, 0);

    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 15);
    gtk_container_add(GTK_CONTAINER(ctk_config->button_save_rc), hbox);
    gtk_container_add(GTK_CONTAINER(alignment), ctk_config->button_save_rc);
    gtk_box_pack_start(GTK_BOX(ctk_config), alignment, TRUE, TRUE, 0);

    /* Create the file selector for rc file */
    g_signal_connect(G_OBJECT(ctk_config->button_save_rc), "clicked",
                     G_CALLBACK(save_rc_clicked),
                     (gpointer) ctk_config);

    ctk_config_set_tooltip(ctk_config, ctk_config->button_save_rc,
                           __save_current_config_help);

    ctk_config->rc_filename = NULL;

    gtk_widget_show_all(GTK_WIDGET(ctk_config));

    return GTK_WIDGET(ctk_config);
}
Example #12
0
GtkWidget* ctk_gvo_sync_new(NvCtrlAttributeHandle *handle,
                            GtkWidget *parent_window,
                            CtkConfig *ctk_config,
                            CtkEvent *ctk_event,
                            CtkGvo *gvo_parent)
{
    GObject *object;
    CtkGvoSync *ctk_gvo_sync;
    GtkWidget *frame;
    GtkWidget *hbox;
    GtkWidget *label;
    GtkWidget *alignment;
    GtkWidget *button;

    GtkWidget *table, *menu;

    gint val, i;
    NVCTRLAttributeValidValuesRec valid;
    ReturnStatus ret;
    gint row;

    const char *help_text;
    

    /* make sure we have a handle */
    
    g_return_val_if_fail(handle != NULL, NULL);
    
    /* create and initialize the object */

    object = g_object_new(CTK_TYPE_GVO_SYNC, NULL);
    
    ctk_gvo_sync = CTK_GVO_SYNC(object);
    ctk_gvo_sync->handle = handle;
    ctk_gvo_sync->parent_window = parent_window;
    ctk_gvo_sync->ctk_config = ctk_config;
    ctk_gvo_sync->ctk_event = ctk_event;
    ctk_gvo_sync->gvo_parent = gvo_parent;
    
    /* Query the current GVO state */

    if ( !query_init_gvo_sync_state(ctk_gvo_sync) ) {
        // Free the object
        g_object_ref(object);
        gtk_object_sink(GTK_OBJECT(object));
        g_object_unref(object);
        return NULL;
    }

    /* set container properties for the widget */

    gtk_box_set_spacing(GTK_BOX(object), 10);
    
    /* banner */
    
    hbox = gtk_hbox_new(FALSE, 0);
    gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, 0);

    ctk_gvo_sync->banner_box = hbox;

    /*
     * Sync options
     */
    
    frame = gtk_frame_new("Sync Options");
    ctk_gvo_sync->frame = frame;
    
    gtk_box_pack_start(GTK_BOX(object), frame, FALSE, FALSE, 0);
    
    table = gtk_table_new(6, 2, FALSE);
    gtk_table_set_row_spacings(GTK_TABLE(table), 0);
    gtk_table_set_col_spacings(GTK_TABLE(table), 0);

    gtk_container_add(GTK_CONTAINER(frame), table);

    /* input video format */

    label = gtk_label_new("Input Video Format: ");
    gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label,
                     0, 1,  0, 1, GTK_FILL, GTK_FILL,
                     TABLE_PADDING, TABLE_PADDING);

    hbox = gtk_hbox_new(FALSE, 5);

    ctk_gvo_sync->input_video_format_text_entry = gtk_entry_new();

    ctk_config_set_tooltip(ctk_config,
                           ctk_gvo_sync->input_video_format_text_entry,
                           __input_video_format_help);
    
    gtk_entry_set_width_chars
        (GTK_ENTRY(ctk_gvo_sync->input_video_format_text_entry),
         max_input_video_format_text_entry_length());

    gtk_widget_set_sensitive(ctk_gvo_sync->input_video_format_text_entry,
                             FALSE);

    update_input_video_format_text_entry(ctk_gvo_sync);

    gtk_box_pack_start(GTK_BOX(hbox),
                       ctk_gvo_sync->input_video_format_text_entry,
                       TRUE, TRUE, 0);

    /* Input video format detect button */

    button = gtk_toggle_button_new_with_label("Detect");
    alignment = gtk_alignment_new(1, 1, 0, 0);
    gtk_container_add(GTK_CONTAINER(alignment), button);

    ctk_gvo_sync->input_video_format_detect_button = button;

    ctk_config_set_tooltip(ctk_config, button,
                           __input_video_format_detect_help);
    
    g_signal_connect(G_OBJECT(button), "toggled",
                     G_CALLBACK(detect_input_toggled), ctk_gvo_sync);

    gtk_box_pack_start(GTK_BOX(hbox), alignment, FALSE, FALSE, 0);

    gtk_table_attach(GTK_TABLE(table), hbox,
                     1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL,
                     TABLE_PADDING, TABLE_PADDING);

    /* Composite Termination */

    if (ctk_gvo_sync->caps & NV_CTRL_GVO_CAPABILITIES_COMPOSITE_TERMINATION) {

        button =
            gtk_check_button_new_with_label("Enable Composite Termination");
        
        ctk_config_set_tooltip(ctk_config, button,
                               __composite_termination_help);

        alignment = gtk_alignment_new(1, 1, 0, 0);
        
        gtk_container_add(GTK_CONTAINER(alignment), button);
        gtk_table_attach(GTK_TABLE(table), alignment,
                         0, 2, 2, 3, GTK_FILL | GTK_EXPAND, GTK_FILL,
                         TABLE_PADDING, TABLE_PADDING);
        
        ctk_gvo_sync->composite_termination_button = button;
        
        init_composite_termination(ctk_gvo_sync);
        
        g_signal_connect(G_OBJECT(button), "toggled",
                         G_CALLBACK(composite_termination_toggled),
                         ctk_gvo_sync);

        row = 3;
    } else {
        ctk_gvo_sync->composite_termination_button = NULL;
        row = 2;
    }

    /* Sync Mode */

    menu = start_menu("Sync Mode: ", table, row);
    
    ctk_drop_down_menu_append_item(CTK_DROP_DOWN_MENU(menu), "Free Running",
                                   NV_CTRL_GVO_SYNC_MODE_FREE_RUNNING);
    
    ctk_drop_down_menu_append_item(CTK_DROP_DOWN_MENU(menu), "GenLock",
                                   NV_CTRL_GVO_SYNC_MODE_GENLOCK);
    
    ctk_drop_down_menu_append_item(CTK_DROP_DOWN_MENU(menu), "FrameLock",
                                   NV_CTRL_GVO_SYNC_MODE_FRAMELOCK);
    
    finish_menu(menu, table, row);
    row++;
    
    ctk_gvo_sync->sync_mode_menu = menu;

    ctk_drop_down_menu_set_tooltip(ctk_config, CTK_DROP_DOWN_MENU(menu),
                                   __sync_mode_help);

    ctk_drop_down_menu_set_current_value
        (CTK_DROP_DOWN_MENU(ctk_gvo_sync->sync_mode_menu),
         ctk_gvo_sync->sync_mode);

    g_signal_connect(G_OBJECT(ctk_gvo_sync->sync_mode_menu), "changed",
                     G_CALLBACK(sync_mode_changed), (gpointer) ctk_gvo_sync);

    /* Sync Format */

    menu = start_menu("Sync Format: ", table, row);
    
    for (i = 0; syncFormatNames[i].name; i++) {
        ctk_drop_down_menu_append_item(CTK_DROP_DOWN_MENU(menu),
                                       syncFormatNames[i].name,
                                       syncFormatNames[i].format);
    }
    
    finish_menu(menu, table, row);
    row++;

    ctk_gvo_sync->sync_format_menu = menu;

    ctk_drop_down_menu_set_tooltip(ctk_config, CTK_DROP_DOWN_MENU(menu),
                                   __sync_format_help);

    init_sync_format_menu(ctk_gvo_sync);

    g_signal_connect(G_OBJECT(ctk_gvo_sync->sync_format_menu),
                     "changed", G_CALLBACK(sync_format_changed),
                     (gpointer) ctk_gvo_sync);

    /* Sync Status */

    label = gtk_label_new("Sync Status:");
    gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1,
                     GTK_FILL, GTK_FILL, TABLE_PADDING, TABLE_PADDING);

    ctk_gvo_sync->sync_lock_status_text = gtk_label_new("");

    update_sync_lock_status_text(ctk_gvo_sync);

    hbox = gtk_hbox_new(FALSE, 5);
    gtk_box_pack_start(GTK_BOX(hbox), ctk_gvo_sync->sync_lock_status_text,
                       FALSE, FALSE, 0);

    gtk_table_attach(GTK_TABLE(table), hbox,
                     1, 2, row, row+1,
                     GTK_FILL /*| GTK_EXPAND*/, GTK_FILL,
                     TABLE_PADDING, TABLE_PADDING);
    row++;


    /*
     * Synchronization Skew (Delay/Advance)
     */

    /* NV_CTRL_GVO_SYNC_DELAY_PIXELS */

    ret = NvCtrlGetValidAttributeValues(handle, NV_CTRL_GVO_SYNC_DELAY_PIXELS,
                                        &valid);

    if ((ret == NvCtrlSuccess) && (valid.type == ATTRIBUTE_TYPE_RANGE)) {
        ret = NvCtrlGetAttribute(handle, NV_CTRL_GVO_SYNC_DELAY_PIXELS, &val);
        if (ret != NvCtrlSuccess) val = 0;

        if (ctk_gvo_sync->caps & NV_CTRL_GVO_CAPABILITIES_ADVANCE_SYNC_SKEW) {
            label = gtk_label_new("HSync Advance:");
            help_text = __hsync_advance_help;
        } else {
            label = gtk_label_new("HSync Delay:");
            help_text = __hsync_delay_help;
        }

        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
        gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1,
                         GTK_FILL, GTK_FILL, TABLE_PADDING, TABLE_PADDING);

        ctk_gvo_sync->hsync_delay_spin_button =
            gtk_spin_button_new_with_range(valid.u.range.min,
                                           valid.u.range.max, 1);

        ctk_config_set_tooltip(ctk_config,
                               ctk_gvo_sync->hsync_delay_spin_button,
                               help_text);

        gtk_spin_button_set_value
            (GTK_SPIN_BUTTON(ctk_gvo_sync->hsync_delay_spin_button), val);
    
        g_signal_connect(G_OBJECT(ctk_gvo_sync->hsync_delay_spin_button),
                         "value-changed",
                         G_CALLBACK(hsync_delay_changed), ctk_gvo_sync);

        hbox = gtk_hbox_new(FALSE, 5);
        gtk_box_pack_start(GTK_BOX(hbox),
                           ctk_gvo_sync->hsync_delay_spin_button,
                           FALSE, FALSE, 0);

        label = gtk_label_new("(pixels)");
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
        gtk_box_pack_start(GTK_BOX(hbox), label,
                           FALSE, FALSE, 0);

        gtk_table_attach(GTK_TABLE(table), hbox,
                         1, 2, row, row+1,
                         GTK_FILL /*| GTK_EXPAND*/, GTK_FILL,
                         TABLE_PADDING, TABLE_PADDING);
        row++;
    }

    /* NV_CTRL_GVO_SYNC_DELAY_LINES */
    
    ret = NvCtrlGetValidAttributeValues(handle, NV_CTRL_GVO_SYNC_DELAY_LINES,
                                        &valid);

    if ((ret == NvCtrlSuccess) && (valid.type == ATTRIBUTE_TYPE_RANGE)) {
        ret = NvCtrlGetAttribute(handle, NV_CTRL_GVO_SYNC_DELAY_LINES, &val);
        if (ret != NvCtrlSuccess) val = 0;

        if (ctk_gvo_sync->caps & NV_CTRL_GVO_CAPABILITIES_ADVANCE_SYNC_SKEW) {
            label = gtk_label_new("VSync Advance:");
            help_text = __vsync_advance_help;
        } else {
            label = gtk_label_new("VSync Delay:");
            help_text = __vsync_delay_help;
        }

        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
        gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1,
                         GTK_FILL, GTK_FILL, TABLE_PADDING, TABLE_PADDING);

        ctk_gvo_sync->vsync_delay_spin_button =
            gtk_spin_button_new_with_range(valid.u.range.min,
                                           valid.u.range.max, 1);

        ctk_config_set_tooltip(ctk_config,
                               ctk_gvo_sync->vsync_delay_spin_button,
                               help_text);

        gtk_spin_button_set_value
            (GTK_SPIN_BUTTON(ctk_gvo_sync->vsync_delay_spin_button), val);
        
        g_signal_connect(G_OBJECT(ctk_gvo_sync->vsync_delay_spin_button),
                         "value-changed",
                         G_CALLBACK(vsync_delay_changed), ctk_gvo_sync);

        hbox = gtk_hbox_new(FALSE, 5);
        gtk_box_pack_start(GTK_BOX(hbox),
                           ctk_gvo_sync->vsync_delay_spin_button,
                           FALSE, FALSE, 0);

        label = gtk_label_new("(lines)");
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
        gtk_box_pack_start(GTK_BOX(hbox), label,
                           FALSE, FALSE, 0);

        gtk_table_attach(GTK_TABLE(table), hbox,
                         1, 2, row, row+1,
                         GTK_FILL /*| GTK_EXPAND*/, GTK_FILL,
                         TABLE_PADDING, TABLE_PADDING);
        row++;
    }

    /* create the watch cursor (for use when the "Detect" button is toggled" */
    
    ctk_gvo_sync->wait_cursor = gdk_cursor_new(GDK_WATCH);

    /* Set UI sensitivity */

    update_gvo_sync_sensitivity(ctk_gvo_sync);

    /* Start listening for events */

    register_for_gvo_sync_events(ctk_gvo_sync);

    /* show the page */

    gtk_widget_show_all(GTK_WIDGET(object));

    return GTK_WIDGET(object);

} /* ctk_gvo_sync_new() */
GtkWidget* ctk_dithering_controls_new(NvCtrlAttributeHandle *handle,
                                      CtkConfig *ctk_config,
                                      CtkEvent *ctk_event,
                                      GtkWidget *reset_button,
                                      char *name)
{
    GObject *object;
    CtkDitheringControls *ctk_dithering_controls;
    GtkWidget *frame, *vbox, *hbox, *label;
    GtkWidget *menu, *table, *menu_item = NULL, *separator;

    /* create the object */
    object = g_object_new(CTK_TYPE_DITHERING_CONTROLS, NULL);
    if (!object) {
        return NULL;
    }

    ctk_dithering_controls = CTK_DITHERING_CONTROLS(object);
    ctk_dithering_controls->handle = handle;
    ctk_dithering_controls->ctk_config = ctk_config;
    ctk_dithering_controls->reset_button = reset_button;
    ctk_dithering_controls->name = strdup(name);

    /* create main dithering box & frame */

    hbox = gtk_hbox_new(FALSE, 0);
    gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, FRAME_PADDING);
    ctk_dithering_controls->dithering_controls_box = hbox;

    frame = gtk_frame_new("Dithering Controls");
    gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, FALSE, 0);

    table = gtk_table_new(5, 4, FALSE);
    gtk_container_add(GTK_CONTAINER(frame), table);
    gtk_table_set_row_spacings(GTK_TABLE(table), 5);
    gtk_table_set_col_spacings(GTK_TABLE(table), 15);
    gtk_container_set_border_width(GTK_CONTAINER(table), 5);

    /* Build Dithering widgets & pack them in table */
    /* dropdown list for dithering configuration */
    menu = gtk_menu_new();

    menu_item = gtk_menu_item_new_with_label("Auto");
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
    gtk_widget_show(menu_item);

    menu_item = gtk_menu_item_new_with_label("Enabled");
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
    gtk_widget_show(menu_item);

    menu_item = gtk_menu_item_new_with_label("Disabled");
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
    gtk_widget_show(menu_item);

    ctk_dithering_controls->dithering_config_menu = gtk_option_menu_new();
    gtk_option_menu_set_menu
        (GTK_OPTION_MENU(ctk_dithering_controls->dithering_config_menu),
         menu);
    ctk_config_set_tooltip(ctk_config, 
                           ctk_dithering_controls->dithering_config_menu, 
                           __dithering_config_help);

    g_signal_connect(G_OBJECT(ctk_dithering_controls->dithering_config_menu),
                     "changed", G_CALLBACK(dithering_config_menu_changed),
                     (gpointer) ctk_dithering_controls);

    /* Packing label & dropdown */
    hbox = gtk_hbox_new(FALSE, 0);
    gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);

    label = gtk_label_new("Dithering: ");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

    hbox = gtk_hbox_new(FALSE, 0);
    gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 0, 1,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
    gtk_box_pack_start(GTK_BOX(hbox),
                       ctk_dithering_controls->dithering_config_menu,
                       FALSE, FALSE, 0);

    /* Build CurrentDithering widget  */
    hbox = gtk_hbox_new(FALSE, 0);
    gtk_table_attach(GTK_TABLE(table), hbox, 2, 3, 0, 1,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
    label = gtk_label_new("Current Dithering: ");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

    hbox = gtk_hbox_new(FALSE, 0);
    gtk_table_attach(GTK_TABLE(table), hbox, 3, 4, 0, 1,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
    label = gtk_label_new(NULL);
    ctk_dithering_controls->dithering_config_txt = label;
    gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

    /* H-bar 1 */
    vbox = gtk_vbox_new(FALSE, 0);
    separator = gtk_hseparator_new();
    gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 0);
    gtk_table_attach(GTK_TABLE(table), vbox, 0, 4, 1, 2,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);

    /* dropdown list for dithering modes - populated in setup */
    ctk_dithering_controls->dithering_mode_menu = gtk_option_menu_new();
    ctk_config_set_tooltip(ctk_config, 
                           ctk_dithering_controls->dithering_mode_menu, 
                           __dithering_mode_help);

    g_signal_connect(G_OBJECT(ctk_dithering_controls->dithering_mode_menu),
                     "changed", G_CALLBACK(dithering_mode_menu_changed),
                     (gpointer) ctk_dithering_controls);


    /* pack the label & drop down */
    hbox = gtk_hbox_new(FALSE, 0);
    gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 2, 3,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
    label = gtk_label_new("Mode: ");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

    hbox = gtk_hbox_new(FALSE, 0);
    ctk_dithering_controls->dithering_mode_box = hbox;
    gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 2, 3,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
    gtk_box_pack_start(GTK_BOX(hbox),
                       ctk_dithering_controls->dithering_mode_menu,
                       FALSE, FALSE, 0);

    /* Build CurrentMode widget  */
    hbox = gtk_hbox_new(FALSE, 0);
    gtk_table_attach(GTK_TABLE(table), hbox, 2, 3, 2, 3,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
    label = gtk_label_new("Current Mode: ");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

    hbox = gtk_hbox_new(FALSE, 0);
    gtk_table_attach(GTK_TABLE(table), hbox, 3, 4, 2, 3,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
    label = gtk_label_new(NULL);
    ctk_dithering_controls->dithering_mode_txt = label;
    gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

    /* H-bar 2 */
    vbox = gtk_vbox_new(FALSE, 0);
    separator = gtk_hseparator_new();
    gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 0);
    gtk_table_attach(GTK_TABLE(table), vbox, 0, 4, 3, 4,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);

    /* dithering depth */
    menu = gtk_menu_new();

    menu_item = gtk_menu_item_new_with_label("Auto");
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
    gtk_widget_show(menu_item);

    menu_item = gtk_menu_item_new_with_label("6 bpc");
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
    gtk_widget_show(menu_item);

    menu_item = gtk_menu_item_new_with_label("8 bpc");
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
    gtk_widget_show(menu_item);

    ctk_dithering_controls->dithering_depth_menu = gtk_option_menu_new();
    gtk_option_menu_set_menu
        (GTK_OPTION_MENU(ctk_dithering_controls->dithering_depth_menu),
         menu);
    ctk_config_set_tooltip(ctk_config, 
                           ctk_dithering_controls->dithering_depth_menu, 
                           __dithering_depth_help);

    g_signal_connect(G_OBJECT(ctk_dithering_controls->dithering_depth_menu),
                     "changed", G_CALLBACK(dithering_depth_menu_changed),
                     (gpointer) ctk_dithering_controls);

    /* Packing label & dropdown */
    hbox = gtk_hbox_new(FALSE, 0);
    gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 4, 5,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);

    label = gtk_label_new("Depth: ");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

    hbox = gtk_hbox_new(FALSE, 0);
    ctk_dithering_controls->dithering_depth_box = hbox;
    gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 4, 5,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
    gtk_box_pack_start(GTK_BOX(hbox),
                       ctk_dithering_controls->dithering_depth_menu,
                       FALSE, FALSE, 0);

    /* Build CurrentDitheringDepth widget  */
    hbox = gtk_hbox_new(FALSE, 0);
    gtk_table_attach(GTK_TABLE(table), hbox, 2, 3, 4, 5,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
    label = gtk_label_new("Current Depth: ");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

    hbox = gtk_hbox_new(FALSE, 0);
    gtk_table_attach(GTK_TABLE(table), hbox, 3, 4, 4, 5,
                     GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
    label = gtk_label_new(NULL);
    ctk_dithering_controls->dithering_depth_txt = label;
    gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

    gtk_widget_show_all(GTK_WIDGET(object));

    ctk_dithering_controls_setup(ctk_dithering_controls);

    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_DITHERING),
                     G_CALLBACK(dithering_update_received),
                     (gpointer) ctk_dithering_controls);
    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_DITHERING_MODE),
                     G_CALLBACK(dithering_update_received),
                     (gpointer) ctk_dithering_controls);
    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_DITHERING_DEPTH),
                     G_CALLBACK(dithering_update_received),
                     (gpointer) ctk_dithering_controls);

    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_CURRENT_DITHERING),
                     G_CALLBACK(dithering_update_received),
                     (gpointer) ctk_dithering_controls);
    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_CURRENT_DITHERING_MODE),
                     G_CALLBACK(dithering_update_received),
                     (gpointer) ctk_dithering_controls);
    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_CURRENT_DITHERING_DEPTH),
                     G_CALLBACK(dithering_update_received),
                     (gpointer) ctk_dithering_controls);

    return GTK_WIDGET(object);

} /* ctk_dithering_controls_new() */
GtkWidget* ctk_display_device_dfp_new(NvCtrlAttributeHandle *handle,
                                      CtkConfig *ctk_config,
                                      CtkEvent *ctk_event,
                                      unsigned int display_device_mask,
                                      char *name)
{
    GObject *object;
    CtkDisplayDeviceDfp *ctk_display_device_dfp;
    GtkWidget *banner;
    GtkWidget *frame;
    GtkWidget *hbox, *vbox, *tmpbox;
    GtkWidget *eventbox;

    GtkWidget *button;
    GtkWidget *radio0;
    GtkWidget *radio1;
    GtkWidget *radio2;
    GtkWidget *alignment;
    
    GtkWidget *table;
    ReturnStatus ret1, ret2;
    gint val_target, val_method;

    object = g_object_new(CTK_TYPE_DISPLAY_DEVICE_DFP, NULL);
    if (!object) return NULL;

    ctk_display_device_dfp = CTK_DISPLAY_DEVICE_DFP(object);
    ctk_display_device_dfp->handle = handle;
    ctk_display_device_dfp->ctk_event = ctk_event;
    ctk_display_device_dfp->ctk_config = ctk_config;
    ctk_display_device_dfp->display_device_mask = display_device_mask;
    ctk_display_device_dfp->name = g_strdup(name);

    /* cache the default scaling target & method values */
    ret1 =
        NvCtrlGetDisplayAttribute(ctk_display_device_dfp->handle,
                                  ctk_display_device_dfp->display_device_mask,
                                  NV_CTRL_GPU_SCALING_DEFAULT_TARGET,
                                  &val_target);
    ret2 =
        NvCtrlGetDisplayAttribute(ctk_display_device_dfp->handle,
                                  ctk_display_device_dfp->display_device_mask,
                                  NV_CTRL_GPU_SCALING_DEFAULT_METHOD,
                                  &val_method);

    if (ret1 != NvCtrlSuccess || ret2 != NvCtrlSuccess ||
        val_target == NV_CTRL_GPU_SCALING_TARGET_INVALID ||
        val_method == NV_CTRL_GPU_SCALING_METHOD_INVALID) {
        val_target = NV_CTRL_GPU_SCALING_TARGET_FLATPANEL_BEST_FIT;
        val_method = NV_CTRL_GPU_SCALING_METHOD_STRETCHED;
    }

    ctk_display_device_dfp->default_scaling_target = val_target;
    ctk_display_device_dfp->default_scaling_method = val_method;

    gtk_box_set_spacing(GTK_BOX(object), 10);

    /* banner */

    banner = ctk_banner_image_new(BANNER_ARTWORK_DFP);
    gtk_box_pack_start(GTK_BOX(object), banner, FALSE, FALSE, 0);
    
    /*
     * create the reset button (which we need while creating the
     * controls in this page so that we can set the button's
     * sensitivity), though we pack it at the bottom of the page
     */

    ctk_display_device_dfp->reset_button =
        gtk_button_new_with_label("Reset Hardware Defaults");

    alignment = gtk_alignment_new(1, 1, 0, 0);
    gtk_container_add(GTK_CONTAINER(alignment),
                      ctk_display_device_dfp->reset_button);
    gtk_box_pack_end(GTK_BOX(object), alignment, TRUE, TRUE, 0);

    g_signal_connect(G_OBJECT(ctk_display_device_dfp->reset_button),
                     "clicked", G_CALLBACK(reset_button_clicked),
                     (gpointer) ctk_display_device_dfp);
    
    ctk_config_set_tooltip(ctk_config, ctk_display_device_dfp->reset_button,
                           "The Reset Hardware Defaults button restores "
                           "the DFP settings to their default values.");

    /* create the hbox to store dfp info, scaling */

    hbox = gtk_hbox_new(FALSE, FRAME_PADDING);
    gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, FRAME_PADDING);

    /* DFP info */

    frame = gtk_frame_new("Flat Panel Information");
    gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, FALSE, 0);
    
    /*
     * 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, 5);
    gtk_container_add(GTK_CONTAINER(frame), tmpbox);
    
    /* Make the txt widgets that will get updated */
    ctk_display_device_dfp->txt_chip_location = gtk_label_new("");
    ctk_display_device_dfp->txt_link = gtk_label_new("");
    ctk_display_device_dfp->txt_signal = gtk_label_new("");
    ctk_display_device_dfp->txt_native_resolution = gtk_label_new("");
    ctk_display_device_dfp->txt_best_fit_resolution = gtk_label_new("");
    ctk_display_device_dfp->txt_frontend_resolution = gtk_label_new("");
    ctk_display_device_dfp->txt_backend_resolution = gtk_label_new("");
    ctk_display_device_dfp->txt_refresh_rate = gtk_label_new("");

    /* Add information widget lines */
    {
        typedef struct {
            GtkWidget *label;
            GtkWidget *txt;
            const gchar *tooltip;
        } TextLineInfo;

        TextLineInfo lines[] = {
            {
                gtk_label_new("Chip location:"),
                ctk_display_device_dfp->txt_chip_location,
                NULL
            },
            {
                gtk_label_new("Connection link:"),
                ctk_display_device_dfp->txt_link,
                NULL
            },
            {
                gtk_label_new("Signal:"),
                ctk_display_device_dfp->txt_signal,
                NULL
            },
            {
                gtk_label_new("Native Resolution:"),
                ctk_display_device_dfp->txt_native_resolution,
                __native_res_help,
            },
            {
                gtk_label_new("Best Fit Resolution:"),
                ctk_display_device_dfp->txt_best_fit_resolution,
                __best_fit_res_help,
            },
            {
                gtk_label_new("Frontend Resolution:"),
                ctk_display_device_dfp->txt_frontend_resolution,
                __frontend_res_help,
            },
            {
                gtk_label_new("Backend Resolution:"),
                ctk_display_device_dfp->txt_backend_resolution,
                __backend_res_help,
            },
            {
                gtk_label_new("Refresh Rate:"),
                ctk_display_device_dfp->txt_refresh_rate,
                __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 == 3 || i == 5 || i == 7) {
                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);
            }
        }
    }

    
    /* Flat Panel Scaling */
    
    frame = gtk_frame_new("Flat Panel Scaling");
    eventbox = gtk_event_box_new();
    gtk_container_add(GTK_CONTAINER(eventbox), frame);
    gtk_box_pack_start(GTK_BOX(hbox), eventbox, FALSE, FALSE, 0);
    ctk_display_device_dfp->scaling_frame = eventbox;
    
    ctk_config_set_tooltip(ctk_config, eventbox, __scaling_help);

    vbox = gtk_vbox_new(FALSE, FRAME_PADDING);
    gtk_container_set_border_width(GTK_CONTAINER(vbox), FRAME_PADDING);
    gtk_container_add(GTK_CONTAINER(frame), vbox);

    button = gtk_check_button_new_with_label("Force Full GPU Scaling");
    ctk_display_device_dfp->scaling_gpu_button = button;
    ctk_config_set_tooltip(ctk_config, button, __force_gpu_scaling_help);

    gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);

    table = gtk_table_new(1, 2, FALSE);
    gtk_table_set_row_spacings(GTK_TABLE(table), 6);
    gtk_table_set_col_spacings(GTK_TABLE(table), 15);
    
    gtk_container_set_border_width(GTK_CONTAINER(table), 5);
    
    ctk_display_device_dfp->txt_scaling = 
        add_table_row(table, 0,
                      0, 0.5, "Scaling:",
                      0, 0.5,  "");

    gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);

    frame = gtk_frame_new("GPU Scaling Method");
    gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
    vbox = gtk_vbox_new(FALSE, FRAME_PADDING);
    gtk_container_set_border_width(GTK_CONTAINER(vbox), FRAME_PADDING);
    gtk_container_add(GTK_CONTAINER(frame), vbox);

    g_signal_connect(G_OBJECT(button), "toggled",
                     G_CALLBACK(dfp_scaling_changed),
                     (gpointer) ctk_display_device_dfp);
    
    radio0 = make_scaling_radio_button
        (ctk_display_device_dfp, vbox, NULL, "Stretched",
         NV_CTRL_GPU_SCALING_METHOD_STRETCHED);
    
    radio1 = make_scaling_radio_button
        (ctk_display_device_dfp, vbox, radio0, "Centered",
         NV_CTRL_GPU_SCALING_METHOD_CENTERED);
    
    radio2 = make_scaling_radio_button
        (ctk_display_device_dfp, vbox, radio1, "Aspect Ratio Scaled",
         NV_CTRL_GPU_SCALING_METHOD_ASPECT_SCALED);
    
    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_GPU_SCALING),
                     G_CALLBACK(dfp_update_received),
                     (gpointer) ctk_display_device_dfp);

    /* pack the color controls */

    ctk_display_device_dfp->color_controls =
        ctk_color_controls_new(handle, ctk_config, ctk_event,
                                   ctk_display_device_dfp->reset_button,
                                   display_device_mask, name);

    if (ctk_display_device_dfp->color_controls) {
        gtk_box_pack_start(GTK_BOX(object),
                           ctk_display_device_dfp->color_controls,
                           FALSE, FALSE, 0);
    }

    /* pack the dithering controls */

    ctk_display_device_dfp->dithering_controls =
        ctk_dithering_controls_new(handle, ctk_config, ctk_event,
                                   ctk_display_device_dfp->reset_button,
                                   display_device_mask, name);

    if (ctk_display_device_dfp->dithering_controls) {
        gtk_box_pack_start(GTK_BOX(object),
                           ctk_display_device_dfp->dithering_controls,
                           FALSE, FALSE, 0);
    }

    /* pack the image sliders */
    
    ctk_display_device_dfp->image_sliders =
        ctk_image_sliders_new(handle, ctk_config, ctk_event,
                              ctk_display_device_dfp->reset_button,
                              display_device_mask, name);
    if (ctk_display_device_dfp->image_sliders) {
        gtk_box_pack_start(GTK_BOX(object),
                           ctk_display_device_dfp->image_sliders,
                           FALSE, FALSE, 0);
    }

    /* pack the EDID button */

    hbox = gtk_hbox_new(FALSE, 0);
    gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, 0);
    ctk_display_device_dfp->edid_box = hbox;
    
    /* show the page */

    gtk_widget_show_all(GTK_WIDGET(object));

    /* Update the GUI */

    update_display_enabled_flag(ctk_display_device_dfp->handle,
                                &ctk_display_device_dfp->display_enabled,
                                ctk_display_device_dfp->display_device_mask);

    ctk_display_device_dfp_setup(ctk_display_device_dfp);
    
    /* 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_dfp);

    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_GPU_SCALING_ACTIVE),
                     G_CALLBACK(info_update_received),
                     (gpointer) ctk_display_device_dfp);

    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_DFP_SCALING_ACTIVE),
                     G_CALLBACK(info_update_received),
                     (gpointer) ctk_display_device_dfp);

    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_FRONTEND_RESOLUTION),
                     G_CALLBACK(info_update_received),
                     (gpointer) ctk_display_device_dfp);

    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_FLATPANEL_BEST_FIT_RESOLUTION),
                     G_CALLBACK(info_update_received),
                     (gpointer) ctk_display_device_dfp);

    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_BACKEND_RESOLUTION),
                     G_CALLBACK(info_update_received),
                     (gpointer) ctk_display_device_dfp);
    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_REFRESH_RATE),
                     G_CALLBACK(info_update_received),
                     (gpointer) ctk_display_device_dfp);

    return GTK_WIDGET(object);

} /* ctk_display_device_dfp_new() */
Example #15
0
/*****
 *
 * Main CTK widget creation.
 *
 */
GtkWidget* ctk_clocks_new(NvCtrlAttributeHandle *handle,
                          CtkConfig *ctk_config,
                          CtkEvent *ctk_event)
{
    GObject *object;
    CtkClocks *ctk_object;
    GtkObject *adjustment;
    GtkWidget *alignment;
    GtkWidget *scale;
    CtkDropDownMenu *menu;

    GtkWidget *label;   

    GtkWidget *frame;
    GtkWidget *banner;
    GtkWidget *hbox;
    GtkWidget *vbox;


    ReturnStatus ret;  /* NvCtrlxxx function return value */
    int value, i = 0;
    int clocks_2D;
    NVCTRLAttributeValidValuesRec ranges_2D;
    NVCTRLAttributeValidValuesRec range_detection;
    int clocks_3D;
    NVCTRLAttributeValidValuesRec ranges_3D;

    Bool overclocking_enabled;
    Bool auto_detection_available = FALSE;
    Bool probing_optimal = FALSE;
    Bool can_access_2d_clocks;
    Bool can_access_3d_clocks;
   

    /* Make sure we have a handle */

    g_return_val_if_fail(handle != NULL, NULL);

    /* If we can't query the overclocking state, don't load the page */

    ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_OVERCLOCKING_STATE,
                             &value);
    if ( ret != NvCtrlSuccess )
        return NULL;
    overclocking_enabled =
        (value==NV_CTRL_GPU_OVERCLOCKING_STATE_MANUAL)?True:False;
   
    /* Check if overclocking is busy */
    
    if ( overclocking_enabled ) {
        ret = NvCtrlGetValidAttributeValues(handle,
                                 NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION,
                                 &range_detection);
        if ( ret == NvCtrlSuccess ) {
            ret = NvCtrlGetAttribute(handle,
                                     NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION_STATE,
                                     &value);
            if ( ret != NvCtrlSuccess )
                return NULL;
            probing_optimal =
                (value == NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION_STATE_BUSY);
            auto_detection_available = TRUE;
        }
    }

    /* Can we access the 2D clocks? */

    can_access_2d_clocks = True;
    ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_2D_CLOCK_FREQS, &clocks_2D);
    if ( ret != NvCtrlSuccess )
        can_access_2d_clocks = False;
    ret = NvCtrlGetValidAttributeValues(handle, NV_CTRL_GPU_2D_CLOCK_FREQS,
                                        &ranges_2D);
    if ( ret != NvCtrlSuccess )
        can_access_2d_clocks = False;

    /* Can we access the 3D clocks? */

    can_access_3d_clocks = True;
    ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_3D_CLOCK_FREQS, &clocks_3D);
    if ( ret != NvCtrlSuccess )
        can_access_3d_clocks = False;
    ret = NvCtrlGetValidAttributeValues(handle, NV_CTRL_GPU_3D_CLOCK_FREQS,
                                        &ranges_3D);
    if ( ret != NvCtrlSuccess )
        can_access_3d_clocks = False;

    /* If we can't access either of the clocks, don't load the page */

    if ( !can_access_2d_clocks && !can_access_3d_clocks )
        return NULL;

    /* Create the ctk object */

    object = g_object_new(CTK_TYPE_CLOCKS, NULL);
    ctk_object = CTK_CLOCKS(object);

    /* Cache the handle and configuration */

    ctk_object->handle               = handle;
    ctk_object->ctk_config           = ctk_config;
    ctk_object->overclocking_enabled = overclocking_enabled;
    ctk_object->auto_detection_available  = auto_detection_available;
    ctk_object->probing_optimal      = probing_optimal;

    /* Create the Clock menu widget */

    menu = (CtkDropDownMenu *)
        ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
    i = 0;
        
    if ( can_access_2d_clocks ) {
            ctk_drop_down_menu_append_item(menu, "2D Clock Frequencies", i++);
    }

    if ( can_access_3d_clocks ) {
            ctk_drop_down_menu_append_item(menu, "3D Clock Frequencies", i++);
    }
    
    ctk_object->clock_menu = GTK_WIDGET(menu);

    g_signal_connect(G_OBJECT(ctk_object->clock_menu), "changed",
                     G_CALLBACK(clock_menu_changed),
                     (gpointer) ctk_object);
    
    ctk_config_set_tooltip(ctk_config, ctk_object->clock_menu,
                           __clock_menu_help);

    gtk_widget_set_sensitive(ctk_object->clock_menu,
                             overclocking_enabled && !probing_optimal);
    
    /* Create the Graphics clock frequency slider widget */

    if ( can_access_2d_clocks ) {
        adjustment =
            gtk_adjustment_new(GET_GPU_CLOCK(clocks_2D),
                               GET_GPU_CLOCK(ranges_2D.u.range.min),
                               GET_GPU_CLOCK(ranges_2D.u.range.max),
                               1, 5, 0.0);
        ctk_object->clocks_being_modified = CLOCKS_2D;
    } else {
        adjustment =
            gtk_adjustment_new(GET_GPU_CLOCK(clocks_3D),
                               GET_GPU_CLOCK(ranges_3D.u.range.min),
                               GET_GPU_CLOCK(ranges_3D.u.range.max),
                               1, 5, 0.0);
        ctk_object->clocks_being_modified = CLOCKS_3D;
    }

    scale = ctk_scale_new(GTK_ADJUSTMENT(adjustment), "GPU (MHz)",
                          ctk_config, G_TYPE_INT);
    ctk_object->gpu_clk_scale = scale;
    
    g_signal_connect(adjustment, "value_changed",
                     G_CALLBACK(adjustment_value_changed),
                     (gpointer) ctk_object);

    ctk_config_set_tooltip(ctk_config,
                           CTK_SCALE(ctk_object->gpu_clk_scale)->gtk_scale,
                           __graphics_clock_help);

    gtk_widget_set_sensitive(ctk_object->gpu_clk_scale,
                             overclocking_enabled && !probing_optimal);

    /* Create the Memory clock frequency slider widget */
    
    if ( can_access_2d_clocks ) {
        adjustment =
            gtk_adjustment_new(GET_MEM_CLOCK(clocks_2D),
                               GET_MEM_CLOCK(ranges_2D.u.range.min),
                               GET_MEM_CLOCK(ranges_2D.u.range.max),
                               1, 5, 0.0);
    } else {
        adjustment =
            gtk_adjustment_new(GET_MEM_CLOCK(clocks_3D),
                               GET_MEM_CLOCK(ranges_3D.u.range.min),
                               GET_MEM_CLOCK(ranges_3D.u.range.max),
                               1, 5, 0.0);
    }

    scale = ctk_scale_new(GTK_ADJUSTMENT(adjustment), "Memory (MHz)",
                          ctk_config, G_TYPE_INT);
    ctk_object->mem_clk_scale = scale;
    
    g_signal_connect(adjustment, "value_changed",
                     G_CALLBACK(adjustment_value_changed),
                     (gpointer) ctk_object);
    
    ctk_config_set_tooltip(ctk_config,
                           CTK_SCALE(ctk_object->mem_clk_scale)->gtk_scale,
                           __mem_clock_help);

    gtk_widget_set_sensitive(ctk_object->mem_clk_scale,
                             overclocking_enabled && !probing_optimal);

    /* Create the Enable Overclocking checkbox widget */

    ctk_object->enable_checkbox =
        gtk_check_button_new_with_label("Enable Overclocking");

    gtk_toggle_button_set_active
        (GTK_TOGGLE_BUTTON(ctk_object->enable_checkbox),
         overclocking_enabled);

    gtk_widget_set_sensitive(ctk_object->enable_checkbox,
                             overclocking_enabled && !probing_optimal);

    g_signal_connect(G_OBJECT(ctk_object->enable_checkbox), "toggled",
                     G_CALLBACK(overclocking_state_toggled),
                     (gpointer) ctk_object);

    ctk_config_set_tooltip(ctk_config, ctk_object->enable_checkbox,
                           __enable_button_help);
    
    gtk_widget_set_sensitive(ctk_object->enable_checkbox, !probing_optimal);

    /* Create the Apply button widget */

    ctk_object->apply_button =
        gtk_button_new_with_label("Apply");

    g_signal_connect(G_OBJECT(ctk_object->apply_button), "clicked",
                     G_CALLBACK(apply_clocks_clicked),
                     (gpointer) ctk_object);
    
    ctk_config_set_tooltip(ctk_config, ctk_object->apply_button,
                           __apply_button_help);

    gtk_widget_set_sensitive(ctk_object->apply_button, False);
    
    /* Create the Auto Detect button widget */

    ctk_object->detect_button =
        gtk_button_new_with_label("Auto Detect");

    g_signal_connect(G_OBJECT(ctk_object->detect_button), "clicked",
                     G_CALLBACK(detect_clocks_clicked),
                     (gpointer) ctk_object);
    
    ctk_config_set_tooltip(ctk_config, ctk_object->detect_button,
                           __detect_button_help);
    
    if ( ctk_object->clocks_being_modified == CLOCKS_2D ) {
        gtk_widget_set_sensitive(ctk_object->detect_button, False);
    } else {
        gtk_widget_set_sensitive(ctk_object->detect_button,
                                 overclocking_enabled &&
                                 auto_detection_available && !probing_optimal);
    }

    /* Create the Reset hardware button widget */

    ctk_object->reset_button =
        gtk_button_new_with_label("Reset Hardware Defaults");

    g_signal_connect(G_OBJECT(ctk_object->reset_button), "clicked",
                     G_CALLBACK(reset_clocks_clicked),
                     (gpointer) ctk_object);
    
    ctk_config_set_tooltip(ctk_config, ctk_object->reset_button,
                           __reset_button_help);

    gtk_widget_set_sensitive(ctk_object->reset_button, False);

    /* Create the auto detect dialog */

    ctk_object->detect_dialog =
        gtk_dialog_new_with_buttons("Auto Detect Optimal 3D Clock Frequencies?",
                                    GTK_WINDOW(gtk_widget_get_parent(GTK_WIDGET(ctk_object))),
                                    GTK_DIALOG_MODAL |  GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
                                    GTK_STOCK_OK,
                                    GTK_RESPONSE_ACCEPT,
                                    GTK_STOCK_CANCEL,
                                    GTK_RESPONSE_REJECT,
                                    NULL
                                    );
    
    label = gtk_label_new(__detect_confirm_msg);
    hbox = gtk_hbox_new(TRUE, 15);

    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 15);

    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(ctk_object->detect_dialog)->vbox),
                       hbox, FALSE, FALSE, 15);

    /*
     * Now that we've created all the widgets we care about, we're
     * ready to compose the panel
     */

    /* Set container properties of the ctk object */

    gtk_box_set_spacing(GTK_BOX(ctk_object), 10);

    banner = ctk_banner_image_new(BANNER_ARTWORK_CLOCK);
    gtk_box_pack_start(GTK_BOX(object), banner, FALSE, FALSE, 0);

    /* Add Overclocking checkbox */

    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_object->enable_checkbox,
                       FALSE, FALSE, 0);

    /* Add Clock frequency frame */

    frame = gtk_frame_new("Clock Frequencies");
    vbox = gtk_vbox_new(FALSE, 0);
    hbox = gtk_hbox_new(FALSE, 0);
            
    gtk_container_set_border_width(GTK_CONTAINER(vbox), FRAME_PADDING);
    
    gtk_box_pack_start(GTK_BOX(object), frame, FALSE, FALSE, 0);
    gtk_container_add(GTK_CONTAINER(frame), vbox);
            
    
    gtk_box_pack_start(GTK_BOX(hbox), ctk_object->clock_menu,
                       FALSE, FALSE, 0);
    
    gtk_box_pack_start(GTK_BOX(vbox), hbox,
                       FALSE, FALSE, 5);

    gtk_box_pack_start(GTK_BOX(vbox), ctk_object->gpu_clk_scale,
                       FALSE, FALSE, 5);
            
    gtk_box_pack_start(GTK_BOX(vbox), ctk_object->mem_clk_scale,
                       FALSE, FALSE, 5);                
        
    /* Add the Apply, Auto Detect, and Reset buttons */

    hbox = gtk_hbox_new(FALSE, 5);

    gtk_box_pack_start(GTK_BOX(hbox), ctk_object->apply_button,
                       FALSE, FALSE, 0);
    gtk_container_add(GTK_CONTAINER(hbox), ctk_object->detect_button);
    gtk_container_add(GTK_CONTAINER(hbox), ctk_object->reset_button);
        
    alignment = gtk_alignment_new(1, 1, 0, 0);
    gtk_container_add(GTK_CONTAINER(alignment), hbox);
    gtk_box_pack_start(GTK_BOX(object), alignment, TRUE, TRUE, 0);

    /* Setup the initial gui state */
    
    sync_gui_to_modify_clocks(ctk_object, ctk_object->clocks_being_modified);
    
    /* Handle events from other NV-CONTROL clients */
    
    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_GPU_OVERCLOCKING_STATE),
                     G_CALLBACK(overclocking_state_received),
                     (gpointer) ctk_object);
    
    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_GPU_2D_CLOCK_FREQS),
                     G_CALLBACK(clocks_received),
                     (gpointer) ctk_object);
    
    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_GPU_3D_CLOCK_FREQS),
                     G_CALLBACK(clocks_received),
                     (gpointer) ctk_object);
    
    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS),
                     G_CALLBACK(clocks_received),
                     (gpointer) ctk_object);

    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION_STATE),
                     G_CALLBACK(auto_detection_state_received),
                     (gpointer) ctk_object);

    /* Show the widget */

    gtk_widget_show_all(GTK_WIDGET(ctk_object));

    return GTK_WIDGET(ctk_object);

} /* ctk_clocks_new() */
Example #16
0
void ctk_drop_down_menu_set_tooltip(CtkConfig *ctk_config, CtkDropDownMenu *d,
                                    const gchar *text)
{
    ctk_config_set_tooltip(ctk_config, GTK_WIDGET(d->combo_box), text);
}
Example #17
0
static GtkWidget *create_slider(CtkXVideo *ctk_xvideo,
                                GtkWidget *vbox,
                                GtkWidget *button,
                                const gchar *name,
                                const char *help,
                                gint attribute,
                                unsigned int bit)
{
    GtkObject *adjustment;
    GtkWidget *scale, *widget;
    gint min, max, val, step_incr, page_incr;
    NVCTRLAttributeValidValuesRec range;
    ReturnStatus ret;
    
    /* get the attribute value */

    ret = NvCtrlGetAttribute(ctk_xvideo->handle, attribute, &val);
    
    if (ret != NvCtrlSuccess) return NULL;
    
    /* get the range for the attribute */

    NvCtrlGetValidAttributeValues(ctk_xvideo->handle, attribute, &range);

    if (range.type != ATTRIBUTE_TYPE_RANGE) return NULL;
    
    min = range.u.range.min;
    max = range.u.range.max;

    step_incr = ((max) - (min))/250;
    if (step_incr <= 0) step_incr = 1;
    
    page_incr = ((max) - (min))/25;
    if (page_incr <= 0) page_incr = 1;

    /* create the slider */
    
    adjustment = gtk_adjustment_new(val, min, max,
                                    step_incr, page_incr, 0.0);

    g_object_set_data(G_OBJECT(adjustment), "xvideo_attribute",
                      GINT_TO_POINTER(attribute));

    g_signal_connect(G_OBJECT(adjustment), "value_changed",
                     G_CALLBACK(slider_changed),
                     (gpointer) ctk_xvideo);

    g_signal_connect_swapped(G_OBJECT(adjustment), "value_changed",
                             G_CALLBACK(set_button_sensitive),
                             (gpointer) button);

    scale = ctk_scale_new(GTK_ADJUSTMENT(adjustment), name,
                          ctk_xvideo->ctk_config, G_TYPE_INT);

    gtk_box_pack_start(GTK_BOX(vbox), scale, TRUE, TRUE, 0);

    ctk_xvideo->active_attributes |= bit;

    widget = CTK_SCALE(scale)->gtk_scale;
    
    ctk_config_set_tooltip(ctk_xvideo->ctk_config, widget, help);

    return scale;
    
} /* create_slider() */
Example #18
0
GtkWidget* ctk_xvideo_new(NvCtrlAttributeHandle *handle,
                          CtkConfig *ctk_config,
                          CtkEvent *ctk_event)
{
    GObject *object;
    CtkXVideo *ctk_xvideo;
    GtkWidget *banner;
    GtkWidget *frame;
    GtkWidget *alignment;
    GtkWidget *hbox;
    GtkWidget *label;
    GtkWidget *vbox;
    GtkWidget *button;
    int sync_mask;
    int xv_overlay_present, xv_texture_present, xv_blitter_present;
    ReturnStatus ret;

    /*
     * before we do anything else, determine if any of the Xv adapters
     * are present
     */
    
    ret = NvCtrlGetAttribute(handle, NV_CTRL_ATTR_EXT_XV_OVERLAY_PRESENT,
                             &xv_overlay_present);
    
    if (ret != NvCtrlSuccess) xv_overlay_present = FALSE;
    
    ret = NvCtrlGetAttribute(handle, NV_CTRL_ATTR_EXT_XV_TEXTURE_PRESENT,
                             &xv_texture_present);

    if (ret != NvCtrlSuccess) xv_texture_present = FALSE;
    
    ret = NvCtrlGetAttribute(handle, NV_CTRL_ATTR_EXT_XV_BLITTER_PRESENT,
                             &xv_blitter_present);
    
    if (ret != NvCtrlSuccess) xv_blitter_present = FALSE;
    
    if (!xv_overlay_present && !xv_texture_present && !xv_blitter_present) {
        return NULL;
    }
    
    
    /* create the XVideo widget */
    
    object = g_object_new(CTK_TYPE_XVIDEO, NULL);
    ctk_xvideo = CTK_XVIDEO(object);
    
    ctk_xvideo->handle = handle;
    ctk_xvideo->ctk_config = ctk_config;
    ctk_xvideo->active_attributes = 0;
    
    gtk_box_set_spacing(GTK_BOX(ctk_xvideo), 10);
    
    
    /* Create button, but don't pack it, yet */

    label = gtk_label_new("Reset Hardware Defaults");
    hbox = gtk_hbox_new(FALSE, 0);
    button = gtk_button_new();

    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 15);
    gtk_container_add(GTK_CONTAINER(button), hbox);
    
    g_signal_connect(G_OBJECT(button), "clicked",
                     G_CALLBACK(reset_defaults), (gpointer) ctk_xvideo);
    
    ctk_config_set_tooltip(ctk_config, button, __reset_button_help);
    
    /* Video film banner */
    
    banner = ctk_banner_image_new(BANNER_ARTWORK_XVIDEO);
    gtk_box_pack_start(GTK_BOX(object), banner, FALSE, FALSE, 0);

    
    /* XVideo Overlay sliders */
    
    if (xv_overlay_present) {
        
        frame = gtk_frame_new("Video Overlay Adaptor");
        gtk_box_pack_start(GTK_BOX(object), frame, FALSE, FALSE, 0);
        
        vbox = gtk_vbox_new(FALSE, 5);
        gtk_container_set_border_width(GTK_CONTAINER(vbox), FRAME_PADDING);
        gtk_container_add(GTK_CONTAINER(frame), vbox);
        
        ctk_xvideo->overlay_saturation =
            create_slider(ctk_xvideo, vbox, button, "Saturation",
                          __xv_overlay_saturation_help,
                          NV_CTRL_ATTR_XV_OVERLAY_SATURATION,
                          __XV_OVERLAY_SATURATION);
        
        ctk_xvideo->overlay_contrast =
            create_slider(ctk_xvideo, vbox, button, "Contrast",
                          __xv_overlay_contrast_help,
                          NV_CTRL_ATTR_XV_OVERLAY_CONTRAST,
                          __XV_OVERLAY_CONTRAST);
        
        ctk_xvideo->overlay_brightness =
            create_slider(ctk_xvideo, vbox, button, "Brightness",
                          __xv_overlay_brightness_help,
                          NV_CTRL_ATTR_XV_OVERLAY_BRIGHTNESS,
                          __XV_OVERLAY_BRIGHTNESS);
        
        ctk_xvideo->overlay_hue =
            create_slider(ctk_xvideo, vbox, button, "Hue",
                          __xv_overlay_hue_help,
                          NV_CTRL_ATTR_XV_OVERLAY_HUE,
                          __XV_OVERLAY_HUE);
    }

    /* XVideo Texture */

    if (xv_texture_present) {
        
        frame = gtk_frame_new("Video Texture Adaptor");
        gtk_box_pack_start(GTK_BOX(object), frame, FALSE, FALSE, 0);
        
        vbox = gtk_vbox_new(FALSE, 5);
        gtk_container_set_border_width(GTK_CONTAINER(vbox), FRAME_PADDING);
        gtk_container_add(GTK_CONTAINER(frame), vbox);
        
        ctk_xvideo->texture_sync_to_blank =
            create_check_button(ctk_xvideo, vbox, button, "Sync to VBlank",
                                __xv_texture_sync_to_vblank_help,
                                NV_CTRL_ATTR_XV_TEXTURE_SYNC_TO_VBLANK,
                                __XV_TEXTURE_SYNC_TO_VBLANK);
        
        ctk_xvideo->texture_brightness =
            create_slider(ctk_xvideo, vbox, button, "Brightness",
                          __xv_texture_brightness_help,
                          NV_CTRL_ATTR_XV_TEXTURE_BRIGHTNESS,
                          __XV_TEXTURE_BRIGHTNESS);
        
        ctk_xvideo->texture_contrast =
            create_slider(ctk_xvideo, vbox, button, "Contrast",
                          __xv_texture_contrast_help,
                          NV_CTRL_ATTR_XV_TEXTURE_CONTRAST,
                          __XV_TEXTURE_CONTRAST);

        ctk_xvideo->texture_hue =
            create_slider(ctk_xvideo, vbox, button, "Hue",
                          __xv_texture_hue_help,
                          NV_CTRL_ATTR_XV_TEXTURE_HUE,
                          __XV_TEXTURE_HUE);
        
        ctk_xvideo->texture_saturation =
            create_slider(ctk_xvideo, vbox, button, "Saturation",
                          __xv_texture_saturation_help,
                          NV_CTRL_ATTR_XV_TEXTURE_SATURATION,
                          __XV_TEXTURE_SATURATION);
    
    }
    
    /* XVideo Blitter */

    if (xv_blitter_present) {

        frame = gtk_frame_new("Video Blitter Adaptor Settings");
        gtk_box_pack_start(GTK_BOX(object), frame, FALSE, FALSE, 0);
        
        vbox = gtk_vbox_new(FALSE, 5);
        gtk_container_set_border_width(GTK_CONTAINER(vbox), FRAME_PADDING);
        gtk_container_add(GTK_CONTAINER(frame), vbox);
        
        ctk_xvideo->blitter_sync_to_blank =
            create_check_button(ctk_xvideo,
                                vbox,
                                button,
                                "Sync to VBlank",
                                __xv_blitter_sync_to_vblank_help,
                                NV_CTRL_ATTR_XV_BLITTER_SYNC_TO_VBLANK,
                                __XV_BLITTER_SYNC_TO_VBLANK);

    }

    /* Sync to display selection */
    if (xv_texture_present || xv_blitter_present) {
        ret = NvCtrlGetAttribute(handle,
                                 NV_CTRL_XV_SYNC_TO_DISPLAY,
                                 &sync_mask);
        if (ret == NvCtrlSuccess) {
            int enabled;
            ret = NvCtrlGetAttribute(handle, 
                                     NV_CTRL_ENABLED_DISPLAYS,
                                     &enabled);
            if (ret == NvCtrlSuccess) {

                GtkWidget *radio[24], *prev_radio;
                int i, n, current = -1, mask;
                char *name, *type;
                gchar *name_str;
                frame = gtk_frame_new("Sync to this display device");
                gtk_box_pack_start(GTK_BOX(object), frame, FALSE, FALSE, 0);

                vbox = gtk_vbox_new(FALSE, 5);
                gtk_container_set_border_width(GTK_CONTAINER(vbox), FRAME_PADDING);
                gtk_container_add(GTK_CONTAINER(frame), vbox);
                ctk_xvideo->xv_sync_to_display_button_box = vbox;

                for (n=0, i = 0; i < 24; i++) {

                    mask = 1 << i;
                    if (!(enabled & mask)) continue;

                    /* get the name of the display device */

                    ret = NvCtrlGetStringDisplayAttribute(handle, mask,
                                              NV_CTRL_STRING_DISPLAY_DEVICE_NAME,
                                              &name);

                    if ((ret != NvCtrlSuccess) || (!name)) {
                        name = g_strdup("Unknown");
                    }

                    /* get the display device type */

                    type = display_device_mask_to_display_device_name(mask);

                    name_str = g_strdup_printf("%s (%s)", name, type);
                    XFree(name);
                    free(type);

                    if (n==0) {
                        prev_radio = NULL;
                    } else {
                        prev_radio = radio[n-1];
                    } 
                    radio[n] = xv_sync_to_display_radio_button_add(ctk_xvideo, 
                                                                   prev_radio,
                                                                   name_str,
                                                                   mask, n);
                    g_free(name_str);
                    ctk_config_set_tooltip(ctk_config, radio[n],
                                           __xv_sync_to_display_help);    

                    if (mask == sync_mask) {
                        current = n;
                    }

                    n++;
                    ctk_xvideo->active_attributes |= __XV_SYNC_TO_DISPLAY;
                }

                g_signal_connect(G_OBJECT(ctk_event),
                                 CTK_EVENT_NAME(NV_CTRL_XV_SYNC_TO_DISPLAY),
                                 G_CALLBACK(xv_sync_to_display_update_received),
                                 (gpointer) ctk_xvideo);
                g_signal_connect(G_OBJECT(ctk_event),
                                 CTK_EVENT_NAME(NV_CTRL_ENABLED_DISPLAYS),
                                 G_CALLBACK(nv_ctrl_enabled_displays),
                                 (gpointer) ctk_xvideo);
                sensitize_radio_buttons(ctk_xvideo);

                if (current != -1)
                    xv_sync_to_display_update_radio_buttons(ctk_xvideo, current);

            }
        }
    }
    
    /* Reset button */

    sensitize_radio_buttons(ctk_xvideo);
    alignment = gtk_alignment_new(1, 1, 0, 0);
    gtk_container_add(GTK_CONTAINER(alignment), button);
    gtk_box_pack_start(GTK_BOX(object), alignment, TRUE, TRUE, 0);
    
    /* finally, show the widget */

    gtk_widget_show_all(GTK_WIDGET(ctk_xvideo));

    return GTK_WIDGET(ctk_xvideo);
    
} /* ctk_xvideo_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() */
Example #20
0
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() */
Example #21
0
/*
 * ctk_xvideo_new() - constructor for the XVideo widget
 */
GtkWidget* ctk_xvideo_new(CtrlTarget *ctrl_target,
                          CtkConfig *ctk_config,
                          CtkEvent *ctk_event)
{
    GObject *object;
    CtkXVideo *ctk_xvideo;
    GtkWidget *banner;
    GtkWidget *frame;
    GtkWidget *alignment;
    GtkWidget *vbox;
    GtkWidget *hbox;
    GtkWidget *label;
    GtkWidget *hseparator;
    int xv_overlay_present, xv_texture_present, xv_blitter_present;
    int display_id;
    gboolean show_page;
    ReturnStatus ret;
    gchar *current_sync_name;

    /*
     * before we do anything else, determine if any of the Xv adapters
     * are present
     */

    ret = NvCtrlGetAttribute(ctrl_target, NV_CTRL_ATTR_EXT_XV_OVERLAY_PRESENT,
                             &xv_overlay_present);
    if (ret != NvCtrlSuccess) {
        xv_overlay_present = FALSE;
    }

    ret = NvCtrlGetAttribute(ctrl_target, NV_CTRL_ATTR_EXT_XV_TEXTURE_PRESENT,
                             &xv_texture_present);
    if (ret != NvCtrlSuccess) {
        xv_texture_present = FALSE;
    }

    ret = NvCtrlGetAttribute(ctrl_target, NV_CTRL_ATTR_EXT_XV_BLITTER_PRESENT,
                             &xv_blitter_present);
    if (ret != NvCtrlSuccess) {
        xv_blitter_present = FALSE;
    }

    if (!xv_overlay_present && !xv_texture_present && !xv_blitter_present) {
        return NULL;
    }

    /* If nothing to show, bail */

    show_page = FALSE;
    if (xv_texture_present || xv_blitter_present) {
        ret = NvCtrlGetAttribute(ctrl_target,
                                 NV_CTRL_XV_SYNC_TO_DISPLAY_ID,
                                 &display_id);
        if (ret == NvCtrlSuccess) {
            show_page = TRUE;
        }
    }

    if (!show_page) {
        return NULL;
    }


    /* create the XVideo widget */

    object = g_object_new(CTK_TYPE_XVIDEO, NULL);
    ctk_xvideo = CTK_XVIDEO(object);

    ctk_xvideo->ctrl_target = ctrl_target;
    ctk_xvideo->ctk_config = ctk_config;
    ctk_xvideo->active_attributes = 0;

    gtk_box_set_spacing(GTK_BOX(ctk_xvideo), 10);


    /* Video film banner */

    banner = ctk_banner_image_new(BANNER_ARTWORK_XVIDEO);
    gtk_box_pack_start(GTK_BOX(object), banner, FALSE, FALSE, 0);

    /* Top Label */

    hbox = gtk_hbox_new(FALSE, 5);
    gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, 0);

    label = gtk_label_new("Xvideo Settings");
    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, 0);

    /* Current Sync Value */

    ret = NvCtrlGetAttribute(ctrl_target,
                             NV_CTRL_CURRENT_XV_SYNC_TO_DISPLAY_ID,
                             &display_id);
    if (ret == NvCtrlSuccess) {
        hbox = gtk_hbox_new(FALSE, 5);
        gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, 5);

        label = gtk_label_new("Currently synced to display:");
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
        label = gtk_label_new("");
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);

        current_sync_name = xv_sync_to_display_radio_button_label(ctk_xvideo,
                                                                  display_id);
        gtk_label_set_text(GTK_LABEL(label), current_sync_name);
        g_free(current_sync_name);

        ctk_xvideo->current_xv_sync_to_display_label = label;
    } else {
        ctk_xvideo->current_xv_sync_to_display_label = NULL;
    }

    /* Sync to display selection */

    frame = gtk_frame_new("Sync to this display device");
    gtk_box_pack_start(GTK_BOX(object), frame, FALSE, FALSE, 0);

    vbox = gtk_vbox_new(FALSE, 5);
    gtk_container_set_border_width(GTK_CONTAINER(vbox), FRAME_PADDING);
    gtk_container_add(GTK_CONTAINER(frame), vbox);
    ctk_xvideo->xv_sync_to_display_button_box = vbox;

    ctk_config_set_tooltip(ctk_xvideo->ctk_config,
                           ctk_xvideo->xv_sync_to_display_button_box,
                           __xv_sync_to_display_help);

    xv_sync_to_display_rebuild_buttons(ctk_xvideo, FALSE);

    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_XV_SYNC_TO_DISPLAY_ID),
                     G_CALLBACK(xv_sync_to_display_id_handler),
                     (gpointer) ctk_xvideo);

    if (ctk_xvideo->current_xv_sync_to_display_label) {
        g_signal_connect(G_OBJECT(ctk_event),
                         CTK_EVENT_NAME(NV_CTRL_CURRENT_XV_SYNC_TO_DISPLAY_ID),
                         G_CALLBACK(current_xv_sync_to_display_id_handler),
                         (gpointer) ctk_xvideo);
    }

    g_signal_connect(G_OBJECT(ctk_event),
                     CTK_EVENT_NAME(NV_CTRL_ENABLED_DISPLAYS),
                     G_CALLBACK(enabled_displays_handler),
                     (gpointer) ctk_xvideo);


    alignment = gtk_alignment_new(1, 1, 0, 0);
    gtk_box_pack_start(GTK_BOX(object), alignment, TRUE, TRUE, 0);

    /* finally, show the widget */

    gtk_widget_show_all(GTK_WIDGET(ctk_xvideo));

    return GTK_WIDGET(ctk_xvideo);
}