* nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
* and Linux systems.
*
* Copyright (C) 2004 NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses>.
*/
#include <gtk/gtk.h>
#include "ctkhelp.h"
#include "common-utils.h"
#include "ctkconstants.h"
#include "ctkbanner.h"
#include <stdlib.h>
#include <assert.h>
static GtkTextBuffer *create_default_help(CtkHelp *ctk_help);
static void close_button_clicked(GtkButton *button, gpointer user_data);
static gboolean window_destroy(GtkWidget *widget, GdkEvent *event,
gpointer user_data);
GType ctk_help_get_type(
void
)
{
static GType ctk_help_type = 0;
if (!ctk_help_type) {
static const GTypeInfo ctk_help_info = {
sizeof (CtkHelpClass),
NULL,
NULL,
NULL,
NULL,
NULL,
sizeof (CtkHelp),
0,
NULL,
NULL
};
ctk_help_type = g_type_register_static
(GTK_TYPE_WINDOW, "CtkHelp", &ctk_help_info, 0);
}
return ctk_help_type;
}
GtkWidget* ctk_help_new(GtkWidget *toggle_button, GtkTextTagTable *tag_table)
{
GObject *object;
CtkHelp *ctk_help;
GtkWidget *vbox, *hbox;
GtkWidget *hseparator;
GtkWidget *alignment;
GtkWidget *button;
GtkWidget *sw;
GtkWidget *banner;
GtkWidget *frame;
GtkWidget *textview;
object = g_object_new(CTK_TYPE_HELP, NULL);
ctk_help = CTK_HELP(object);
ctk_help->toggle_button = toggle_button;
gtk_window_set_title(GTK_WINDOW(ctk_help),
"NVIDIA Settings Help");
gtk_window_set_default_size(GTK_WINDOW(ctk_help), -1, 400);
gtk_container_set_border_width(GTK_CONTAINER(ctk_help), CTK_WINDOW_PAD);
vbox = gtk_vbox_new(FALSE, 5);
gtk_container_add(GTK_CONTAINER(ctk_help), vbox);
hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
banner = ctk_banner_image_new(BANNER_ARTWORK_HELP);
gtk_box_pack_start(GTK_BOX(hbox), banner, TRUE, TRUE, 0);
frame = gtk_frame_new(NULL);
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
sw = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
gtk_container_add(GTK_CONTAINER(frame), sw);
textview = gtk_text_view_new();
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview), FALSE);
gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), FALSE);
ctk_help->text_viewer = textview;
gtk_container_add(GTK_CONTAINER(sw), ctk_help->text_viewer);
g_object_set(G_OBJECT(ctk_help->text_viewer),
"pixels-inside-wrap", 10, NULL);
ctk_help->tag_table = tag_table;
ctk_help->default_help = create_default_help(ctk_help);
gtk_text_view_set_buffer
(GTK_TEXT_VIEW(ctk_help->text_viewer), ctk_help->default_help);
hseparator = gtk_hseparator_new();
gtk_box_pack_start(GTK_BOX(vbox), hseparator, FALSE, FALSE, 0);
hbox = gtk_hbox_new(FALSE, 5);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
alignment = gtk_alignment_new(1, 1, 0, 0);
gtk_container_add(GTK_CONTAINER(alignment), button);
gtk_box_pack_start(GTK_BOX(hbox), alignment, TRUE, TRUE, 0);
g_signal_connect(G_OBJECT(button), "clicked",
G_CALLBACK(close_button_clicked),
(gpointer) ctk_help);
g_signal_connect(G_OBJECT(ctk_help), "destroy-event",
G_CALLBACK(window_destroy), (gpointer) ctk_help);
g_signal_connect(G_OBJECT(ctk_help), "delete-event",
G_CALLBACK(window_destroy), (gpointer) ctk_help);
return GTK_WIDGET(ctk_help);
}
void ctk_help_set_page(CtkHelp *ctk_help, GtkTextBuffer *buffer)
{
GtkTextBuffer *b;
GtkTextIter iter;
GtkTextView *view;
GtkTextMark *mark;
if (buffer) {
b = buffer;
} else {
b = ctk_help->default_help;
}
view = GTK_TEXT_VIEW(ctk_help->text_viewer);
gtk_text_view_set_buffer(view, b);
gtk_text_buffer_get_start_iter(b, &iter);
mark = gtk_text_buffer_create_mark(b, NULL, &iter, TRUE);
gtk_text_view_scroll_to_mark(view, mark, 0.0, TRUE, 0.0, 0.0);
gtk_text_buffer_place_cursor(b, &iter);
}
static GtkTextBuffer *create_default_help(CtkHelp *ctk_help)
{
GtkTextIter iter, start, end;
GtkTextBuffer *buffer;
buffer = gtk_text_buffer_new(ctk_help->tag_table);
gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0);
gtk_text_buffer_insert_with_tags_by_name
(buffer, &iter, "\nNVIDIA Settings Help", -1,
CTK_HELP_TITLE_TAG, NULL);
gtk_text_buffer_insert(buffer, &iter, "\n\nThere is no help available "
"for this page.", -1);
* Apply CTK_HELP_HEADING_NOT_EDITABLE_TAG and
* CTK_HELP_WORD_WRAP_TAG to the whole buffer
*/
gtk_text_buffer_get_bounds(buffer, &start, &end);
gtk_text_buffer_apply_tag_by_name
(buffer, CTK_HELP_HEADING_NOT_EDITABLE_TAG, &start, &end);
gtk_text_buffer_apply_tag_by_name
(buffer, CTK_HELP_WORD_WRAP_TAG, &start, &end);
gtk_text_buffer_apply_tag_by_name
(buffer, CTK_HELP_MARGIN_TAG, &start, &end);
return buffer;
}
GtkTextTagTable *ctk_help_create_tag_table(void)
{
GtkTextTagTable *table;
GtkTextTag *tag;
table = gtk_text_tag_table_new();
tag = gtk_text_tag_new(CTK_HELP_TITLE_TAG);
g_object_set(G_OBJECT(tag),
"weight", PANGO_WEIGHT_BOLD,
"size", 15 * PANGO_SCALE,
NULL);
gtk_text_tag_table_add(table, tag);
tag = gtk_text_tag_new(CTK_HELP_HEADING_TAG);
g_object_set(G_OBJECT(tag),
"weight", PANGO_WEIGHT_BOLD,
"size", 12 * PANGO_SCALE,
NULL);
gtk_text_tag_table_add(table, tag);
tag = gtk_text_tag_new(CTK_HELP_HEADING_NOT_EDITABLE_TAG);
g_object_set(G_OBJECT(tag), "editable", FALSE, NULL);
gtk_text_tag_table_add(table, tag);
tag = gtk_text_tag_new(CTK_HELP_WORD_WRAP_TAG);
g_object_set(G_OBJECT(tag), "wrap_mode", GTK_WRAP_WORD, NULL);
gtk_text_tag_table_add(table, tag);
tag = gtk_text_tag_new(CTK_HELP_MARGIN_TAG);
g_object_set(G_OBJECT(tag), "left_margin", 10, "right_margin", 10, NULL);
gtk_text_tag_table_add(table, tag);
tag = gtk_text_tag_new(CTK_HELP_SINGLE_SPACE_TAG);
g_object_set(G_OBJECT(tag), "pixels_inside_wrap", 0, NULL);
gtk_text_tag_table_add(table, tag);
tag = gtk_text_tag_new(CTK_HELP_BOLD_TAG);
g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_BOLD, NULL);
gtk_text_tag_table_add(table, tag);
return table;
}
static void close_button_clicked(GtkButton *button, gpointer user_data)
{
CtkHelp *ctk_help = CTK_HELP(user_data);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ctk_help->toggle_button),
FALSE);
}
static gboolean window_destroy(GtkWidget *widget, GdkEvent *event,
gpointer user_data)
{
CtkHelp *ctk_help = CTK_HELP(user_data);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ctk_help->toggle_button),
FALSE);
return TRUE;
}
* Utility functions for building a help GtkTextBuffer.
*/
void ctk_help_title(GtkTextBuffer *buffer, GtkTextIter *iter,
const gchar *fmt, ...)
{
gchar *a, *b;
NV_VSNPRINTF(a, fmt);
b = g_strconcat("\n", a, "\n", NULL);
gtk_text_buffer_insert_with_tags_by_name(buffer, iter, b, -1,
CTK_HELP_TITLE_TAG, NULL);
g_free(b);
free(a);
}
void ctk_help_para(GtkTextBuffer *buffer, GtkTextIter *iter,
const gchar *fmt, ...)
{
gchar *a, *b;
NV_VSNPRINTF(a, fmt);
b = g_strconcat("\n", a, "\n", NULL);
gtk_text_buffer_insert(buffer, iter, b, -1);
g_free(b);
free(a);
}
void ctk_help_heading(GtkTextBuffer *buffer, GtkTextIter *iter,
const gchar *fmt, ...)
{
gchar *a, *b;
NV_VSNPRINTF(a, fmt);
b = g_strconcat("\n", a, "\n", NULL);
gtk_text_buffer_insert_with_tags_by_name(buffer, iter, b, -1,
CTK_HELP_HEADING_TAG, NULL);
g_free(b);
free(a);
}
void ctk_help_term(GtkTextBuffer *buffer, GtkTextIter *iter,
const gchar *fmt, ...)
{
gchar *a, *b;
NV_VSNPRINTF(a, fmt);
b = g_strconcat("\n", a, NULL);
gtk_text_buffer_insert_with_tags_by_name(buffer, iter, b, -1,
CTK_HELP_BOLD_TAG, NULL);
g_free(b);
free(a);
}
void ctk_help_finish(GtkTextBuffer *buffer)
{
GtkTextIter start, end;
gtk_text_buffer_get_bounds(buffer, &start, &end);
gtk_text_buffer_apply_tag_by_name
(buffer, CTK_HELP_HEADING_NOT_EDITABLE_TAG, &start, &end);
gtk_text_buffer_apply_tag_by_name
(buffer, CTK_HELP_WORD_WRAP_TAG, &start, &end);
gtk_text_buffer_apply_tag_by_name
(buffer, CTK_HELP_MARGIN_TAG, &start, &end);
gtk_text_buffer_apply_tag_by_name
(buffer, CTK_HELP_SINGLE_SPACE_TAG, &start, &end);
}
gchar *ctk_help_create_reset_hardware_defaults_text(gchar *type, gchar *name)
{
return g_strconcat("The Reset ", type, " Hardware Defaults button restores ",
"all ", name, " settings to their default values.", NULL);
}
void ctk_help_reset_hardware_defaults(GtkTextBuffer *b, GtkTextIter *i,
gchar *text)
{
ctk_help_heading(b, i, "Reset Hardware Defaults");
ctk_help_para(b, i, "%s", text);
}
static void help_data_list_free_cb(gpointer data, gpointer user_data)
{
CtkHelpDataItem *item = (CtkHelpDataItem *)data;
free(item->label);
free(item->help_text);
free(item);
}
void ctk_help_data_list_prepend(GList **list,
const gchar *label,
const gchar *help_text,
const gchar *extended_help_text)
{
CtkHelpDataItem *item;
if (!label || !help_text) {
return;
}
item = nvalloc(sizeof(CtkHelpDataItem));
item->label = nvstrdup(label);
item->help_text = nvstrdup(help_text);
item->extended_help_text = extended_help_text ?
nvstrdup(extended_help_text) : NULL;
*list = g_list_prepend(*list, item);
}
void ctk_help_data_list_free_full(GList *list)
{
g_list_foreach(list, help_data_list_free_cb, NULL);
g_list_free(list);
}
static void help_data_list_print_helper(GtkTextBuffer *b,
GtkTextIter *i,
GList *help_data_list,
gboolean use_headings)
{
CtkHelpDataItem *item;
GList *cur;
GString *temp_string;
temp_string = g_string_new("");
for (cur = help_data_list; cur; cur = cur->next) {
item = (CtkHelpDataItem *)cur->data;
if (use_headings) {
ctk_help_heading(b, i, "%s", item->label);
} else {
ctk_help_term(b, i, "%s", item->label);
}
g_string_printf(temp_string, "%s", item->help_text);
if (item->extended_help_text) {
g_string_append_printf(temp_string, " %s",
item->extended_help_text);
}
ctk_help_para(b, i, "%s", temp_string->str);
}
g_string_free(temp_string, TRUE);
}
void ctk_help_data_list_print_terms(GtkTextBuffer *b,
GtkTextIter *i,
GList *help_data_list)
{
help_data_list_print_helper(b, i,
help_data_list,
FALSE);
}
void ctk_help_data_list_print_sections(GtkTextBuffer *b,
GtkTextIter *i,
GList *help_data_list)
{
help_data_list_print_helper(b, i,
help_data_list,
TRUE);
}