2
* nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
5
* Copyright (C) 2004 NVIDIA Corporation.
7
* This program is free software; you can redistribute it and/or modify it
8
* under the terms and conditions of the GNU General Public License,
9
* version 2, as published by the Free Software Foundation.
11
* This program is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses>.
21
#include <NvCtrlAttributes.h>
23
#include "ctkbanner.h"
25
#include "ctkdisplaydevice-crt.h"
27
#include "ctkimagesliders.h"
29
#include "ctkconfig.h"
34
static void ctk_display_device_crt_class_init(CtkDisplayDeviceCrtClass *);
35
static void ctk_display_device_crt_finalize(GObject *);
37
static void reset_button_clicked(GtkButton *button, gpointer user_data);
39
static void ctk_display_device_crt_setup(CtkDisplayDeviceCrt
40
*ctk_display_device_crt);
42
static void info_update_received(GtkObject *object, gpointer arg1,
45
static void crt_info_setup(CtkDisplayDeviceCrt *ctk_display_device_crt);
47
static void enabled_displays_received(GtkObject *object, gpointer arg1,
50
static const char * __refresh_rate_help = "The refresh rate displays the "
51
"rate at which the screen is currently refreshing the image.";
53
GType ctk_display_device_crt_get_type(void)
55
static GType ctk_display_device_crt_type = 0;
57
if (!ctk_display_device_crt_type) {
58
static const GTypeInfo ctk_display_device_crt_info = {
59
sizeof (CtkDisplayDeviceCrtClass),
61
NULL, /* base_finalize */
62
(GClassInitFunc) ctk_display_device_crt_class_init,
63
NULL, /* class_finalize */
64
NULL, /* class_data */
65
sizeof (CtkDisplayDeviceCrt),
67
NULL, /* instance_init */
70
ctk_display_device_crt_type = g_type_register_static (GTK_TYPE_VBOX,
71
"CtkDisplayDeviceCrt", &ctk_display_device_crt_info, 0);
74
return ctk_display_device_crt_type;
77
static void ctk_display_device_crt_class_init(
78
CtkDisplayDeviceCrtClass *ctk_display_device_crt_class
81
GObjectClass *gobject_class = (GObjectClass *)ctk_display_device_crt_class;
82
gobject_class->finalize = ctk_display_device_crt_finalize;
85
static void ctk_display_device_crt_finalize(
89
CtkDisplayDeviceCrt *ctk_display_device_crt = CTK_DISPLAY_DEVICE_CRT(object);
90
g_free(ctk_display_device_crt->name);
91
g_signal_handlers_disconnect_matched(ctk_display_device_crt->ctk_event,
97
(gpointer) ctk_display_device_crt);
101
* ctk_display_device_crt_new() - constructor for the CRT display
105
GtkWidget* ctk_display_device_crt_new(NvCtrlAttributeHandle *handle,
106
CtkConfig *ctk_config,
108
unsigned int display_device_mask,
112
CtkDisplayDeviceCrt *ctk_display_device_crt;
116
GtkWidget *tmphbox, *eventbox;
118
GtkWidget *alignment;
120
object = g_object_new(CTK_TYPE_DISPLAY_DEVICE_CRT, NULL);
121
if (!object) return NULL;
123
ctk_display_device_crt = CTK_DISPLAY_DEVICE_CRT(object);
124
ctk_display_device_crt->handle = handle;
125
ctk_display_device_crt->ctk_config = ctk_config;
126
ctk_display_device_crt->ctk_event = ctk_event;
127
ctk_display_device_crt->display_device_mask = display_device_mask;
128
ctk_display_device_crt->name = g_strdup(name);
129
ctk_display_device_crt->txt_refresh_rate = gtk_label_new("");
130
gtk_box_set_spacing(GTK_BOX(object), 10);
134
banner = ctk_banner_image_new(BANNER_ARTWORK_CRT);
135
gtk_box_pack_start(GTK_BOX(object), banner, FALSE, FALSE, 0);
138
* create the reset button (which we need while creating the
139
* controls in this page so that we can set the button's
140
* sensitivity), though we pack it at the bottom of the page
143
ctk_display_device_crt->reset_button =
144
gtk_button_new_with_label("Reset CRT Hardware Defaults");
146
alignment = gtk_alignment_new(1, 1, 0, 0);
147
gtk_container_add(GTK_CONTAINER(alignment),
148
ctk_display_device_crt->reset_button);
149
gtk_box_pack_end(GTK_BOX(object), alignment, TRUE, TRUE, 0);
151
g_signal_connect(G_OBJECT(ctk_display_device_crt->reset_button),
152
"clicked", G_CALLBACK(reset_button_clicked),
153
(gpointer) ctk_display_device_crt);
155
ctk_config_set_tooltip(ctk_config, ctk_display_device_crt->reset_button,
156
ctk_help_create_reset_hardware_defaults_text("CRT", name));
158
/* pack the image sliders */
160
ctk_display_device_crt->image_sliders =
161
ctk_image_sliders_new(handle, ctk_config, ctk_event,
162
ctk_display_device_crt->reset_button,
163
display_device_mask, name);
164
if (ctk_display_device_crt->image_sliders) {
165
gtk_box_pack_start(GTK_BOX(object),
166
ctk_display_device_crt->image_sliders,
169
/* add the label Refresh Rate and its value */
171
frame = gtk_frame_new(NULL);
172
gtk_box_pack_start(GTK_BOX(object), frame, FALSE, FALSE, 0);
173
tmphbox = gtk_hbox_new(FALSE, 0);
174
gtk_container_set_border_width(GTK_CONTAINER(tmphbox), 5);
175
gtk_container_add(GTK_CONTAINER(frame), tmphbox);
177
tmpbox = gtk_vbox_new(FALSE, 5);
178
gtk_container_add(GTK_CONTAINER(tmphbox), tmpbox);
180
/* pack the Refresh Rate Label */
185
const gchar *tooltip;
188
TextLineInfo line = {
189
gtk_label_new("Refresh Rate:"),
190
ctk_display_device_crt->txt_refresh_rate,
194
hbox = gtk_hbox_new(FALSE, 0);
195
gtk_box_pack_start(GTK_BOX(hbox), line.label,
197
gtk_box_pack_start(GTK_BOX(hbox), line.txt,
200
/* Include tooltips */
202
gtk_box_pack_start(GTK_BOX(tmpbox), hbox, FALSE, FALSE, 0);
204
eventbox = gtk_event_box_new();
205
gtk_container_add(GTK_CONTAINER(eventbox), hbox);
206
ctk_config_set_tooltip(ctk_config, eventbox, line.tooltip);
207
gtk_box_pack_start(GTK_BOX(tmpbox), eventbox, FALSE, FALSE, 0);
210
/* pack the EDID button */
212
hbox = gtk_hbox_new(FALSE, 0);
213
gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, 0);
214
ctk_display_device_crt->edid_box = hbox;
218
gtk_widget_show_all(GTK_WIDGET(object));
222
update_display_enabled_flag(ctk_display_device_crt->handle,
223
&ctk_display_device_crt->display_enabled,
224
ctk_display_device_crt->display_device_mask);
226
ctk_display_device_crt_setup(ctk_display_device_crt);
228
/* handle enable/disable events on the display device */
230
g_signal_connect(G_OBJECT(ctk_event),
231
CTK_EVENT_NAME(NV_CTRL_ENABLED_DISPLAYS),
232
G_CALLBACK(enabled_displays_received),
233
(gpointer) ctk_display_device_crt);
235
g_signal_connect(G_OBJECT(ctk_event),
236
CTK_EVENT_NAME(NV_CTRL_REFRESH_RATE),
237
G_CALLBACK(info_update_received),
238
(gpointer) ctk_display_device_crt);
240
return GTK_WIDGET(object);
245
GtkTextBuffer *ctk_display_device_crt_create_help(GtkTextTagTable *table,
247
*ctk_display_device_crt)
253
b = gtk_text_buffer_new(table);
255
gtk_text_buffer_get_iter_at_offset(b, &i, 0);
257
ctk_help_title(b, &i, "%s Help", ctk_display_device_crt->name);
259
ctk_help_heading(b, &i, "Refresh rate");
260
ctk_help_para(b, &i, __refresh_rate_help);
262
add_image_sliders_help
263
(CTK_IMAGE_SLIDERS(ctk_display_device_crt->image_sliders), b, &i);
265
if (ctk_display_device_crt->edid) {
266
add_acquire_edid_help(b, &i);
269
td = gtk_tooltips_data_get(GTK_WIDGET(ctk_display_device_crt->reset_button));
270
ctk_help_reset_hardware_defaults (b, &i, td->tip_text);
280
* reset_button_clicked() -
283
static void reset_button_clicked(GtkButton *button, gpointer user_data)
285
CtkDisplayDeviceCrt *ctk_display_device_crt =
286
CTK_DISPLAY_DEVICE_CRT(user_data);
288
ctk_image_sliders_reset
289
(CTK_IMAGE_SLIDERS(ctk_display_device_crt->image_sliders));
291
gtk_widget_set_sensitive(ctk_display_device_crt->reset_button, FALSE);
293
ctk_config_statusbar_message(ctk_display_device_crt->ctk_config,
294
"Reset hardware defaults for %s.",
295
ctk_display_device_crt->name);
297
} /* reset_button_clicked() */
302
* Updates the display device page to reflect the current
303
* configuration of the display device.
305
static void ctk_display_device_crt_setup(CtkDisplayDeviceCrt
306
*ctk_display_device_crt)
308
/* Update CRT-specific settings */
309
crt_info_setup(ctk_display_device_crt);
311
/* Update the image sliders */
313
ctk_image_sliders_setup
314
(CTK_IMAGE_SLIDERS(ctk_display_device_crt->image_sliders));
317
/* update acquire EDID button */
319
if (ctk_display_device_crt->edid) {
322
list = gtk_container_get_children
323
(GTK_CONTAINER(ctk_display_device_crt->edid_box));
326
(GTK_CONTAINER(ctk_display_device_crt->edid_box),
327
(GtkWidget *)(list->data));
332
ctk_display_device_crt->edid =
333
ctk_edid_new(ctk_display_device_crt->handle,
334
ctk_display_device_crt->ctk_config,
335
ctk_display_device_crt->ctk_event,
336
ctk_display_device_crt->reset_button,
337
ctk_display_device_crt->display_device_mask,
338
ctk_display_device_crt->name);
340
if (ctk_display_device_crt->edid) {
341
gtk_box_pack_start(GTK_BOX(ctk_display_device_crt->edid_box),
342
ctk_display_device_crt->edid, TRUE, TRUE, 0);
346
/* update the reset button */
348
gtk_widget_set_sensitive(ctk_display_device_crt->reset_button, FALSE);
350
} /* ctk_display_device_crt_setup() */
352
static void crt_info_setup(CtkDisplayDeviceCrt *ctk_display_device_crt)
358
ret = NvCtrlGetDisplayAttribute(ctk_display_device_crt->handle,
359
ctk_display_device_crt->display_device_mask,
360
NV_CTRL_REFRESH_RATE, &val);
361
if (ret == NvCtrlSuccess) {
363
float fvalue = ((float)(val)) / 100.0f;
364
snprintf(str, 32, "%.2f Hz", fvalue);
366
(GTK_LABEL(ctk_display_device_crt->txt_refresh_rate),
370
(GTK_LABEL(ctk_display_device_crt->txt_refresh_rate),
375
* When the list of enabled displays on the GPU changes,
376
* this page should disable/enable access based on whether
377
* or not the display device is enabled.
379
static void enabled_displays_received(GtkObject *object, gpointer arg1,
382
CtkDisplayDeviceCrt *ctk_object = CTK_DISPLAY_DEVICE_CRT(user_data);
384
/* Requery display information only if display disabled */
386
update_display_enabled_flag(ctk_object->handle,
387
&ctk_object->display_enabled,
388
ctk_object->display_device_mask);
390
if (ctk_object->display_enabled) {
394
ctk_display_device_crt_setup(ctk_object);
396
} /* enabled_displays_received() */
400
* When resolution changes occur, we should update the GUI to reflect
404
static void info_update_received(GtkObject *object, gpointer arg1,
407
CtkDisplayDeviceCrt *ctk_object = CTK_DISPLAY_DEVICE_CRT(user_data);
408
CtkEventStruct *event_struct = (CtkEventStruct *) arg1;
410
/* if the event is not for this display device, return */
411
if (!(event_struct->display_mask & ctk_object->display_device_mask)) {
414
crt_info_setup(ctk_object);