~ubuntu-branches/ubuntu/precise/nvidia-settings/precise-proposed

« back to all changes in this revision

Viewing changes to src/gtk+-2.x/ctkdisplaydevice-dfp.c

  • Committer: Bazaar Package Importer
  • Author(s): Randall Donald
  • Date: 2004-07-03 19:09:17 UTC
  • Revision ID: james.westby@ubuntu.com-20040703190917-rqkze2s58ux5pamy
Tags: upstream-1.0
ImportĀ upstreamĀ versionĀ 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
 
3
 * and Linux systems.
 
4
 *
 
5
 * Copyright (C) 2004 NVIDIA Corporation.
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of Version 2 of the GNU General Public
 
9
 * License as published by the Free Software Foundation.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful, but
 
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See Version 2
 
14
 * of the GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the:
 
18
 *
 
19
 *           Free Software Foundation, Inc.
 
20
 *           59 Temple Place - Suite 330
 
21
 *           Boston, MA 02111-1307, USA
 
22
 *
 
23
 */
 
24
 
 
25
#include <gtk/gtk.h>
 
26
#include <NvCtrlAttributes.h>
 
27
 
 
28
#include "dfp_banner.h"
 
29
 
 
30
#include "ctkdisplaydevice-dfp.h"
 
31
 
 
32
#include "ctkimagesliders.h"
 
33
#include "ctkconfig.h"
 
34
#include "ctkhelp.h"
 
35
 
 
36
 
 
37
static GtkWidget *make_scaling_radio_button(CtkDisplayDeviceDfp
 
38
                                            *ctk_display_device_dfp,
 
39
                                            GtkWidget *vbox,
 
40
                                            GtkWidget *prev_radio,
 
41
                                            char *label,
 
42
                                            gint value);
 
43
 
 
44
static GtkWidget *make_dithering_radio_button(CtkDisplayDeviceDfp
 
45
                                              *ctk_display_device_dfp,
 
46
                                              GtkWidget *vbox,
 
47
                                              GtkWidget *prev_radio,
 
48
                                              char *label,
 
49
                                              gint value);
 
50
 
 
51
static void dfp_scaling_changed(GtkWidget *widget, gpointer user_data);
 
52
 
 
53
static void dfp_dithering_changed(GtkWidget *widget, gpointer user_data);
 
54
 
 
55
static void reset_button_clicked(GtkButton *button, gpointer user_data);
 
56
 
 
57
static void
 
58
dfp_scaling_update_radio_buttons(CtkDisplayDeviceDfp *ctk_display_device_dfp,
 
59
                                 gint value);
 
60
 
 
61
 
 
62
static void
 
63
dfp_dithering_update_radio_buttons(CtkDisplayDeviceDfp *ctk_display_device_dfp,
 
64
                                   gint value);
 
65
 
 
66
static void dfp_update_received(GtkObject *object, gpointer arg1,
 
67
                                gpointer user_data);
 
68
 
 
69
 
 
70
#define FRAME_PADDING 5
 
71
 
 
72
#define __SCALING (1<<0)
 
73
#define __DITHERING (1<<1)
 
74
 
 
75
 
 
76
static const char *__scaling_help =
 
77
"A FlatPanel usually has a single 'native' "
 
78
"resolution.  If you are using a resolution that is "
 
79
"smaller than the FlatPanel's native resolution, then "
 
80
"FlatPanel Scaling can adjust how the image is "
 
81
"displayed on the FlatPanel.";
 
82
 
 
83
static const char *__dithering_help =
 
84
"Some GeForce2 GPUs required dithering to "
 
85
"properly display on a flatpanel; this option allows "
 
86
"you to control the dithering behavior.";
 
87
 
 
88
 
 
89
GType ctk_display_device_dfp_get_type(void)
 
90
{
 
91
    static GType ctk_display_device_dfp_type = 0;
 
92
    
 
93
    if (!ctk_display_device_dfp_type) {
 
94
        static const GTypeInfo ctk_display_device_dfp_info = {
 
95
            sizeof (CtkDisplayDeviceDfpClass),
 
96
            NULL, /* base_init */
 
97
            NULL, /* base_finalize */
 
98
            NULL, /* class_init, */
 
99
            NULL, /* class_finalize */
 
100
            NULL, /* class_data */
 
101
            sizeof (CtkDisplayDeviceDfp),
 
102
            0, /* n_preallocs */
 
103
            NULL, /* instance_init */
 
104
        };
 
105
 
 
106
        ctk_display_device_dfp_type = g_type_register_static (GTK_TYPE_VBOX,
 
107
                "CtkDisplayDeviceDfp", &ctk_display_device_dfp_info, 0);
 
108
    }
 
109
 
 
110
    return ctk_display_device_dfp_type;
 
111
}
 
112
 
 
113
 
 
114
 
 
115
/*
 
116
 * ctk_display_device_dfp_new() - constructor for the DFP display
 
117
 * device page
 
118
 */
 
119
 
 
120
GtkWidget* ctk_display_device_dfp_new(NvCtrlAttributeHandle *handle,
 
121
                                      CtkConfig *ctk_config,
 
122
                                      CtkEvent *ctk_event,
 
123
                                      unsigned int display_device_mask,
 
124
                                      char *name)
 
125
{
 
126
    GObject *object;
 
127
    CtkDisplayDeviceDfp *ctk_display_device_dfp;
 
128
    GtkWidget *image;
 
129
    GtkWidget *frame;
 
130
    GtkWidget *hbox, *vbox;
 
131
    GtkWidget *label;
 
132
    GtkWidget *eventbox;
 
133
 
 
134
    GtkWidget *radio0;
 
135
    GtkWidget *radio1;
 
136
    GtkWidget *radio2;
 
137
    GtkWidget *radio3;
 
138
    GtkWidget *alignment;
 
139
    
 
140
    ReturnStatus ret;
 
141
    
 
142
    guint8 *image_buffer = NULL;
 
143
    const nv_image_t *img;    
 
144
    gint val, i;
 
145
 
 
146
    object = g_object_new(CTK_TYPE_DISPLAY_DEVICE_DFP, NULL);
 
147
 
 
148
    ctk_display_device_dfp = CTK_DISPLAY_DEVICE_DFP(object);
 
149
    ctk_display_device_dfp->handle = handle;
 
150
    ctk_display_device_dfp->ctk_config = ctk_config;
 
151
    ctk_display_device_dfp->display_device_mask = display_device_mask;
 
152
    ctk_display_device_dfp->name = name;
 
153
 
 
154
    gtk_box_set_spacing(GTK_BOX(object), 10);
 
155
 
 
156
    /* banner */
 
157
    
 
158
    hbox = gtk_hbox_new(FALSE, 0);
 
159
    gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, 0);
 
160
 
 
161
    frame = gtk_frame_new(NULL);
 
162
    gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, FALSE, 0);
 
163
 
 
164
    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
 
165
    
 
166
    img = &dfp_banner_image;
 
167
    
 
168
    image_buffer = decompress_image_data(img);
 
169
    
 
170
    image = gtk_image_new_from_pixbuf
 
171
        (gdk_pixbuf_new_from_data(image_buffer, GDK_COLORSPACE_RGB,
 
172
                                  FALSE, 8, img->width, img->height,
 
173
                                  img->width * img->bytes_per_pixel,
 
174
                                  free_decompressed_image, NULL));
 
175
 
 
176
    gtk_container_add(GTK_CONTAINER(frame), image);
 
177
    
 
178
    /*
 
179
     * create the reset button (which we need while creating the
 
180
     * controls in this page so that we can set the button's
 
181
     * sensitivity), though we pack it at the bottom of the page
 
182
     */
 
183
 
 
184
    label = gtk_label_new("Reset Hardware Defaults");
 
185
    hbox = gtk_hbox_new(FALSE, 0);
 
186
    ctk_display_device_dfp->reset_button = gtk_button_new();
 
187
    
 
188
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 15);
 
189
    gtk_container_add(GTK_CONTAINER(ctk_display_device_dfp->reset_button),
 
190
                      hbox);
 
191
 
 
192
    alignment = gtk_alignment_new(1, 1, 0, 0);
 
193
    gtk_container_add(GTK_CONTAINER(alignment),
 
194
                      ctk_display_device_dfp->reset_button);
 
195
    gtk_box_pack_end(GTK_BOX(object), alignment, TRUE, TRUE, 0);
 
196
 
 
197
    g_signal_connect(G_OBJECT(ctk_display_device_dfp->reset_button),
 
198
                     "clicked", G_CALLBACK(reset_button_clicked),
 
199
                     (gpointer) ctk_display_device_dfp);
 
200
    
 
201
    ctk_config_set_tooltip(ctk_config, ctk_display_device_dfp->reset_button,
 
202
                           "The Reset Hardware Defaults button restores "
 
203
                           "the DFP settings to their default values.");
 
204
 
 
205
    /* create the hbox to store scaling and dithering */
 
206
 
 
207
    hbox = gtk_hbox_new(FALSE, FRAME_PADDING);
 
208
    gtk_box_pack_start(GTK_BOX(object), hbox, TRUE, TRUE, FRAME_PADDING);
 
209
 
 
210
    /* FlatPanel Scaling */
 
211
    
 
212
    ret = NvCtrlGetDisplayAttribute(handle, display_device_mask,
 
213
                                    NV_CTRL_FLATPANEL_SCALING, &val);
 
214
 
 
215
    if (ret == NvCtrlSuccess) {
 
216
        frame = gtk_frame_new("FlatPanel Scaling");
 
217
        eventbox = gtk_event_box_new();
 
218
        gtk_container_add(GTK_CONTAINER(eventbox), frame);
 
219
        gtk_box_pack_start(GTK_BOX(hbox), eventbox, TRUE, TRUE, 0);
 
220
    
 
221
        ctk_config_set_tooltip(ctk_config, eventbox, __scaling_help);
 
222
 
 
223
        vbox = gtk_vbox_new(FALSE, FRAME_PADDING);
 
224
        gtk_container_set_border_width(GTK_CONTAINER(vbox), FRAME_PADDING);
 
225
        gtk_container_add(GTK_CONTAINER(frame), vbox);
 
226
        
 
227
        
 
228
        radio0 = make_scaling_radio_button
 
229
            (ctk_display_device_dfp, vbox, NULL, "Default",
 
230
             NV_CTRL_FLATPANEL_SCALING_DEFAULT);
 
231
        
 
232
        radio1 = make_scaling_radio_button
 
233
            (ctk_display_device_dfp, vbox, radio0, "Scaled",
 
234
             NV_CTRL_FLATPANEL_SCALING_SCALED);
 
235
        
 
236
        radio2 = make_scaling_radio_button
 
237
            (ctk_display_device_dfp, vbox, radio1, "Centered",
 
238
             NV_CTRL_FLATPANEL_SCALING_CENTERED);
 
239
        
 
240
        radio3 = make_scaling_radio_button
 
241
            (ctk_display_device_dfp, vbox, radio2, "Fixed Aspect Ratio Scaled",
 
242
             NV_CTRL_FLATPANEL_SCALING_ASPECT_SCALED);
 
243
        
 
244
        /*
 
245
         * XXX TODO: determine when we should advertise Monitor
 
246
         * Scaling (aka "Native" scaling)
 
247
         */
 
248
        
 
249
        ctk_display_device_dfp->scaling_buttons
 
250
            [NV_CTRL_FLATPANEL_SCALING_NATIVE] = NULL;
 
251
        
 
252
        
 
253
        dfp_scaling_update_radio_buttons(ctk_display_device_dfp, val);
 
254
        
 
255
        g_signal_connect(G_OBJECT(ctk_event),
 
256
                         CTK_EVENT_NAME(NV_CTRL_FLATPANEL_SCALING),
 
257
                         G_CALLBACK(dfp_update_received),
 
258
                         (gpointer) ctk_display_device_dfp);
 
259
        
 
260
        ctk_display_device_dfp->active_attributes |= __SCALING;
 
261
        
 
262
    } else {
 
263
        
 
264
        for (i = 0; i < NV_CTRL_FLATPANEL_SCALING_ASPECT_SCALED+1; i++) {
 
265
            ctk_display_device_dfp->scaling_buttons[i] = NULL;
 
266
        }
 
267
        
 
268
        ctk_display_device_dfp->active_attributes &= ~__SCALING;
 
269
    }
 
270
 
 
271
    /* FlatPanel Dithering */
 
272
 
 
273
    ret = NvCtrlGetDisplayAttribute(handle, display_device_mask,
 
274
                                    NV_CTRL_FLATPANEL_DITHERING, &val);
 
275
 
 
276
    if (ret == NvCtrlSuccess) {
 
277
        frame = gtk_frame_new("FlatPanel Dithering");
 
278
        eventbox = gtk_event_box_new();
 
279
        gtk_container_add(GTK_CONTAINER(eventbox), frame);
 
280
        gtk_box_pack_start(GTK_BOX(hbox), eventbox, TRUE, TRUE, 0);
 
281
    
 
282
        ctk_config_set_tooltip(ctk_config, eventbox, __dithering_help);
 
283
 
 
284
        vbox = gtk_vbox_new(FALSE, FRAME_PADDING);
 
285
        gtk_container_set_border_width(GTK_CONTAINER(vbox), FRAME_PADDING);
 
286
        gtk_container_add(GTK_CONTAINER(frame), vbox);
 
287
    
 
288
    
 
289
        radio0 = make_dithering_radio_button
 
290
            (ctk_display_device_dfp, vbox, NULL, "Default",
 
291
             NV_CTRL_FLATPANEL_DITHERING_DEFAULT);
 
292
 
 
293
        radio1 = make_dithering_radio_button
 
294
            (ctk_display_device_dfp, vbox, radio0, "Enabled",
 
295
             NV_CTRL_FLATPANEL_DITHERING_ENABLED);
 
296
 
 
297
        radio2 = make_dithering_radio_button
 
298
            (ctk_display_device_dfp, vbox, radio1, "Disabled",
 
299
             NV_CTRL_FLATPANEL_DITHERING_DISABLED);
 
300
 
 
301
        dfp_dithering_update_radio_buttons(ctk_display_device_dfp, val);
 
302
        
 
303
        g_signal_connect(G_OBJECT(ctk_event),
 
304
                         CTK_EVENT_NAME(NV_CTRL_FLATPANEL_DITHERING),
 
305
                         G_CALLBACK(dfp_update_received),
 
306
                         (gpointer) ctk_display_device_dfp);
 
307
        
 
308
        ctk_display_device_dfp->active_attributes |= __DITHERING;
 
309
 
 
310
    } else {
 
311
 
 
312
        for (i = 0; i < NV_CTRL_FLATPANEL_DITHERING_DISABLED+1; i++) {
 
313
            ctk_display_device_dfp->dithering_buttons[i] = NULL;
 
314
        }
 
315
        
 
316
        ctk_display_device_dfp->active_attributes &= ~__DITHERING;
 
317
    }
 
318
 
 
319
    /* pack the image sliders */
 
320
    
 
321
    ctk_display_device_dfp->image_sliders =
 
322
        ctk_image_sliders_new(handle, ctk_config, ctk_event,
 
323
                              ctk_display_device_dfp->reset_button,
 
324
                              display_device_mask, name);
 
325
    if (ctk_display_device_dfp->image_sliders) {
 
326
        gtk_box_pack_start(GTK_BOX(object),
 
327
                           ctk_display_device_dfp->image_sliders,
 
328
                           FALSE, FALSE, 0);
 
329
    }
 
330
 
 
331
    /* show the page */
 
332
 
 
333
    gtk_widget_show_all(GTK_WIDGET(object));
 
334
 
 
335
    return GTK_WIDGET(object);
 
336
 
 
337
} /* ctk_display_device_dfp_new() */
 
338
 
 
339
 
 
340
 
 
341
/*
 
342
 * make_scaling_radio_button() - create a radio button and plug it
 
343
 * into the scaling radio group.
 
344
 */
 
345
 
 
346
static GtkWidget *make_scaling_radio_button(CtkDisplayDeviceDfp
 
347
                                            *ctk_display_device_dfp,
 
348
                                            GtkWidget *vbox,
 
349
                                            GtkWidget *prev_radio,
 
350
                                            char *label,
 
351
                                            gint value)
 
352
{
 
353
    GtkWidget *radio;
 
354
    
 
355
    if (prev_radio) {
 
356
        radio = gtk_radio_button_new_with_label_from_widget
 
357
            (GTK_RADIO_BUTTON(prev_radio), label);
 
358
    } else {
 
359
        radio = gtk_radio_button_new_with_label(NULL, label);
 
360
    }
 
361
    
 
362
    gtk_box_pack_start(GTK_BOX(vbox), radio, FALSE, FALSE, 0);
 
363
 
 
364
    g_object_set_data(G_OBJECT(radio), "scaling_value",
 
365
                      GINT_TO_POINTER(value));
 
366
   
 
367
    g_signal_connect(G_OBJECT(radio), "toggled",
 
368
                     G_CALLBACK(dfp_scaling_changed),
 
369
                     (gpointer) ctk_display_device_dfp);
 
370
 
 
371
    ctk_display_device_dfp->scaling_buttons[value] = radio;
 
372
 
 
373
    return radio;
 
374
    
 
375
} /* make_scaling_radio_button() */
 
376
 
 
377
 
 
378
 
 
379
/*
 
380
 * make_dithering_radio_button() - create a radio button and plug it
 
381
 * into the dithering radio group.
 
382
 */
 
383
 
 
384
static GtkWidget *make_dithering_radio_button(CtkDisplayDeviceDfp
 
385
                                              *ctk_display_device_dfp,
 
386
                                              GtkWidget *vbox,
 
387
                                              GtkWidget *prev_radio,
 
388
                                              char *label,
 
389
                                              gint value)
 
390
{
 
391
    GtkWidget *radio;
 
392
 
 
393
    if (prev_radio) {
 
394
        radio = gtk_radio_button_new_with_label_from_widget
 
395
            (GTK_RADIO_BUTTON(prev_radio), label);
 
396
    } else {
 
397
        radio = gtk_radio_button_new_with_label(NULL, label);
 
398
    }
 
399
 
 
400
    gtk_box_pack_start(GTK_BOX(vbox), radio, FALSE, FALSE, 0);
 
401
    
 
402
    g_object_set_data(G_OBJECT(radio), "dithering_value",
 
403
                      GINT_TO_POINTER(value));
 
404
   
 
405
    g_signal_connect(G_OBJECT(radio), "toggled",
 
406
                     G_CALLBACK(dfp_dithering_changed),
 
407
                     (gpointer) ctk_display_device_dfp);
 
408
 
 
409
    ctk_display_device_dfp->dithering_buttons[value] = radio;
 
410
 
 
411
    return radio;
 
412
    
 
413
} /* make_dithering_radio_button() */
 
414
 
 
415
 
 
416
 
 
417
/*
 
418
 * post_dfp_scaling_update() - helper function for
 
419
 * dfp_scaling_changed() and dfp_update_received(); this does whatever
 
420
 * work is necessary after scaling has been updated -- currently, this
 
421
 * just means posting a statusbar message.
 
422
 */
 
423
 
 
424
static void
 
425
post_dfp_scaling_update(CtkDisplayDeviceDfp *ctk_display_device_dfp,
 
426
                        gint value)
 
427
{
 
428
    static const char *scaling_string_table[] = {
 
429
        "Default",        /* NV_CTRL_FLATPANEL_SCALING_DEFAULT */
 
430
        "Monitor Scaled", /* NV_CTRL_FLATPANEL_SCALING_NATIVE */
 
431
        "Scaled",         /* NV_CTRL_FLATPANEL_SCALING_SCALED */
 
432
        "Centered",       /* NV_CTRL_FLATPANEL_SCALING_CENTERED */
 
433
        "Aspect Scaled"   /* NV_CTRL_FLATPANEL_SCALING_ASPECT_SCALED */
 
434
    };
 
435
        
 
436
    if (value > NV_CTRL_FLATPANEL_SCALING_ASPECT_SCALED) return;
 
437
    
 
438
    ctk_config_statusbar_message(ctk_display_device_dfp->ctk_config,
 
439
                                 "Set FlatPanel Scaling for %s to %s.",
 
440
                                 ctk_display_device_dfp->name,
 
441
                                 scaling_string_table[value]);
 
442
    
 
443
} /* post_dfp_scaling_update() */
 
444
 
 
445
 
 
446
 
 
447
/*
 
448
 * dfp_scaling_changed() - callback function for changes to the
 
449
 * scaling radio button group; if the specified radio button is
 
450
 * active, send updated state to the server
 
451
 */
 
452
 
 
453
static void dfp_scaling_changed(GtkWidget *widget, gpointer user_data)
 
454
{
 
455
    CtkDisplayDeviceDfp *ctk_display_device_dfp =
 
456
        CTK_DISPLAY_DEVICE_DFP(user_data);
 
457
    gboolean enabled;
 
458
    gint value;
 
459
 
 
460
    enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
 
461
 
 
462
    if (enabled) {
 
463
 
 
464
        user_data = g_object_get_data(G_OBJECT(widget), "scaling_value");
 
465
        value = GPOINTER_TO_INT(user_data);
 
466
        
 
467
        NvCtrlSetDisplayAttribute(ctk_display_device_dfp->handle,
 
468
                                  ctk_display_device_dfp->display_device_mask,
 
469
                                  NV_CTRL_FLATPANEL_SCALING, value);
 
470
        
 
471
        post_dfp_scaling_update(ctk_display_device_dfp, value);
 
472
    }
 
473
 
 
474
} /* dfp_scaling_changed() */
 
475
 
 
476
 
 
477
 
 
478
/*
 
479
 * post_dfp_dithering_update() - helper function for
 
480
 * dfp_dithering_changed() and dfp_update_received(); this does
 
481
 * whatever work is necessary after dithering has been updated --
 
482
 * currently, this just means posting a statusbar message.
 
483
 */
 
484
 
 
485
static void
 
486
post_dfp_dithering_update(CtkDisplayDeviceDfp *ctk_display_device_dfp,
 
487
                          gint value)
 
488
{
 
489
    static const char *dithering_string_table[] = {
 
490
        "Default", /* NV_CTRL_FLATPANEL_DITHERING_DEFAULT */
 
491
        "Enabled", /* NV_CTRL_FLATPANEL_DITHERING_ENABLED */
 
492
        "Disabled" /* NV_CTRL_FLATPANEL_DITHERING_DISABLED */
 
493
    };
 
494
 
 
495
    if (value > NV_CTRL_FLATPANEL_DITHERING_DISABLED) return;
 
496
    
 
497
    ctk_config_statusbar_message(ctk_display_device_dfp->ctk_config,
 
498
                                 "Set FlatPanel Dithering for %s to %s.",
 
499
                                 ctk_display_device_dfp->name,
 
500
                                 dithering_string_table[value]);
 
501
    
 
502
} /* post_dfp_dithering_update() */
 
503
 
 
504
 
 
505
 
 
506
/*
 
507
 * dfp_dithering_changed() - callback function for changes to the
 
508
 * dithering radio button group; if the specified radio button is
 
509
 * active, send updated state to the server
 
510
 */
 
511
 
 
512
static void dfp_dithering_changed(GtkWidget *widget, gpointer user_data)
 
513
{
 
514
    CtkDisplayDeviceDfp *ctk_display_device_dfp =
 
515
        CTK_DISPLAY_DEVICE_DFP(user_data);
 
516
    
 
517
    gboolean enabled;
 
518
    gint value;
 
519
    
 
520
    enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
 
521
    
 
522
    if (enabled) {
 
523
        
 
524
        user_data = g_object_get_data(G_OBJECT(widget), "dithering_value");
 
525
        value = GPOINTER_TO_INT(user_data);
 
526
        
 
527
        NvCtrlSetDisplayAttribute(ctk_display_device_dfp->handle,
 
528
                                  ctk_display_device_dfp->display_device_mask,
 
529
                                  NV_CTRL_FLATPANEL_DITHERING, value);
 
530
        
 
531
        post_dfp_dithering_update(ctk_display_device_dfp, value);
 
532
    }
 
533
    
 
534
} /* dfp_dithering_changed() */
 
535
 
 
536
 
 
537
 
 
538
/*
 
539
 * reset_button_clicked() - callback when the reset button is clicked
 
540
 */
 
541
 
 
542
static void reset_button_clicked(GtkButton *button, gpointer user_data)
 
543
{
 
544
    CtkDisplayDeviceDfp *ctk_display_device_dfp =
 
545
        CTK_DISPLAY_DEVICE_DFP(user_data);
 
546
 
 
547
    gint value;
 
548
    
 
549
    if (ctk_display_device_dfp->image_sliders) {
 
550
        ctk_image_sliders_reset
 
551
            (CTK_IMAGE_SLIDERS(ctk_display_device_dfp->image_sliders));
 
552
    }
 
553
 
 
554
    /*
 
555
     * if scaling is active, send the default scaling value to the
 
556
     * server and update the radio button group
 
557
     */
 
558
   
 
559
    if (ctk_display_device_dfp->active_attributes & __SCALING) {
 
560
        
 
561
        value = NV_CTRL_FLATPANEL_SCALING_DEFAULT;
 
562
 
 
563
        NvCtrlSetDisplayAttribute(ctk_display_device_dfp->handle,
 
564
                                  ctk_display_device_dfp->display_device_mask,
 
565
                                  NV_CTRL_FLATPANEL_SCALING, value);
 
566
 
 
567
        dfp_scaling_update_radio_buttons(ctk_display_device_dfp, value);
 
568
    }
 
569
    
 
570
    /*
 
571
     * if dithering is active, send the default dithering value to the
 
572
     * server and update the radio button group
 
573
     */
 
574
    
 
575
    if (ctk_display_device_dfp->active_attributes & __DITHERING) {
 
576
    
 
577
        value = NV_CTRL_FLATPANEL_DITHERING_DEFAULT;
 
578
 
 
579
        NvCtrlSetDisplayAttribute(ctk_display_device_dfp->handle,
 
580
                                  ctk_display_device_dfp->display_device_mask,
 
581
                                  NV_CTRL_FLATPANEL_DITHERING, value);
 
582
 
 
583
        dfp_dithering_update_radio_buttons(ctk_display_device_dfp, value);
 
584
    }
 
585
    
 
586
    /* status bar message */
 
587
 
 
588
    ctk_config_statusbar_message(ctk_display_device_dfp->ctk_config,
 
589
                                 "Reset hardware defaults for %s.",
 
590
                                 ctk_display_device_dfp->name);
 
591
    
 
592
} /* reset_button_clicked() */
 
593
 
 
594
 
 
595
 
 
596
/*
 
597
 * dfp_scaling_update_radio_buttons() - update the scaling radio
 
598
 * button group, making the specified scaling value active.
 
599
 */
 
600
 
 
601
static void
 
602
dfp_scaling_update_radio_buttons(CtkDisplayDeviceDfp *ctk_display_device_dfp,
 
603
                                 gint value)
 
604
{
 
605
    GtkWidget *b, *button = NULL;
 
606
    int i;
 
607
 
 
608
    if ((value < NV_CTRL_FLATPANEL_SCALING_DEFAULT) ||
 
609
        (value > NV_CTRL_FLATPANEL_SCALING_ASPECT_SCALED)) return;
 
610
 
 
611
    button = ctk_display_device_dfp->scaling_buttons[value];
 
612
    
 
613
    if (!button) return;
 
614
 
 
615
    /* turn off signal handling for all the scaling buttons */
 
616
 
 
617
    for (i = 0; i < 5; i++) {
 
618
        b = ctk_display_device_dfp->scaling_buttons[i];
 
619
        if (!b) continue;
 
620
 
 
621
        g_signal_handlers_block_by_func
 
622
            (G_OBJECT(b), G_CALLBACK(dfp_scaling_changed),
 
623
             (gpointer) ctk_display_device_dfp);
 
624
    }
 
625
    
 
626
    /* set the appropriate button active */
 
627
 
 
628
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
 
629
    
 
630
    /* turn on signal handling for all the scaling buttons */
 
631
 
 
632
    for (i = 0; i < 5; i++) {
 
633
        b = ctk_display_device_dfp->scaling_buttons[i];
 
634
        if (!b) continue;
 
635
 
 
636
        g_signal_handlers_unblock_by_func
 
637
            (G_OBJECT(b), G_CALLBACK(dfp_scaling_changed),
 
638
             (gpointer) ctk_display_device_dfp);
 
639
    }
 
640
    
 
641
} /* dfp_scaling_update_radio_buttons() */
 
642
 
 
643
 
 
644
 
 
645
/*
 
646
 * dfp_dithering_update_radio_buttons() - update the dithering radio
 
647
 * button group, making the specified dithering value active.
 
648
 */
 
649
 
 
650
static void
 
651
dfp_dithering_update_radio_buttons(CtkDisplayDeviceDfp *ctk_display_device_dfp,
 
652
                                   gint value)
 
653
{
 
654
    GtkWidget *b, *button = NULL;
 
655
    int i;
 
656
 
 
657
    if ((value < NV_CTRL_FLATPANEL_DITHERING_DEFAULT) ||
 
658
        (value > NV_CTRL_FLATPANEL_DITHERING_DISABLED)) return;
 
659
 
 
660
    button = ctk_display_device_dfp->dithering_buttons[value];
 
661
    
 
662
    if (!button) return;
 
663
    
 
664
    /* turn off signal handling for all the dithering buttons */
 
665
 
 
666
    for (i = 0; i < 3; i++) {
 
667
        b = ctk_display_device_dfp->dithering_buttons[i];
 
668
        if (!b) continue;
 
669
        
 
670
        g_signal_handlers_block_by_func
 
671
            (G_OBJECT(b), G_CALLBACK(dfp_dithering_changed),
 
672
             (gpointer) ctk_display_device_dfp);
 
673
    }
 
674
    
 
675
    /* set the appropriate button active */
 
676
 
 
677
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
 
678
 
 
679
    /* turn on signal handling for all the dithering buttons */
 
680
 
 
681
    for (i = 0; i < 3; i++) {
 
682
        b = ctk_display_device_dfp->dithering_buttons[i];
 
683
        if (!b) continue;
 
684
        
 
685
        g_signal_handlers_unblock_by_func
 
686
            (G_OBJECT(b), G_CALLBACK(dfp_dithering_changed),
 
687
             (gpointer) ctk_display_device_dfp);
 
688
    }
 
689
} /* dfp_dithering_update_radio_buttons() */
 
690
 
 
691
 
 
692
 
 
693
/*
 
694
 * dfp_dithering_update_received() - callback function for changed DFP
 
695
 * settings; this is called when we receive an event indicating that
 
696
 * another NV-CONTROL client changed any of the settings that we care
 
697
 * about.
 
698
 */
 
699
 
 
700
static void dfp_update_received(GtkObject *object, gpointer arg1,
 
701
                                gpointer user_data)
 
702
{
 
703
    CtkEventStruct *event_struct = (CtkEventStruct *) arg1;
 
704
    CtkDisplayDeviceDfp *ctk_display_device_dfp =
 
705
        CTK_DISPLAY_DEVICE_DFP(user_data);
 
706
    
 
707
    /* if the event is not for this display device, return */
 
708
    
 
709
    if (!(event_struct->display_mask &
 
710
          ctk_display_device_dfp->display_device_mask)) {
 
711
        return;
 
712
    }
 
713
    
 
714
    switch (event_struct->attribute) {
 
715
    case NV_CTRL_FLATPANEL_SCALING:
 
716
        dfp_scaling_update_radio_buttons(ctk_display_device_dfp,
 
717
                                         event_struct->value);
 
718
        post_dfp_scaling_update(ctk_display_device_dfp, event_struct->value);
 
719
        break;
 
720
        
 
721
    case NV_CTRL_FLATPANEL_DITHERING:
 
722
        dfp_dithering_update_radio_buttons(ctk_display_device_dfp,
 
723
                                           event_struct->value);
 
724
        post_dfp_dithering_update(ctk_display_device_dfp, event_struct->value);
 
725
        break;
 
726
    default:
 
727
        break;
 
728
    }
 
729
    
 
730
} /* dfp_dithering_update_received() */
 
731
 
 
732
 
 
733
 
 
734
/*
 
735
 * ctk_display_device_dfp_create_help() - construct the DFP display
 
736
 * device help page
 
737
 */
 
738
 
 
739
GtkTextBuffer *ctk_display_device_dfp_create_help(GtkTextTagTable *table,
 
740
                                                  CtkDisplayDeviceDfp
 
741
                                                  *ctk_display_device_dfp)
 
742
{
 
743
    GtkTextIter i;
 
744
    GtkTextBuffer *b;
 
745
    gboolean ret = FALSE;
 
746
    
 
747
    b = gtk_text_buffer_new(table);
 
748
    
 
749
    gtk_text_buffer_get_iter_at_offset(b, &i, 0);
 
750
    
 
751
    ctk_help_title(b, &i, "%s Help", ctk_display_device_dfp->name);
 
752
    
 
753
    if (ctk_display_device_dfp->active_attributes & __SCALING) {
 
754
        ctk_help_heading(b, &i, "FlatPanel Scaling");
 
755
        ctk_help_para(b, &i, __scaling_help);
 
756
        
 
757
        ctk_help_term(b, &i, "Default");
 
758
        ctk_help_para(b, &i, "The driver will choose what scaling state is "
 
759
                      "best.");
 
760
        
 
761
        ctk_help_term(b, &i, "Scaled");
 
762
        ctk_help_para(b, &i, "The image will be expanded to fit the entire "
 
763
                      "FlatPanel.");
 
764
 
 
765
        ctk_help_term(b, &i, "Centered");
 
766
        ctk_help_para(b, &i, "The image will only occupy the number of pixels "
 
767
                      "needed and be centered on the FlatPanel.");
 
768
 
 
769
        ctk_help_term(b, &i, "Fixed Aspect Ratio Scaled");
 
770
        ctk_help_para(b, &i, "The image will be expanded (like when Scaled), "
 
771
                      "but the image will retain the original aspect ratio.");
 
772
        ret = TRUE;
 
773
    }
 
774
    
 
775
    if (ctk_display_device_dfp->active_attributes & __DITHERING) {
 
776
        ctk_help_heading(b, &i, "FlatPanel Dithering");
 
777
        ctk_help_para(b, &i, __dithering_help);
 
778
        
 
779
        ctk_help_term(b, &i, "Default");
 
780
        ctk_help_para(b, &i, "The driver will choose when to dither.");
 
781
 
 
782
        ctk_help_term(b, &i, "Enabled");
 
783
        ctk_help_para(b, &i, "Force dithering on.");
 
784
 
 
785
        ctk_help_term(b, &i, "Disabled");
 
786
        ctk_help_para(b, &i, "Force dithering off.");
 
787
        
 
788
        ret = TRUE;
 
789
    }
 
790
 
 
791
    if (ctk_display_device_dfp->image_sliders) {
 
792
        ret |= add_image_sharpening_help
 
793
            (CTK_IMAGE_SLIDERS(ctk_display_device_dfp->image_sliders), b, &i);
 
794
    }
 
795
    
 
796
    if (!ret) {
 
797
        ctk_help_para(b, &i, "There are no configurable options available "
 
798
                      "for %s.", ctk_display_device_dfp->name);
 
799
    }
 
800
    
 
801
    ctk_help_finish(b);
 
802
    
 
803
    return b;
 
804
    
 
805
} /* ctk_display_device_dfp_create_help() */