/* NVClock 0.8 - Linux overclocker for NVIDIA cards
*
* Copyright(C) 2001-2005 Roderick Colenbrander
*
* site: http://NVClock.sourceforge.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Hardware page containing card info, hardware monitoring, overclocking ..
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include "interface.h"
#include "hw.h"
#include "nvclock.h"
#ifdef HAVE_NVCONTROL
#include "nvcontrol.h"
#endif
void reset_speeds(GtkButton *button, gpointer data);
gboolean update_speeds(GtkWidget *widget);
void test_speeds(gpointer data);
gboolean thermal_update(NVThermal *thermal);
gboolean timeout_callback(gpointer data);
GType nv_agp_get_type (void)
{
static GType agp_type = 0;
if (!agp_type)
{
static const GTypeInfo agp_info =
{
sizeof (NVAgpClass),
NULL, /* base_init */
NULL, /* base_finalize */
NULL,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (NVAgp),
0, /* n_preallocs */
NULL /* instance_init */
};
agp_type = g_type_register_static (GTK_TYPE_VBOX, "NVAgp",
&agp_info, 0);
}
return agp_type;
}
GType nv_bios_get_type (void)
{
static GType bios_type = 0;
if (!bios_type)
{
static const GTypeInfo bios_info =
{
sizeof (NVBiosClass),
NULL, /* base_init */
NULL, /* base_finalize */
NULL,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (NVBios),
0, /* n_preallocs */
NULL /* instance_init */
};
bios_type = g_type_register_static (GTK_TYPE_VBOX, "NVBios",
&bios_info, 0);
}
return bios_type;
}
GType nv_info_get_type (void)
{
static GType info_type = 0;
if (!info_type)
{
static const GTypeInfo info =
{
sizeof (NVInfoClass),
NULL, /* base_init */
NULL, /* base_finalize */
NULL,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (NVInfo),
0, /* n_preallocs */
NULL /* instance_init */
};
info_type = g_type_register_static (GTK_TYPE_VBOX, "NVInfo",
&info, 0);
}
return info_type;
}
GType nv_overclock_get_type (void)
{
static GType overclock_type = 0;
if (!overclock_type)
{
static const GTypeInfo overclock_info =
{
sizeof (NVOverclockClass),
NULL, /* base_init */
NULL, /* base_finalize */
NULL,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (NVOverclock),
0, /* n_preallocs */
NULL /* instance_init */
};
overclock_type = g_type_register_static (GTK_TYPE_VBOX, "NVOverclock",
&overclock_info, 0);
}
return overclock_type;
}
GType nv_pipeline_get_type (void)
{
static GType pipeline_type = 0;
if (!pipeline_type)
{
static const GTypeInfo pipeline_info =
{
sizeof (NVPipelineClass),
NULL, /* base_init */
NULL, /* base_finalize */
NULL,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (NVPipeline),
0, /* n_preallocs */
NULL /* instance_init */
};
pipeline_type = g_type_register_static (GTK_TYPE_VBOX, "NVPipeline",
&pipeline_info, 0);
}
return pipeline_type;
}
GType nv_thermal_get_type (void)
{
static GType thermal_type = 0;
if (!thermal_type)
{
static const GTypeInfo thermal_info =
{
sizeof (NVThermalClass),
NULL, /* base_init */
NULL, /* base_finalize */
NULL,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (NVThermal),
0, /* n_preallocs */
NULL /* instance_init */
};
thermal_type = g_type_register_static (GTK_TYPE_VBOX, "NVThermal",
&thermal_info, 0);
}
return thermal_type;
}
void change_fanspeed(GtkButton *button, gpointer data)
{
NVThermal *thermal = NV_THERMAL(data);
float fanspeed = gtk_range_get_value(GTK_RANGE((thermal->scale_dutycycle)));
if(thermal->card->number != nv_card->number)
set_card(thermal->card->number);
/* First process cards with 'advanced' sensors as both I2C_/GPU_FANSPEED_MONITORING are set */
if(nv_card->caps & I2C_FANSPEED_MONITORING)
{
nv_card->set_i2c_fanspeed_pwm(nv_card->sensor, fanspeed);
}
else if(nv_card->caps & GPU_FANSPEED_MONITORING)
{
nv_card->set_fanspeed(fanspeed);
}
}
/* This function overclocks the card and updates the speeds on the gui. */
void change_speeds(GtkButton *button, gpointer data)
{
NVOverclock *overclock = NV_OVERCLOCK(data);
if(overclock->card->number != nv_card->number)
set_card(overclock->card->number);
if((int)nv_card->get_gpu_speed() != gtk_range_get_value(GTK_RANGE((overclock->scale_gpu))))
{
gint nvclk = gtk_range_get_value(GTK_RANGE((overclock->scale_gpu)));
nv_card->set_gpu_speed(nvclk);
}
if((int)nv_card->get_memory_speed() != gtk_range_get_value(GTK_RANGE((overclock->scale_mem))))
{
gint memclk = gtk_range_get_value(GTK_RANGE((overclock->scale_mem)));
nv_card->set_memory_speed(memclk);
}
overclock->clock_changes=0;
update_speeds(data);
/* Let the user decide if the speeds work fine */
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(overclock->chk_test_speeds)))
{
test_speeds(data);
}
}
void enable_overclocking(GtkToggleButton *button, NVOverclock *overclock)
{
char *section = g_strdup_printf("hw%d", overclock->card->number);
change_entry((cfg_entry**)&overclock->conf->cfg, section, "enable_overclocking", 1);
if(gtk_toggle_button_get_active(button))
{
GtkWidget *dialog;
/* In some cases We need to ask the user if he really wants to enable overclocking */
if(nv_card->gpu == MOBILE)
{
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, "%s", "Overclocking on Laptops is more dangerous than normal overclocking because they are more sensitive to heat.\n\nAre you sure you want to enable overclocking?");
}
else if((nv_card->arch & (NV3X | NV4X)) && nv_card->gpu == DESKTOP && !(nv_card->caps & COOLBITS_OVERCLOCKING))
{
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, "%s", "NVClock supports GeforceFX/6/7 overclocking through a low-level backend and through the Nvidia drivers (Coolbits).\nThe low-level backend should work in all cases but can give issues if your card uses different clocks in 2D and 3D. The Coolbits backend on the other hand supports 2D/3D clocks but requires Nvidia driver 1.0-7664. The Coolbits backend can't be used on your system right now either because the driver is too old or the option isn't enabled in the X config file.\n\nAre you sure you want to use the low-level backend?");
}
else
{
change_entry((cfg_entry**)&overclock->conf->cfg, section, "enable_overclocking", 1);
gtk_widget_set_sensitive(overclock->vbox, TRUE);
return;
}
int res = gtk_dialog_run(GTK_DIALOG(dialog));
switch(res)
{
case GTK_RESPONSE_YES:
change_entry((cfg_entry**)&overclock->conf->cfg, section, "enable_overclocking", 1);
gtk_widget_set_sensitive(overclock->vbox, TRUE);
break;
case GTK_RESPONSE_NO:
case GTK_RESPONSE_DELETE_EVENT:
change_entry((cfg_entry**)&overclock->conf->cfg, section, "enable_overclocking", 0);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(overclock->chk_overclock), FALSE);
}
g_signal_connect_swapped(GTK_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), GTK_OBJECT(dialog));
gtk_widget_destroy(dialog);
}
else
{
change_entry((cfg_entry**)&overclock->conf->cfg, section, "enable_overclocking", 0);
gtk_widget_set_sensitive(overclock->vbox, FALSE);
#ifdef HAVE_NVCONTROL
if((nv_card->caps & COOLBITS_OVERCLOCKING) && (nv_card->state != STATE_LOWLEVEL))
{
NVSetAttribute(overclock->dpy, 0, 0, NV_GPU_OVERCLOCKING_STATE, 0);
}
#endif
}
}
void enable_fanspeed_adjustments(GtkToggleButton *button, NVThermal *thermal)
{
char *section = g_strdup_printf("hw%d", thermal->card->number);
cfg_entry *entry = lookup_entry((cfg_entry**)&thermal->conf->cfg, section, "enable_fanspeed_adjustments");
if(gtk_toggle_button_get_active(button))
{
GtkWidget *dialog;
if(entry)
{
/* The user enabled fanspeed adjustments during a previous session, so don't show any dialogs */
if(entry->value)
return;
}
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, "%s", "Adjusting the fanspeed of your videocard is dangerous and should only be done when you know what you are doing.\nAre you sure you want to enable fanspeed adjustments?");
int res = gtk_dialog_run(GTK_DIALOG(dialog));
switch(res)
{
case GTK_RESPONSE_YES:
change_entry((cfg_entry**)&thermal->conf->cfg, section, "enable_fanspeed_adjustments", 1);
gtk_widget_set_sensitive(thermal->vbx_dutycycle, TRUE);
break;
case GTK_RESPONSE_NO:
case GTK_RESPONSE_DELETE_EVENT:
change_entry((cfg_entry**)&thermal->conf->cfg, section, "enable_fanspeed_adjustments", 0);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(thermal->chk_fanspeed), FALSE);
}
g_signal_connect_swapped(GTK_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), GTK_OBJECT(dialog));
gtk_widget_destroy(dialog);
}
else
{
if(nv_card->caps & I2C_AUTOMATIC_FANSPEED_CONTROL)
nv_card->set_i2c_fanspeed_mode(nv_card->sensor, 0); /* Put the card back into automatic mode */
change_entry((cfg_entry**)&thermal->conf->cfg, section, "enable_fanspeed_adjustments", 0);
gtk_widget_set_sensitive(thermal->vbx_dutycycle, FALSE);
}
free(section);
}
void reset_speeds(GtkButton *button, gpointer data)
{
NVOverclock *overclock = NV_OVERCLOCK(data);
if(overclock->card->number != nv_card->number)
set_card(overclock->card->number);
nv_card->reset_gpu_speed();
nv_card->reset_memory_speed();
update_speeds(data);
}
/* Show a dialog using which the user can test the new clocks. If the clocks don't work
/ correctly the old ones will be restored.
*/
void test_speeds(gpointer data)
{
GtkWidget *label;
Timeout *timeout;
timeout = g_malloc(sizeof(Timeout));
timeout->dialog = GTK_DIALOG(gtk_dialog_new_with_buttons("Testing the new speeds",
GTK_WINDOW(NULL), GTK_DIALOG_MODAL, GTK_STOCK_YES, GTK_RESPONSE_ACCEPT,
GTK_STOCK_NO, GTK_RESPONSE_REJECT, NULL));
label = gtk_label_new("Are the new speeds working correctly?");
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(timeout->dialog)->vbox), label);
gtk_widget_show(label);
timeout->time = 5;
timeout->label = gtk_label_new("Timeout in: 5 second(s)");
gtk_container_add(GTK_CONTAINER(timeout->dialog->vbox), timeout->label);
gtk_widget_show(GTK_WIDGET(timeout->label));
/* Create the real timeout */
timeout->timeout_id = g_timeout_add(1000, timeout_callback, timeout);
gint result = gtk_dialog_run(GTK_DIALOG(timeout->dialog));
/* Stop the timer because we got an answer back */
g_source_remove(timeout->timeout_id);
/* We receive ACCEPT when the Yes button was pressed. In all other cases it is REJECT */
switch(result)
{
case GTK_RESPONSE_DELETE_EVENT:
case GTK_RESPONSE_REJECT:
/* Restore the default speeds */
reset_speeds(NULL, data);
break;
}
gtk_widget_destroy(GTK_WIDGET(timeout->dialog));
g_free(timeout);
}
/* This function updates the speeds on the gui. */
int update_speeds(GtkWidget *widget)
{
NVOverclock *overclock = NV_OVERCLOCK(widget);
/* When the widget isn't visible anymore, return FALSE to stop the calling of this function */
if(!GTK_WIDGET_MAPPED(overclock))
{
overclock->clock_changes = 0; /* Make sure the sliders aren't locked the next time we are visible */
return FALSE;
}
if(overclock->card->number != nv_card->number)
set_card(overclock->card->number);
if(overclock->clock_changes)
return TRUE;
overclock->clock_changes=0;
overclock->nvclk = nv_card->get_gpu_speed();
overclock->memclk = nv_card->get_memory_speed();
/* When the current clocks don't match the ones on the gui, update them */
if(overclock->nvclk != gtk_range_get_value(GTK_RANGE(overclock->scale_gpu)))
{
gtk_range_set_value(GTK_RANGE((overclock->scale_gpu)), overclock->nvclk);
}
if(overclock->memclk != gtk_range_get_value(GTK_RANGE(overclock->scale_mem)))
{
gtk_range_set_value(GTK_RANGE((overclock->scale_mem)), overclock->memclk);
}
return TRUE;
}
void chk_test_speeds_toggled(GtkToggleButton *button, gpointer data)
{
NVOverclock *overclock = NV_OVERCLOCK(data);
char *section = g_strdup_printf("hw%d", overclock->card->number);
change_entry(overclock->conf->cfg, section, "test_speeds", gtk_toggle_button_get_active(button));
}
/* When the overclock page is shown; update the clocks every second which is usefull for GeforceFX/Geforce6600GT cards
/ as for those the clocks change between 2d and 3d.
*/
void nv_overclock_mapped(GtkWidget *widget)
{
NVOverclock *overclock = NV_OVERCLOCK(widget);
if(overclock->card->number != nv_card->number)
set_card(overclock->card->number);
/* When the use_lowlevel_backend option is set, force LOWLEVEL */
if(overclock->conf->use_lowlevel_backend && overclock->combo_speeds)
{
nv_card->set_state(STATE_LOWLEVEL);
gtk_widget_set_sensitive(overclock->combo_speeds, 0);
}
/* When lowlevel is disabled, restore the correct state */
else if((nv_card->caps & COOLBITS_OVERCLOCKING) && !overclock->conf->use_lowlevel_backend && nv_card->state == STATE_LOWLEVEL)
{
gtk_widget_set_sensitive(overclock->combo_speeds, 1);
switch(gtk_combo_box_get_active(GTK_COMBO_BOX(overclock->combo_speeds)))
{
case 0:
nv_card->set_state(STATE_2D);
break;
case 1:
nv_card->set_state(STATE_3D);
break;
case 2:
nv_card->set_state(STATE_BOTH);
break;
}
}
g_timeout_add(1000, (GSourceFunc)update_speeds, overclock);
}
gboolean timeout_callback(gpointer data)
{
Timeout *timeout = (Timeout*)data;
GtkLabel *label = GTK_LABEL(timeout->label);
timeout->time--;
/* When we ran out of time simulate "No" */
if(timeout->time == 0)
{
gtk_dialog_response(timeout->dialog, GTK_RESPONSE_REJECT);
return FALSE;
}
/* Refresh the time */
gtk_label_set_text(label, g_strdup_printf("Timeout in: %d second(s)", timeout->time));
return TRUE;
}
gboolean thermal_update(NVThermal *thermal)
{
int core, ambient;
gchar *tmp;
/* When the widget isn't visible anymore, return FALSE to stop the calling of this function */
if(!GTK_WIDGET_MAPPED(thermal))
return FALSE;
if(thermal->card->number != nv_card->number)
set_card(thermal->card->number);
core = nv_card->get_gpu_temp(nv_card->sensor);
/* The progressbar can be set to values between 0 and 1. In the past its range could be set by
/ accessing its adjustment but that has been deprecated. To create a bar that goes from lets say
/ 25 to 110 we can, we need to have 25 correspond with 0 and 110 with 1. The first step is to substract
/ 25 from the value. Next 110-30 gives 85, to normalize that to 1 we need to divide by 85. The reason for
/ a range upto 110 is that because of driver bugs the Geforce6 can easily reach 100C.
*/
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(thermal->pbar_core), ((float)core-25)/85);
tmp = g_strdup_printf("%d C", core);
gtk_label_set_text(GTK_LABEL(thermal->lbl_core), tmp);
g_free(tmp);
if(nv_card->caps & BOARD_TEMP_MONITORING)
{
ambient = nv_card->get_board_temp(nv_card->sensor);
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(thermal->pbar_ambient), ((float)ambient-25)/85);
tmp = g_strdup_printf("%d C", ambient);
gtk_label_set_text(GTK_LABEL(thermal->lbl_ambient), tmp);
g_free(tmp);
}
/* Quit when there's no controllable fan */
if(!(nv_card->caps & (GPU_FANSPEED_MONITORING | I2C_FANSPEED_MONITORING)))
return TRUE;
/* Only update the scale when it doesn't have focus else you can never adjust the fanspeed */
if(GTK_WIDGET_HAS_FOCUS(thermal->scale_dutycycle))
{
/* Once the scale loses focus, the scale is quickly updated with the new value.
/ To allow fanspeed adjustments wait 'timeout' seconds before updating the sliders
/ else the user needs to click on Apply very quickly ;)
*/
thermal->timeout=3;
return TRUE;
}
if(thermal->timeout)
{
thermal->timeout--;
return TRUE;
}
/* First process cards with 'advanced' sensors as both I2C_/GPU_FANSPEED_MONITORING are set */
if(nv_card->caps & I2C_FANSPEED_MONITORING)
{
int fanspeed = nv_card->get_i2c_fanspeed_rpm(nv_card->sensor);
/* Set the fanspeed in the progress bar from 2000 to 6000 in RPM */
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(thermal->pbar_fanspeed), ((float)fanspeed-2000)/4000);
/* Set the fanspeed in RPM */
tmp = g_strdup_printf("%d RPM", fanspeed);
gtk_label_set_text(GTK_LABEL(thermal->lbl_fanspeed), tmp);
g_free(tmp);
gtk_range_set_value(GTK_RANGE((thermal->scale_dutycycle)), (float)nv_card->get_i2c_fanspeed_pwm(nv_card->sensor));
}
else if(nv_card->caps & GPU_FANSPEED_MONITORING)
{
gtk_range_set_value(GTK_RANGE((thermal->scale_dutycycle)), (float)nv_card->get_fanspeed());
}
return TRUE;
}
void nv_thermal_mapped(GtkWidget *thermal)
{
thermal_update(NV_THERMAL(thermal));
g_timeout_add(1000, (GSourceFunc)thermal_update, thermal);
}
void combo_speeds_changed(GtkComboBox *combo, gpointer data)
{
switch(gtk_combo_box_get_active(combo))
{
case 0:
nv_card->set_state(STATE_2D);
break;
case 1:
nv_card->set_state(STATE_3D);
break;
case 2:
nv_card->set_state(STATE_BOTH);
break;
}
NV_OVERCLOCK(data)->clock_changes = 0; /* Force the clocks to get updated */
}
/* When the gpu slider gets moved, set a flag that there are clock changes, so that our
/ refresh function won't update the clocks.
*/
void scale_gpu_changed(GtkToggleButton *button, gpointer data)
{
NVOverclock *overclock = NV_OVERCLOCK(data);
if(overclock->nvclk != gtk_range_get_value(GTK_RANGE((overclock->scale_gpu))))
overclock->clock_changes = 1;
}
/* When the memory slider gets moved, set a flag that there are clock changes, so that our
/ refresh function won't update the clocks.
*/
void scale_mem_changed(GtkToggleButton *button, gpointer data)
{
NVOverclock *overclock = NV_OVERCLOCK(data);
if(overclock->memclk != gtk_range_get_value(GTK_RANGE((overclock->scale_mem))))
overclock->clock_changes = 1;
}
gchar* value_to_mhz(GtkRange *range, gdouble value, int option)
{
return g_strdup_printf("%.3f MHz ", value);
}
gchar* value_to_percent(GtkRange *range, gdouble value, int option)
{
return g_strdup_printf("%.1f%%", value);
}
gchar* value_to_rpm(GtkRange *range, gdouble value, int option)
{
return g_strdup_printf("%.1f RPM", value);
}
void set_agp_info(GtkWidget *widget)
{
char *agprate;
NVAgp *agp = NV_AGP(widget);
if(agp->card->number != nv_card->number)
set_card(agp->card->number);
gtk_label_set_label(GTK_LABEL(agp->lbl_agp_txt), nv_card->get_agp_status());
agprate = g_strdup_printf("%dX", nv_card->get_bus_rate());
gtk_label_set_label(GTK_LABEL(agp->lbl_agprate_txt), agprate);
gtk_label_set_label(GTK_LABEL(agp->lbl_agprates_txt), nv_card->get_agp_supported_rates());
gtk_label_set_label(GTK_LABEL(agp->lbl_fw_txt), nv_card->get_agp_fw_status());
gtk_label_set_label(GTK_LABEL(agp->lbl_sba_txt), nv_card->get_agp_sba_status());
g_free(agprate);
}
/* Sets all Nvidia bios info */
void set_bios_info(GtkWidget *widget)
{
char *tmp;
int i;
NVBios *bios = NV_BIOS(widget);
GtkTreeIter iter;
gtk_label_set_label(GTK_LABEL(bios->lbl_signonmsg_txt), nv_card->bios->signon_msg);
for(i=0; i<nv_card->bios->perf_entries; i++)
{
int column = 2;
gchar *nvclk, *memclk;
if(nv_card->bios->perf_lst[i].delta)
nvclk = g_strdup_printf("%d(+%d) MHz", nv_card->bios->perf_lst[i].nvclk, nv_card->bios->perf_lst[i].delta);
else
nvclk = g_strdup_printf("%d MHz", nv_card->bios->perf_lst[i].nvclk);
memclk = g_strdup_printf("%d MHz", nv_card->bios->perf_lst[i].memclk);
gtk_tree_store_append(bios->store_perf, &iter, NULL);
gtk_tree_store_set(bios->store_perf, &iter, 0 /* column 0 */, nvclk, 1 /* column 1 */, memclk, -1 );
if(nv_card->bios->volt_entries)
{
gchar *voltage = g_strdup_printf("%.2f V", nv_card->bios->perf_lst[i].voltage);
gtk_tree_store_set(bios->store_perf, &iter, column, voltage, -1 );
g_free(voltage);
column++;
}
if(nv_card->bios->perf_lst[0].fanspeed)
{
gchar *fanspeed = g_strdup_printf("%d%%", nv_card->bios->perf_lst[i].fanspeed);
gtk_tree_store_set(bios->store_perf, &iter, column, fanspeed, -1 );
g_free(fanspeed);
column++;
}
g_free(nvclk);
g_free(memclk);
}
if(nv_card->bios->volt_entries)
gtk_label_set_label(GTK_LABEL(bios->lbl_volt), "Voltage Levels");
for(i=0; i<nv_card->bios->perf_entries; i++)
{
gchar *voltage, *vid;
voltage = g_strdup_printf("%.2f V", nv_card->bios->volt_lst[i].voltage);
vid = g_strdup_printf("%d", nv_card->bios->volt_lst[i].VID);
gtk_tree_store_append(bios->store_volt, &iter, NULL);
gtk_tree_store_set(bios->store_volt, &iter, 0 /* column 0 */, voltage, 1 /* column 1 */, vid, -1 );
g_free(voltage);
g_free(vid);
}
}
/* This function sets overclocking info like the min/max values of the sliders. */
void set_overclock_info(GtkWidget *widget)
{
NVOverclock *overclock = NV_OVERCLOCK(widget);
GtkAdjustment *adj_core = gtk_range_get_adjustment(GTK_RANGE(overclock->scale_gpu));
GtkAdjustment *adj_mem = gtk_range_get_adjustment(GTK_RANGE(overclock->scale_mem));
char *section = g_strdup_printf("hw%d", overclock->card->number);
cfg_entry *entry;
int overclocking = 0;
if((entry = lookup_entry((cfg_entry**)&overclock->conf->cfg, section, "enable_overclocking")))
{
overclocking = entry->value;
}
/* Force lowlevel backend if it was set in the config file */
if(overclock->conf->use_lowlevel_backend && overclock->combo_speeds)
{
nv_card->set_state(STATE_LOWLEVEL);
gtk_widget_set_sensitive(overclock->combo_speeds, 0);
}
else if(nv_card->caps & COOLBITS_OVERCLOCKING)
nv_card->set_state(STATE_2D); /* Default to 2D for the combo */
/* Disable overclocking for some types of hardware.
/ By default:
/ - Don't overclock mobile GPUs because it is more dangerous on this type of hardware
/ - Allow only gpu overclocking on Nforce boards because the memory is system memory which we can't overclock
*/
if(nv_card->gpu == NFORCE)
gtk_widget_set_sensitive(overclock->scale_mem, 0);
/* In case of GeforceFX/Geforce6 cards we use NV-CONTROL for now as it allows us to set 2d/3d clocks. */
if(nv_card->caps & COOLBITS_OVERCLOCKING)
{
int res=0;
#ifdef HAVE_NVCONTROL
int overclocking_enabled;
overclock->have_coolbits = NVGetAttribute(overclock->dpy, 0, 0, NV_GPU_OVERCLOCKING_STATE, &overclocking_enabled);
/* Enable overclocking when it was enabled in the config file */
if(overclocking && overclock->have_coolbits && !overclocking_enabled)
{
NVSetAttribute(overclock->dpy, 0, 0, NV_GPU_OVERCLOCKING_STATE, 1);
NVGetAttribute(overclock->dpy, 0, 0, NV_GPU_OVERCLOCKING_STATE, &overclocking_enabled);
}
/* Disable overclocking when it was disabled in the config file */
else if(!overclocking && overclock->have_coolbits && overclocking_enabled)
{
NVSetAttribute(overclock->dpy, 0, 0, NV_GPU_OVERCLOCKING_STATE, 0);
NVGetAttribute(overclock->dpy, 0, 0, NV_GPU_OVERCLOCKING_STATE, &overclocking_enabled);
}
if(overclock->have_coolbits && overclocking_enabled)
{
gtk_widget_set_sensitive(overclock->vbox, TRUE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(overclock->chk_overclock), TRUE);
res = 1;
}
#else
overclock->have_coolbits = 0;
#endif
if(!res)
{
gtk_widget_set_sensitive(overclock->vbox, FALSE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(overclock->chk_overclock), FALSE);
}
}
/* Disable mobile overclocking unless 'overclocking' is set */
else if(((nv_card->gpu == MOBILE && !overclocking) || (nv_card->caps == 0)))
{
gtk_widget_set_sensitive(overclock->vbox, FALSE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(overclock->chk_overclock), FALSE);
}
else
{
gtk_widget_set_sensitive(overclock->vbox, TRUE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(overclock->chk_overclock), TRUE);
}
adj_mem->lower = nv_card->memclk_min;
adj_mem->upper = nv_card->memclk_max;
adj_core->lower = nv_card->nvclk_min;
adj_core->upper = nv_card->nvclk_max;
if((entry = lookup_entry((cfg_entry**)&overclock->conf->cfg, section, "test_speeds")))
{
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(overclock->chk_test_speeds), entry->value);
}
/* Show the speeds on the gui; we can't use update_speeds as it doesn't work on invisible windows. (related to the update thread) */
gtk_range_set_value(GTK_RANGE((overclock->scale_gpu)), nv_card->get_gpu_speed());
gtk_range_set_value(GTK_RANGE((overclock->scale_mem)), nv_card->get_memory_speed());
}
enum pipe_columns
{
BIT_COLUMN,
DESC_COLUMN,
STATE_COLUMN,
MASKED_COLUMN,
N_PIPE_COLUMNS
};
void set_pipeline_info(GtkWidget *widget)
{
NVPipeline *pipeline = NV_PIPELINE(widget);
char *bit, *config, *desc, *masked, *state, *units;
char pmask, vmask;
int mask = 0; /* Mask containing all available units */
int hw_masked = 0; /* HW masked units */
int hw_state = 0; /* Currently activated units */
int punits, total; /* Number of pixel units and total number of pixel units per pipeline */
int i;
GtkTreeIter iter;
mask = nv_card->get_default_mask();
if(nv_card->get_hw_masked_units(&pmask, &vmask, 1))
hw_masked = (vmask << 8) | pmask;
punits = nv_card->get_pixel_pipelines(&pmask, 1, &total);
units = g_strdup_printf("Pixel: %dx%d\tVertex: %dx1", total, punits, nv_card->get_vertex_pipelines(&vmask, 1));
gtk_label_set_text(GTK_LABEL(pipeline->lbl_pipes_txt), units);
g_free(units);
hw_state = (vmask << 8) | pmask;
config = g_strdup_printf("0x%04X", hw_state);
gtk_label_set_text(GTK_LABEL(pipeline->lbl_config_txt), config);
g_free(config);
for(i=0; i<16; i++)
{
bit = g_strdup_printf("%d", i);
if((i < 8) && (mask & 1<<i))
{
desc = g_strdup_printf("Pixel unit %d", i);
if(hw_masked & 1<<i)
masked = g_strdup_printf("Yes");
else
masked = g_strdup_printf("-");
if(hw_state & 1<<i)
state = g_strdup_printf("Enabled");
else
state = g_strdup_printf("Disabled");
}
else if(i < 8)
{
desc = g_strdup_printf("-");
masked = g_strdup_printf("-");
state = g_strdup_printf("");
}
if((i >= 8) && (mask & 1<<i))
{
desc = g_strdup_printf("Vertex unit %d", i-8);
if(hw_masked & 1<<i)
masked = g_strdup_printf("Yes");
else
masked = g_strdup_printf("-");
if(hw_state & 1<<i)
state = g_strdup_printf("Enabled");
else
state = g_strdup_printf("Disabled");
}
else if(i >= 8)
{
desc = g_strdup_printf("-");
masked = g_strdup_printf("-");
state = g_strdup_printf("");
}
gtk_tree_store_append(pipeline->store, &iter, NULL);
gtk_tree_store_set(pipeline->store, &iter,
BIT_COLUMN, bit,
DESC_COLUMN, desc,
STATE_COLUMN, state,
MASKED_COLUMN, masked,
-1 );
g_free(bit);
g_free(desc);
g_free(state);
g_free(masked);
}
}
void set_thermal_info(GtkWidget *widget)
{
NVThermal *thermal = NV_THERMAL(widget);
char *section = g_strdup_printf("hw%d", thermal->card->number);
cfg_entry *entry;
gtk_label_set_label(GTK_LABEL(thermal->lbl_sensor_txt), nv_card->sensor_name);
if(nv_card->caps & (GPU_FANSPEED_MONITORING | I2C_FANSPEED_MONITORING))
{
if((entry = lookup_entry((cfg_entry**)&thermal->conf->cfg, section, "enable_fanspeed_adjustments")))
{
gtk_widget_set_sensitive(thermal->vbx_dutycycle, entry->value);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(thermal->chk_fanspeed), entry->value);
}
else
{
gtk_widget_set_sensitive(thermal->vbx_dutycycle, FALSE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(thermal->chk_fanspeed), FALSE);
}
}
}
void set_videocard_info(GtkWidget *widget)
{
char *arch, *bios, *vidmem, *irq, *mem_type;
NVInfo *info = NV_INFO(widget);
if(info->card->number != nv_card->number)
set_card(info->card->number);
gtk_label_set_label(GTK_LABEL(info->lbl_gpu_txt), nv_card->card_name);
arch = g_strdup_printf("NV%X %X", nv_card->get_gpu_architecture(), nv_card->get_gpu_revision());
gtk_label_set_label(GTK_LABEL(info->lbl_arch_txt), arch);
/* Bios dumping doesn't allways work correctly */
if(nv_card->bios)
gtk_label_set_label(GTK_LABEL(info->lbl_bios_txt), nv_card->bios->version);
else
{
bios = g_strdup_printf("Unknown");
gtk_label_set_label(GTK_LABEL(info->lbl_bios_txt), bios);
g_free(bios);
}
vidmem = g_strdup_printf("%d MB", nv_card->get_memory_size());
gtk_label_set_label(GTK_LABEL(info->lbl_vidmem_txt), vidmem);
if(strcmp(nv_card->get_bus_type(), "PCI-Express") == 0)
{
gchar* bus_type = g_strdup_printf("%s %dX", nv_card->get_bus_type(), nv_card->get_bus_rate());
gtk_label_set_label(GTK_LABEL(info->lbl_bustype_txt), bus_type);
g_free(bus_type);
}
else
gtk_label_set_label(GTK_LABEL(info->lbl_bustype_txt), nv_card->get_bus_type());
mem_type = g_strdup_printf("%d bit %s", nv_card->get_memory_width(), nv_card->get_memory_type());
gtk_label_set_label(GTK_LABEL(info->lbl_memtype_txt), mem_type);
irq = g_strdup_printf("%d", nv_card->irq);
gtk_label_set_label(GTK_LABEL(info->lbl_irq_txt), irq);
g_free(arch);
g_free(vidmem);
g_free(irq);
g_free(mem_type);
}
GtkWidget* nv_agp_new (NVCard *card)
{
NVAgp *agp = g_object_new (NV_TYPE_AGP, NULL);
agp->card = card;
agp->table = gtk_table_new(4,2, FALSE);
agp->frame = gtk_frame_new("AGP Information");
gtk_container_add(GTK_CONTAINER(agp->frame), agp->table);
gtk_table_set_col_spacings(GTK_TABLE(agp->table), 2);
gtk_table_set_row_spacings(GTK_TABLE(agp->table), 3);
agp->lbl_agp = gtk_label_new("AGP Status");
gtk_misc_set_alignment (GTK_MISC (agp->lbl_agp), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(agp->table), GTK_WIDGET(agp->lbl_agp), 0, 1, 0, 1,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
agp->lbl_agp_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (agp->lbl_agp_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(agp->table), GTK_WIDGET(agp->lbl_agp_txt), 1, 2, 0, 1,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
agp->lbl_agprate = gtk_label_new("AGP rate");
gtk_misc_set_alignment (GTK_MISC (agp->lbl_agprate), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(agp->table), GTK_WIDGET(agp->lbl_agprate), 0, 1, 1, 2,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
agp->lbl_agprate_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (agp->lbl_agprate_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(agp->table), GTK_WIDGET(agp->lbl_agprate_txt), 1, 2, 1, 2,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
agp->lbl_agprates = gtk_label_new("Supported AGP Rates");
gtk_misc_set_alignment (GTK_MISC (agp->lbl_agprates), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(agp->table), GTK_WIDGET(agp->lbl_agprates), 0, 1, 2, 3,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
agp->lbl_agprates_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (agp->lbl_agprates_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(agp->table), GTK_WIDGET(agp->lbl_agprates_txt), 1, 2, 2, 3,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
agp->lbl_fw = gtk_label_new("Fast Writes");
gtk_misc_set_alignment (GTK_MISC (agp->lbl_fw), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(agp->table), GTK_WIDGET(agp->lbl_fw), 0, 1, 3, 4,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
agp->lbl_fw_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (agp->lbl_fw_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(agp->table), GTK_WIDGET(agp->lbl_fw_txt), 1, 2, 3, 4,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
agp->lbl_sba = gtk_label_new("Sideband Addressing");
gtk_misc_set_alignment (GTK_MISC (agp->lbl_sba), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(agp->table), GTK_WIDGET(agp->lbl_sba), 0, 1, 4, 5,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
agp->lbl_sba_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (agp->lbl_sba_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(agp->table), GTK_WIDGET(agp->lbl_sba_txt), 1, 2, 4, 5,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
gtk_box_pack_start(GTK_BOX(agp), agp->frame, FALSE, FALSE, 0);
gtk_widget_show_all(GTK_WIDGET(agp));
set_agp_info(GTK_WIDGET(agp));
return GTK_WIDGET (agp);
}
GtkWidget* nv_bios_new (NVCard *card)
{
int column = 2;
NVBios *bios = g_object_new (NV_TYPE_BIOS, NULL);
bios->table = gtk_table_new(3,2, FALSE);
gtk_table_set_col_spacings(GTK_TABLE(bios->table), 2);
gtk_table_set_row_spacings(GTK_TABLE(bios->table), 3);
bios->frame = gtk_frame_new("VideoBios Information");
gtk_container_add(GTK_CONTAINER(bios->frame), bios->table);
bios->lbl_signonmsg = gtk_label_new("Title");
gtk_misc_set_alignment (GTK_MISC (bios->lbl_signonmsg), 0.02, 0);
gtk_table_attach (GTK_TABLE(bios->table), GTK_WIDGET(bios->lbl_signonmsg), 0, 1, 0, 1,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
bios->lbl_signonmsg_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (bios->lbl_signonmsg_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(bios->table), GTK_WIDGET(bios->lbl_signonmsg_txt), 1, 2, 0, 1,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
bios->lbl_perf = gtk_label_new("Perf. Levels");
gtk_misc_set_alignment (GTK_MISC (bios->lbl_perf), 0.02, 0);
gtk_table_attach (GTK_TABLE(bios->table), GTK_WIDGET(bios->lbl_perf), 0, 1, 1, 2,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
/* Create a treeview for storing the performance table */
bios->tree_view_perf = gtk_tree_view_new();
bios->store_perf = gtk_tree_store_new(N_PIPE_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING );
gtk_tree_view_set_model(GTK_TREE_VIEW(bios->tree_view_perf), GTK_TREE_MODEL(bios->store_perf));
/* Create GPU clock column */
bios->column_perf = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(bios->column_perf, "GPU");
bios->renderer_perf = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(bios->column_perf, bios->renderer_perf, FALSE);
gtk_tree_view_column_set_attributes(bios->column_perf, bios->renderer_perf, "text", 0, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(bios->tree_view_perf), bios->column_perf);
/* Create Memory clock column */
bios->column_perf = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(bios->column_perf, "Memory");
bios->renderer_perf = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(bios->column_perf, bios->renderer_perf, FALSE);
gtk_tree_view_column_set_attributes(bios->column_perf, bios->renderer_perf, "text", 1, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(bios->tree_view_perf), bios->column_perf);
/* Create GPU Voltage column if the bios contains voltage entires*/
if(card->bios->volt_entries)
{
bios->column_perf = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(bios->column_perf, "Voltage");
bios->renderer_perf = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(bios->column_perf, bios->renderer_perf, FALSE);
gtk_tree_view_column_set_attributes(bios->column_perf, bios->renderer_perf, "text", column, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(bios->tree_view_perf), bios->column_perf);
column++;
}
/* Create Fanspeed column if the bios contains duty cycle entires*/
if(card->bios->perf_lst[0].fanspeed)
{
bios->column_perf = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(bios->column_perf, "Fanspeed");
bios->renderer_perf = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(bios->column_perf, bios->renderer_perf, FALSE);
gtk_tree_view_column_set_attributes(bios->column_perf, bios->renderer_perf, "text", column, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(bios->tree_view_perf), bios->column_perf);
column++;
}
/* Allow an alternating color for the rows in the list */
g_object_set(bios->tree_view_perf, "rules-hint", TRUE, NULL);
gtk_table_attach (GTK_TABLE(bios->table), GTK_WIDGET(bios->tree_view_perf), 1, 2, 1, 2,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
bios->lbl_volt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (bios->lbl_volt), 0.02, 0);
gtk_table_attach (GTK_TABLE(bios->table), GTK_WIDGET(bios->lbl_volt), 0, 1, 2, 3,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
/* Create a treeview for storing the performance table */
bios->tree_view_volt = gtk_tree_view_new();
bios->store_volt = gtk_tree_store_new(N_PIPE_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING );
gtk_tree_view_set_model(GTK_TREE_VIEW(bios->tree_view_volt), GTK_TREE_MODEL(bios->store_volt));
/* Create GPU clock column */
bios->column_volt = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(bios->column_volt, "Voltage");
bios->renderer_volt = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(bios->column_volt, bios->renderer_volt, FALSE);
gtk_tree_view_column_set_attributes(bios->column_volt, bios->renderer_volt, "text", 0, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(bios->tree_view_volt), bios->column_volt);
bios->column_volt = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(bios->column_volt, "VID");
bios->renderer_volt = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(bios->column_volt, bios->renderer_volt, FALSE);
gtk_tree_view_column_set_attributes(bios->column_volt, bios->renderer_volt, "text", 1, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(bios->tree_view_volt), bios->column_volt);
/* Allow an alternating color for the rows in the list */
g_object_set(bios->tree_view_volt, "rules-hint", TRUE, NULL);
gtk_table_attach (GTK_TABLE(bios->table), GTK_WIDGET(bios->tree_view_volt), 1, 2, 2, 3,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
gtk_box_pack_start(GTK_BOX(bios), bios->frame, FALSE, FALSE, 0);
gtk_widget_show_all(GTK_WIDGET(bios));
set_bios_info(GTK_WIDGET(bios));
return GTK_WIDGET (bios);
}
GtkWidget* nv_info_new (NVCard *card)
{
NVInfo *info = g_object_new (NV_TYPE_INFO, NULL);
info->card = card;
info->table = gtk_table_new(7,2, FALSE);
info->frame = gtk_frame_new("Videocard Information");
gtk_container_add(GTK_CONTAINER(info->frame), info->table);
gtk_table_set_col_spacings(GTK_TABLE(info->table), 2);
gtk_table_set_row_spacings(GTK_TABLE(info->table), 3);
info->lbl_gpu = gtk_label_new("Graphics Processor");
gtk_misc_set_alignment (GTK_MISC (info->lbl_gpu), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(info->table), GTK_WIDGET(info->lbl_gpu), 0, 1, 0, 1,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
info->lbl_gpu_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (info->lbl_gpu_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(info->table), GTK_WIDGET(info->lbl_gpu_txt), 1, 2, 0, 1,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
info->lbl_arch = gtk_label_new("Architecture");
gtk_misc_set_alignment (GTK_MISC (info->lbl_arch), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(info->table), GTK_WIDGET(info->lbl_arch), 0, 1, 1, 2,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
info->lbl_arch_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (info->lbl_arch_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(info->table), GTK_WIDGET(info->lbl_arch_txt), 1, 2, 1, 2,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
info->lbl_bios = gtk_label_new("Bios Version");
gtk_misc_set_alignment (GTK_MISC (info->lbl_bios), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(info->table), GTK_WIDGET(info->lbl_bios), 0, 1, 2, 3,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
info->lbl_bios_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (info->lbl_bios_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(info->table), GTK_WIDGET(info->lbl_bios_txt), 1, 2, 2, 3,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
info->lbl_bustype = gtk_label_new("Bus Type");
gtk_misc_set_alignment (GTK_MISC (info->lbl_bustype), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(info->table), GTK_WIDGET(info->lbl_bustype), 0, 1, 3, 4,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
info->lbl_bustype_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (info->lbl_bustype_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(info->table), GTK_WIDGET(info->lbl_bustype_txt), 1, 2, 3, 4,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
info->lbl_vidmem = gtk_label_new("Video Memory");
gtk_misc_set_alignment (GTK_MISC (info->lbl_vidmem), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(info->table), GTK_WIDGET(info->lbl_vidmem), 0, 1, 4, 5,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
info->lbl_vidmem_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (info->lbl_vidmem_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(info->table), GTK_WIDGET(info->lbl_vidmem_txt), 1, 2, 4, 5,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
info->lbl_memtype = gtk_label_new("Memory Type");
gtk_misc_set_alignment (GTK_MISC (info->lbl_memtype), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(info->table), GTK_WIDGET(info->lbl_memtype), 0, 1, 5, 6,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
info->lbl_memtype_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (info->lbl_memtype_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(info->table), GTK_WIDGET(info->lbl_memtype_txt), 1, 2, 5, 6,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
info->lbl_irq = gtk_label_new("IRQ");
gtk_misc_set_alignment (GTK_MISC (info->lbl_irq), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(info->table), GTK_WIDGET(info->lbl_irq), 0, 1, 6, 7,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
info->lbl_irq_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (info->lbl_irq_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(info->table), GTK_WIDGET(info->lbl_irq_txt), 1, 2, 6, 7,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
gtk_box_pack_start(GTK_BOX(info), info->frame, FALSE, FALSE, 0);
gtk_widget_show_all(GTK_WIDGET(info));
set_videocard_info(GTK_WIDGET(info));
return GTK_WIDGET (info);
}
GtkWidget* nv_overclock_new (config *conf, GtkTooltips *tips, NVCard *card, void *dpy)
{
NVOverclock *overclock = g_object_new (NV_TYPE_OVERCLOCK, NULL);
GtkWidget *alignment;
overclock->card = card;
overclock->conf = conf;
overclock->clock_changes = 0;
overclock->memclk = 0;
overclock->nvclk = 0;
overclock->tips = tips;
#ifdef HAVE_NVCONTROL
overclock->dpy = (Display*)dpy;
#endif
/* Create a frame in which we will store all overclocking related stuff as it needs to be possible to disable overclocking */
overclock->frame = gtk_frame_new(NULL);
overclock->chk_overclock = gtk_check_button_new_with_label("Enable overclocking");
gtk_frame_set_label_widget(GTK_FRAME(overclock->frame), overclock->chk_overclock);
gtk_tooltips_set_tip(GTK_TOOLTIPS(overclock->tips), overclock->chk_overclock, \
"Through overclocking you can increase the performance of your videocard a lot. "
"While overclocking increases performance it comes at a great risk. The problem "
"is that the temperature of the GPU and memory increases a lot. Without proper "
"cooling this can seriously damage your hardware. Enabling of overclocking is "
"at your own risk!", NULL);
/* Vbox in which to store gpu/memory scales, overclock buttons .. */
overclock->vbox = gtk_vbox_new(FALSE, 3);
gtk_container_add(GTK_CONTAINER(overclock->frame), overclock->vbox);
gtk_container_set_border_width(GTK_CONTAINER(overclock->vbox), 2);
gtk_box_pack_start(GTK_BOX(overclock), overclock->frame, TRUE, TRUE, 0);
gtk_widget_set_sensitive(overclock->vbox, FALSE);
/* Overclocking of GeforceFX/Geforce6 hardware can happen through two backends. The first
/ uses the NV-CONTROL X extension and the other is a low-level backend. We try to default
/ to NV-CONTROL as it allows you to specify 2d/3d clocks. Note that for example MOBILE GPUs
/ aren't by NV-CONTROL.
/
/ To allow switching between 2d/3d clocks we need a combobox but only if Coolbits is supported.
*/
if(nv_card->caps & COOLBITS_OVERCLOCKING)
{
overclock->combo_speeds = gtk_combo_box_new_text();
gtk_combo_box_append_text(GTK_COMBO_BOX(overclock->combo_speeds), "2D Clocks");
gtk_combo_box_append_text(GTK_COMBO_BOX(overclock->combo_speeds), "3D Clocks");
gtk_combo_box_append_text(GTK_COMBO_BOX(overclock->combo_speeds), "2D + 3D Clocks");
gtk_combo_box_set_active(GTK_COMBO_BOX(overclock->combo_speeds), 0);
gtk_box_pack_start(GTK_BOX(overclock->vbox), overclock->combo_speeds, FALSE, FALSE, 0);
g_signal_connect(GTK_COMBO_BOX(overclock->combo_speeds), "changed", G_CALLBACK(combo_speeds_changed), overclock);
}
overclock->frm_gpu = gtk_frame_new("GPU clock");
gtk_box_pack_start(GTK_BOX(overclock->vbox), overclock->frm_gpu, FALSE, FALSE, 0);
overclock->scale_gpu = gtk_hscale_new_with_range(0, 100, 1);
gtk_tooltips_set_tip(GTK_TOOLTIPS(overclock->tips), overclock->scale_gpu, "Adjusts the clock frequency at which the GPU runs", NULL);
gtk_container_add(GTK_CONTAINER(overclock->frm_gpu), overclock->scale_gpu);
g_signal_connect(GTK_RANGE(overclock->scale_gpu), "format-value", G_CALLBACK(value_to_mhz), NULL);
g_signal_connect(GTK_RANGE(overclock->scale_gpu), "value-changed", G_CALLBACK(scale_gpu_changed), overclock);
gtk_scale_set_value_pos (GTK_SCALE (overclock->scale_gpu), GTK_POS_RIGHT);
overclock->frm_mem = gtk_frame_new("Memory clock");
gtk_box_pack_start(GTK_BOX(overclock->vbox), overclock->frm_mem, FALSE, FALSE, 0);
overclock->scale_mem = gtk_hscale_new_with_range(0, 100, 1);
gtk_tooltips_set_tip(GTK_TOOLTIPS(overclock->tips), overclock->scale_mem, "Adjusts the clock frequency at which the memory runs", NULL);
gtk_container_add(GTK_CONTAINER(overclock->frm_mem), overclock->scale_mem);
g_signal_connect(GTK_RANGE(overclock->scale_mem), "format-value", G_CALLBACK(value_to_mhz), NULL);
g_signal_connect(GTK_RANGE(overclock->scale_mem), "value-changed", G_CALLBACK(scale_mem_changed), overclock);
gtk_scale_set_value_pos (GTK_SCALE (overclock->scale_mem), GTK_POS_RIGHT);
overclock->chk_test_speeds = gtk_check_button_new_with_label("Test speeds before applying");
gtk_tooltips_set_tip(GTK_TOOLTIPS(overclock->tips), overclock->chk_test_speeds, \
"Test the clocks during a clock change. When the clocks don't work properly you can restore the previous ones.", NULL);
gtk_box_pack_start(GTK_BOX(overclock->vbox), overclock->chk_test_speeds, FALSE, FALSE, 10);
overclock->bbox = gtk_hbutton_box_new();
gtk_box_set_spacing(GTK_BOX(overclock->bbox), 5);
alignment = gtk_alignment_new(1, 1, 0, 0);
gtk_container_add(GTK_CONTAINER(alignment), overclock->bbox);
gtk_box_pack_start(GTK_BOX(overclock->vbox), alignment, TRUE, TRUE, 0);
/* Change Speeds button */
overclock->btn_change_speeds = gtk_button_new_with_label("Change Speeds");
gtk_tooltips_set_tip(GTK_TOOLTIPS(overclock->tips), overclock->btn_change_speeds, "Apply any GPU/memory clock changes", NULL);
gtk_container_add(GTK_CONTAINER(overclock->bbox), overclock->btn_change_speeds);
overclock->btn_reset_speeds = gtk_button_new_with_label("Reset Speeds");
gtk_tooltips_set_tip(GTK_TOOLTIPS(overclock->tips), overclock->btn_reset_speeds, "Restore the original GPU/memory clocks", NULL);
gtk_container_add(GTK_CONTAINER(overclock->bbox), overclock->btn_reset_speeds);
gtk_button_box_set_layout(GTK_BUTTON_BOX(overclock->bbox), GTK_BUTTONBOX_END);
gtk_widget_show_all(GTK_WIDGET(overclock));
set_overclock_info(GTK_WIDGET(overclock));
g_signal_connect(G_OBJECT(overclock->btn_change_speeds), "clicked", G_CALLBACK(change_speeds), overclock);
g_signal_connect(G_OBJECT(overclock->btn_reset_speeds), "clicked", G_CALLBACK(reset_speeds), overclock);
g_signal_connect(GTK_TOGGLE_BUTTON(overclock->chk_overclock), "toggled", G_CALLBACK (enable_overclocking), overclock);
g_signal_connect(GTK_TOGGLE_BUTTON(overclock->chk_test_speeds), "toggled", G_CALLBACK (chk_test_speeds_toggled), overclock);
g_signal_connect(overclock, "map", G_CALLBACK(nv_overclock_mapped), NULL);
return GTK_WIDGET (overclock);
}
GtkWidget *nv_pipeline_new(config *conf, NVCard *card)
{
NVPipeline *pipeline = g_object_new(NV_TYPE_PIPELINE, NULL);
pipeline->frame = gtk_frame_new("Pipeline information");
gtk_box_pack_start(GTK_BOX(pipeline), pipeline->frame, FALSE, FALSE, 2);
pipeline->table = gtk_table_new(2,2, FALSE);
gtk_table_set_col_spacings(GTK_TABLE(pipeline->table), 2);
gtk_table_set_row_spacings(GTK_TABLE(pipeline->table), 3);
gtk_container_add(GTK_CONTAINER(pipeline->frame), pipeline->table);
pipeline->lbl_pipes = gtk_label_new("Active units");
gtk_misc_set_alignment (GTK_MISC (pipeline->lbl_pipes), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(pipeline->table), GTK_WIDGET(pipeline->lbl_pipes), 0, 1, 0, 1,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
pipeline->lbl_pipes_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (pipeline->lbl_pipes_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(pipeline->table), GTK_WIDGET(pipeline->lbl_pipes_txt), 1, 2, 0, 1,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
pipeline->lbl_config = gtk_label_new("Configuration");
gtk_misc_set_alignment (GTK_MISC (pipeline->lbl_config), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(pipeline->table), GTK_WIDGET(pipeline->lbl_config), 0, 1, 1, 2,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
pipeline->lbl_config_txt = gtk_label_new("");
gtk_misc_set_alignment (GTK_MISC (pipeline->lbl_config_txt), 0.02, 0.5);
gtk_table_attach (GTK_TABLE(pipeline->table), GTK_WIDGET(pipeline->lbl_config_txt), 1, 2, 1, 2,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 3, 0);
pipeline->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
pipeline->tree_view = gtk_tree_view_new();
pipeline->store = gtk_tree_store_new(N_PIPE_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING );
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW (pipeline->scrolled_window), pipeline->tree_view);
/* Only show vertical scrollbars when needed */
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pipeline->scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_tree_view_set_model(GTK_TREE_VIEW(pipeline->tree_view), GTK_TREE_MODEL(pipeline->store));
pipeline->column = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(pipeline->column, "Bit");
pipeline->renderer = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(pipeline->column, pipeline->renderer, FALSE);
gtk_tree_view_column_set_attributes(pipeline->column, pipeline->renderer, "text", BIT_COLUMN, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(pipeline->tree_view), pipeline->column);
pipeline->column = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(pipeline->column, "Description");
pipeline->renderer = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(pipeline->column, pipeline->renderer, FALSE);
gtk_tree_view_column_set_attributes(pipeline->column, pipeline->renderer, "text", DESC_COLUMN, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(pipeline->tree_view), pipeline->column);
pipeline->column = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(pipeline->column, "State");
pipeline->renderer = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(pipeline->column, pipeline->renderer, FALSE);
gtk_tree_view_column_set_attributes(pipeline->column, pipeline->renderer, "text", STATE_COLUMN, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(pipeline->tree_view), pipeline->column);
pipeline->column = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(pipeline->column, "HW Masked");
pipeline->renderer = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(pipeline->column, pipeline->renderer, FALSE);
gtk_tree_view_column_set_attributes(pipeline->column, pipeline->renderer,"text", MASKED_COLUMN, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(pipeline->tree_view), pipeline->column);
/* Allow an alternating color for the rows in the list */
g_object_set(pipeline->tree_view, "rules-hint", TRUE, NULL);
gtk_box_pack_start(GTK_BOX(pipeline), pipeline->scrolled_window, TRUE, TRUE, 2);
gtk_widget_show_all(GTK_WIDGET(pipeline));
set_pipeline_info(GTK_WIDGET(pipeline));
return GTK_WIDGET(pipeline);
}
GtkWidget *nv_thermal_new(config *conf, GtkTooltips *tips, NVCard *card)
{
NVThermal *thermal = g_object_new(NV_TYPE_THERMAL, NULL);
GtkWidget *hbox;
int have_ambient;
thermal->card = card;
thermal->conf = conf;
thermal->tips = tips;
thermal->frame = gtk_frame_new("Sensor information");
gtk_box_pack_start(GTK_BOX(thermal), thermal->frame, FALSE, FALSE, 0);
thermal->vbox = gtk_vbox_new(FALSE, 2);
gtk_container_set_border_width(GTK_CONTAINER(thermal->vbox), 2);
gtk_container_add(GTK_CONTAINER(thermal->frame), thermal->vbox);
hbox = gtk_hbox_new(FALSE, 2);
thermal->lbl_sensor = gtk_label_new("Sensor chip ");
gtk_misc_set_alignment(GTK_MISC(thermal->lbl_sensor), 0.02, 0.5);
gtk_box_pack_start(GTK_BOX(hbox), thermal->lbl_sensor, FALSE, FALSE, 0);
thermal->lbl_sensor_txt = gtk_label_new("");
gtk_misc_set_alignment(GTK_MISC(thermal->lbl_sensor_txt), 0.02, 0.5);
gtk_box_pack_start(GTK_BOX(hbox), thermal->lbl_sensor_txt, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(thermal->vbox), hbox, FALSE, FALSE, 0);
thermal->frm_core = gtk_frame_new("GPU Temperature");
hbox = gtk_hbox_new(FALSE, 2);
gtk_container_add(GTK_CONTAINER(thermal->frm_core), hbox);
thermal->pbar_core = gtk_progress_bar_new();
thermal->lbl_core = gtk_label_new("");
gtk_box_pack_start(GTK_BOX(hbox), thermal->pbar_core, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), thermal->lbl_core, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(thermal->vbox), thermal->frm_core, FALSE, FALSE, 0);
gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
if(nv_card->caps & BOARD_TEMP_MONITORING)
{
thermal->frm_ambient = gtk_frame_new("Ambient Temperature");
hbox = gtk_hbox_new(FALSE, 2);
thermal->pbar_ambient = gtk_progress_bar_new();
thermal->lbl_ambient = gtk_label_new("");
gtk_container_add(GTK_CONTAINER(thermal->frm_ambient), hbox);
gtk_box_pack_start(GTK_BOX(hbox), thermal->pbar_ambient, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), thermal->lbl_ambient, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(thermal->vbox), thermal->frm_ambient, FALSE, FALSE, 0);
gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
}
/* Create a frame containing the 'real' fanspeed in RPM which is supported on some i2c sensors */
if(nv_card->caps & I2C_FANSPEED_MONITORING)
{
thermal->frm_fanspeed = gtk_frame_new("Fanspeed");
hbox = gtk_hbox_new(FALSE, 2);
thermal->pbar_fanspeed = gtk_progress_bar_new();
thermal->lbl_fanspeed = gtk_label_new("");
gtk_container_add(GTK_CONTAINER(thermal->frm_fanspeed), hbox);
gtk_box_pack_start(GTK_BOX(hbox), thermal->pbar_fanspeed, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), thermal->lbl_fanspeed, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(thermal->vbox), thermal->frm_fanspeed, FALSE, FALSE, 0);
gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
}
/* Create a frame with a slider using which fanspeed can be adjusted by changing the duty cycle */
if(nv_card->caps & (GPU_FANSPEED_MONITORING | I2C_FANSPEED_MONITORING))
{
GtkWidget *alignment;
thermal->frm_fanspeed = gtk_frame_new(NULL);
gtk_box_pack_start(GTK_BOX(thermal), thermal->frm_fanspeed, FALSE, FALSE, 0);
thermal->chk_fanspeed = gtk_check_button_new_with_label("Enable fanspeed adjustments");
gtk_tooltips_set_tip(GTK_TOOLTIPS(thermal->tips), thermal->chk_fanspeed, "Various cards feature the ability to adjust the speed of the fans on the card to reduce noise / increase cooling.", NULL);
gtk_frame_set_label_widget(GTK_FRAME(thermal->frm_fanspeed), thermal->chk_fanspeed);
g_signal_connect(GTK_TOGGLE_BUTTON(thermal->chk_fanspeed), "toggled", G_CALLBACK (enable_fanspeed_adjustments), thermal);
thermal->frm_dutycycle = gtk_frame_new("Fan - Duty cycle");
gtk_container_set_border_width(GTK_CONTAINER(thermal->frm_dutycycle), 2);
gtk_container_add(GTK_CONTAINER(thermal->frm_fanspeed), thermal->frm_dutycycle);
thermal->vbx_dutycycle = gtk_vbox_new(FALSE, 2);
gtk_container_add(GTK_CONTAINER(thermal->frm_dutycycle), thermal->vbx_dutycycle);
thermal->scale_dutycycle = gtk_hscale_new_with_range(0, 100, .1);
gtk_tooltips_set_tip(GTK_TOOLTIPS(thermal->tips), thermal->scale_dutycycle, \
"Using this option you can adjust the duty cycle of the fanspeed.\n\n"
"Note that the duty cycle is NOT the fanspeed. The duty cycle controls "
"the percentage of time in a fixed time interval in which the fan is 'on'. "
"By choosing a higher value the fan is enabled a larger part of the time "
"which results in a higher fanspeed. Changing the duty cycle from 20% to 40% "
"doesn't double the noise or fanspeed.\n", NULL);
gtk_scale_set_value_pos (GTK_SCALE (thermal->scale_dutycycle), GTK_POS_RIGHT);
gtk_box_pack_start(GTK_BOX(thermal->vbx_dutycycle), thermal->scale_dutycycle, FALSE, FALSE, 0);
g_signal_connect(GTK_RANGE(thermal->scale_dutycycle), "format-value", G_CALLBACK(value_to_percent), NULL);
thermal->bbox = gtk_hbutton_box_new();
gtk_box_set_spacing(GTK_BOX(thermal->bbox), 5);
alignment = gtk_alignment_new(1, 1, 0, 0);
gtk_container_add(GTK_CONTAINER(alignment), thermal->bbox);
gtk_box_pack_start(GTK_BOX(thermal->vbx_dutycycle), alignment, FALSE, FALSE, 0);
thermal->btn_apply = gtk_button_new_with_label("Apply");
gtk_tooltips_set_tip(GTK_TOOLTIPS(thermal->tips), thermal->btn_apply, "Apply fanspeed changes.", NULL);
gtk_container_add(GTK_CONTAINER(thermal->bbox), thermal->btn_apply);
g_signal_connect(G_OBJECT(thermal->btn_apply), "clicked", G_CALLBACK(change_fanspeed), thermal);
}
gtk_widget_show_all(GTK_WIDGET(thermal));
/* Makes sure the temperature gets updated every second */
g_signal_connect(thermal, "map", G_CALLBACK(nv_thermal_mapped), NULL);
set_thermal_info(GTK_WIDGET(thermal));
return GTK_WIDGET(thermal);
}
int gui_hw_init(config *conf, GtkTooltips *tips)
{
GtkTreeIter parent, child;
int i;
#ifdef HAVE_NVCONTROL
int irq=0;
Display *dpy = XOpenDisplay("");
/* If opengl stuff isn't supported don't show it on the gui */
if(init_nvcontrol(dpy))
{
int tmp;
NVGetAttribute(dpy, 0, 0, NV_IRQ, &irq);
}
#else
void *dpy;
#endif
for(i=0; i < nvclock.num_cards; i++)
{
set_card(i);
add(&parent, NULL, nvclock.card[i].card_name, BANNER_HW, nv_info_new(&nvclock.card[i]));
add(&child, &parent, "Overclocking", BANNER_HW, nv_overclock_new(conf, tips, &nvclock.card[i], dpy));
/* fixme: backend should know about the bustype; if pci we shouldn't show agp */
if(strcmp(nv_card->get_bus_type(), "AGP") == 0)
add(&child, &parent, "AGP", BANNER_HW, nv_agp_new(&nvclock.card[i]));
/* Show currently only bios info for recent models and if there's a bios dump available */
if(nv_card->bios)
if(nv_card->bios->perf_entries)
add(&child, &parent, "VideoBios", BANNER_HW, nv_bios_new(&nvclock.card[i]));
if(nv_card->caps & GPU_TEMP_MONITORING)
add(&child, &parent, "Hardware Monitoring", BANNER_HW, nv_thermal_new(conf, tips, &nvclock.card[i]));
if(nv_card->arch & NV4X)
add(&child, &parent, "Pipelines", BANNER_HW, nv_pipeline_new(conf, &nvclock.card[i]));
}
return 1;
}
syntax highlighted by Code2HTML, v. 0.9.1