Esempio n. 1
0
File: cm-dinsig.c Progetto: gpg/gpa
/* This function constructs the container holding all widgets making
   up this data widget.  It is called during instance creation.  */
static void
construct_data_widget (GpaCMDinsig *card)
{
  GtkWidget *frame;
  GtkWidget *table;
  GtkWidget *vbox;
  GtkWidget *label;
  int rowidx;
  char *text;

  /* General frame.  */
  frame = gtk_frame_new (NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
  label = gtk_label_new (_("<b>General</b>"));
  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
  gtk_frame_set_label_widget (GTK_FRAME (frame), label);
  table = gtk_table_new (2, 3, FALSE);
  gtk_container_set_border_width (GTK_CONTAINER (table), 10);
  gtk_container_add (GTK_CONTAINER (frame), table);
  rowidx = 0;

  card->entries[ENTRY_SERIALNO] = gtk_label_new (NULL);
  add_table_row (table, &rowidx, _("Serial number:"),
                 card->entries[ENTRY_SERIALNO], NULL, 0);

  gtk_box_pack_start (GTK_BOX (card), frame, FALSE, TRUE, 0);

  /* Info frame.  */
  frame = gtk_frame_new (NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
  vbox = gtk_vbox_new (FALSE, 5);
  text = g_strdup_printf
    (_("There is not much information to display for a %s card.  "
       "You may want to use the application selector button to "
       "switch to another application available on this card."), "DINSIG");
  label = gtk_label_new (text);
  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
  gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);

  gtk_container_add (GTK_CONTAINER (frame), vbox);
  gtk_box_pack_start (GTK_BOX (card), frame, FALSE, TRUE, 0);

}
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() */
Esempio n. 3
0
/*
 * CTK VCS (Visual Computing System) widget creation
 *
 */
GtkWidget* ctk_vcs_new(NvCtrlAttributeHandle *handle,
                        CtkConfig *ctk_config)
{
    GObject *object;
    CtkVcs *ctk_object;
    GtkWidget *label;
    GtkWidget *vbox;
    GtkWidget *hbox;
    GtkWidget *event;
    GtkWidget *banner;
    GtkWidget *hseparator;
    GtkWidget *table;
    GtkWidget *scrollWin;
    GtkWidget *checkbutton;

    gchar *product_name;
    gchar *serial_number;
    gchar *build_date;
    gchar *product_id;
    gchar *firmware_version;
    gchar *hardware_version;

    gint current_row;
    gboolean high_perf_mode;

    ReturnStatus ret;
    gchar *s;
    char *psu_str = NULL;
    PSUEntry psuEntry;

    GtkWidget *vbox_scroll, *hbox_scroll;

    /*
     * get the static string data that we will display below
     */
    
    /* Product Name */
    ret = NvCtrlGetStringAttribute(handle,
                                   NV_CTRL_STRING_VCSC_PRODUCT_NAME,
                                   &product_name);
    if (ret != NvCtrlSuccess) {
        product_name = g_strdup("Unable to determine");
    }

    /* Serial Number */
    ret = NvCtrlGetStringAttribute(handle,
                                   NV_CTRL_STRING_VCSC_SERIAL_NUMBER,
                                   &serial_number);
    if (ret != NvCtrlSuccess) {
        serial_number = g_strdup("Unable to determine");
    }

    /* Build Date */
    ret = NvCtrlGetStringAttribute(handle,
                                   NV_CTRL_STRING_VCSC_BUILD_DATE,
                                   &build_date);
    if (ret != NvCtrlSuccess) {
        build_date = g_strdup("Unable to determine");
    }

    /* Product ID */
    ret = NvCtrlGetStringAttribute(handle,
                                   NV_CTRL_STRING_VCSC_PRODUCT_ID,
                                   &product_id);
    if (ret != NvCtrlSuccess) {
        product_id = g_strdup("Unable to determine");
    }

    /* Firmware Version */
    ret = NvCtrlGetStringAttribute(handle,
                                   NV_CTRL_STRING_VCSC_FIRMWARE_VERSION,
                                   &firmware_version);
    if (ret != NvCtrlSuccess) {
        firmware_version = g_strdup("Unable to determine");
    }

    /* Hardware Version */
    ret = NvCtrlGetStringAttribute(handle,
                                   NV_CTRL_STRING_VCSC_HARDWARE_VERSION,
                                   &hardware_version);
    if (ret != NvCtrlSuccess) {
        hardware_version = g_strdup("Unable to determine");
    }


    /* now, create the object */
    
    object = g_object_new(CTK_TYPE_VCS, NULL);
    ctk_object = CTK_VCS(object);

    /* cache the attribute handle */

    ctk_object->handle = handle;
    ctk_object->ctk_config = ctk_config;

    /* set container properties of the object */

    gtk_box_set_spacing(GTK_BOX(ctk_object), 10);

    /* banner */

    banner = ctk_banner_image_new(BANNER_ARTWORK_VCS);
    gtk_box_pack_start(GTK_BOX(ctk_object), banner, FALSE, FALSE, 0);

    /*
     * This displays basic System information, including
     * display name, Operating system type and the NVIDIA driver version.
     */

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

    /* General purpose error dialog */
    ctk_object->error_dialog = create_error_dialog(ctk_object);

    if (NvCtrlGetAttribute(ctk_object->handle, NV_CTRL_VCSC_HIGH_PERF_MODE,
                            &high_perf_mode) == NvCtrlSuccess) {

        hbox = gtk_hbox_new(FALSE, 0);
        checkbutton = gtk_check_button_new_with_label("Enable High Performance Mode");
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), high_perf_mode);
        g_signal_connect(G_OBJECT(checkbutton), "toggled", 
                         G_CALLBACK(vcs_perf_checkbox_toggled),
                         (gpointer) ctk_object);
        gtk_box_pack_start(GTK_BOX(hbox), checkbutton, TRUE, TRUE, 0);
        gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); 
    }

    /* Create the Scrolling Window */
    scrollWin = gtk_scrolled_window_new(NULL, NULL);
    hbox_scroll = gtk_hbox_new(FALSE, 0);
    vbox_scroll = gtk_vbox_new(FALSE, 5);
    event = gtk_event_box_new();
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollWin),
                                   GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
    gtk_widget_modify_fg(event, GTK_STATE_NORMAL, &(event->style->text[GTK_STATE_NORMAL]));
    gtk_widget_modify_bg(event, GTK_STATE_NORMAL, &(event->style->base[GTK_STATE_NORMAL]));
    gtk_container_add(GTK_CONTAINER(event), hbox_scroll);
    gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollWin),
                                          event);
    gtk_box_pack_start(GTK_BOX(hbox_scroll), vbox_scroll, TRUE, TRUE, 5);
    gtk_widget_set_size_request(scrollWin, -1, 50);
    gtk_box_pack_start(GTK_BOX(vbox), scrollWin, TRUE, TRUE, 0);

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

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

    table = gtk_table_new(5, 2, FALSE);
    gtk_box_pack_start(GTK_BOX(vbox_scroll), 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);

    add_table_row(table, 0,
                  0, 0.5, "Product Name:", 0, 0.5, product_name);
    add_table_row(table, 1,
                  0, 0.5, "Serial Number:", 0, 0.5, serial_number);
    add_table_row(table, 2,
                  0, 0.5, "Build Date:", 0, 0.5, build_date);
    add_table_row(table, 3,
                  0, 0.5, "Product ID:", 0, 0.5, product_id);
    add_table_row(table, 4,
                  0, 0.5, "Firmware version:", 0, 0.5, firmware_version);
    add_table_row(table, 5,
                  0, 0.5, "Hardware version:", 0, 0.5, hardware_version);

    g_free(product_name);
    g_free(serial_number);
    g_free(build_date);
    g_free(product_id);
    g_free(firmware_version);
    g_free(hardware_version);


    /* Query Canoas 2.0 specific details */
    if ((NvCtrlGetAttribute(ctk_object->handle, NV_CTRL_VCSC_HIGH_PERF_MODE, 
                            &high_perf_mode) == NvCtrlSuccess) && 
        (NvCtrlGetStringAttribute(ctk_object->handle,
                                  NV_CTRL_STRING_VCSC_PSU_INFO,
                                  &psu_str)  == NvCtrlSuccess)) {
        GtkWidget *vbox_padding;

        /* Show the additonal queried information */


        /* Populate scrolling window with data */
        vbox_padding = gtk_vbox_new(FALSE, 0);
        hbox = gtk_hbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(vbox_scroll), vbox_padding, FALSE, FALSE, 1);
        gtk_box_pack_start(GTK_BOX(vbox_scroll), hbox, FALSE, FALSE, 0);
        label = gtk_label_new("VCS Thermal 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);

        table = gtk_table_new(3, 2, FALSE);
        gtk_box_pack_start(GTK_BOX(vbox_scroll), 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);

        label = gtk_label_new("Intake Temperature:");
        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
        gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
                         GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);

        label = gtk_label_new(NULL);
        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
        gtk_table_attach(GTK_TABLE(table), label, 1, 2, 0, 1,
                         GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
        ctk_object->intake_temp = label;

        label = gtk_label_new("Exhaust Temperature:");
        /* This is the current largest label.  Get its size */
        gtk_widget_size_request(label, &ctk_object->req);

        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
        gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
                         GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);

        label = gtk_label_new(NULL);
        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
        gtk_table_attach(GTK_TABLE(table), label, 1, 2, 1, 2,
                         GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
        ctk_object->exhaust_temp = label;

        label = gtk_label_new("Board Temperature:");
        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
        gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3,
                         GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);

        label = gtk_label_new(NULL);
        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
        gtk_table_attach(GTK_TABLE(table), label, 1, 2, 2, 3,
                         GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
        ctk_object->board_temp = label;

        /* Populate table for PSU information */

        psuEntry.psu_current    = -1;
        psuEntry.psu_power      = -1;
        psuEntry.psu_voltage    = -1;
        psuEntry.psu_state      = -1;

        if (psu_str) {
            parse_token_value_pairs(psu_str, apply_psu_entry_token, &psuEntry);
        }

        vbox_padding = gtk_vbox_new(FALSE, 0);
        hbox = gtk_hbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(vbox_scroll), vbox_padding, FALSE, FALSE, 1);
        gtk_box_pack_start(GTK_BOX(vbox_scroll), hbox, FALSE, FALSE, 0);
        label = gtk_label_new("VCS Power Supply Unit 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);

        table = gtk_table_new(4, 2, FALSE);
        gtk_box_pack_start(GTK_BOX(vbox_scroll), 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);

        label = gtk_label_new("PSU State:");
        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
        gtk_widget_set_size_request(label, ctk_object->req.width, -1);
        gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
                         GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);


        label = gtk_label_new(NULL);
        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
        gtk_table_attach(GTK_TABLE(table), label, 1, 2, 0, 1,
                         GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
        ctk_object->psu_state = label;

        label = gtk_label_new("PSU Current:");
        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
        gtk_widget_set_size_request(label, ctk_object->req.width, -1);
        gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
                         GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);


        label = gtk_label_new(NULL);
        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
        gtk_table_attach(GTK_TABLE(table), label, 1, 2, 1, 2,
                         GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
        ctk_object->psu_current = label;

        current_row = 2;

        if (psuEntry.psu_power != -1) {
            label = gtk_label_new("PSU Power:");
            gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
            gtk_widget_set_size_request(label, ctk_object->req.width, -1);
            gtk_table_attach(GTK_TABLE(table), label, 0, 1, 
                             current_row, current_row + 1,
                             GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);

            label = gtk_label_new(NULL);
            gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
            gtk_table_attach(GTK_TABLE(table), label, 1, 2, 
                             current_row, current_row + 1,
                             GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
            ctk_object->psu_power = label;
            current_row++;
        }

        if (psuEntry.psu_voltage != -1) {
            label = gtk_label_new("PSU Voltage:");
            gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
            gtk_widget_set_size_request(label, ctk_object->req.width, -1);
            gtk_table_attach(GTK_TABLE(table), label, 0, 1, 
                             current_row, current_row + 1,
                             GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);

            label = gtk_label_new(NULL);
            gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
            gtk_table_attach(GTK_TABLE(table), label, 1, 2, 
                             current_row, current_row + 1,
                             GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
            ctk_object->psu_voltage = label;
        }

        /* Create container for fan status table */

        vbox_padding = gtk_vbox_new(FALSE, 0);
        hbox = gtk_hbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(vbox_scroll), vbox_padding, FALSE, FALSE, 1);
        gtk_box_pack_start(GTK_BOX(vbox_scroll), hbox, FALSE, FALSE, 0);
        label = gtk_label_new("VCS Fan 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);

        hbox = gtk_hbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(vbox_scroll), hbox, FALSE, FALSE, 0);
        ctk_object->fan_status_container = hbox;

        /* Register a timer callback to update the dynamic information */
        s = g_strdup_printf("VCS Monitor (VCS %d)",
                            NvCtrlGetTargetId(ctk_object->handle));

        ctk_config_add_timer(ctk_object->ctk_config,
                             DEFAULT_UPDATE_VCS_INFO_TIME_INTERVAL,
                             s,
                             (GSourceFunc) update_vcs_info,
                             (gpointer) ctk_object);
        g_free(s);

        update_vcs_info(ctk_object);
    }

    gtk_widget_show_all(GTK_WIDGET(object));
    
    return GTK_WIDGET(object);
}