summaryrefslogtreecommitdiffstats
path: root/src/sources/nvidiathermalsrc.cpp
blob: 7cd2eeefcee153438109a96df07561e6b5ade34f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/***************************************************************************
 *   Copyright (C) 2007 by Ken Werner                                      *
 *   [email protected]                                                     *
 *                                                                         *
 *   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.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/

#include "nvidiathermalsrc.h"
#include <tqstringlist.h>
#include <tqregexp.h>
#include <tdelocale.h>
#include <kdebug.h>

#ifndef HAVE_NVCONTROL
    #include <kprocio.h>
#else
    #include <tqpaintdevice.h> // for the Device* pointer
    
    // include the NVCtrl include stuff
    #include <X11/Xlib.h>
    #include <fixx11h.h> // needed for TQt, to include X11 header
extern "C" {
    #include <NVCtrlLib.h>
}
#endif

#ifndef HAVE_NVCONTROL
NVidiaThermalSrc::NVidiaThermalSrc(TQWidget* inParent, const TQString& inID, const TQString& inName):
		LabelSource(inParent), mProcess(0) {
#else
NVidiaThermalSrc::NVidiaThermalSrc(TQWidget* inParent, const TQString& inID, const TQString& inName, unsigned int attrib):
        LabelSource(inParent), mAttrib(attrib) {
#endif
	mID = inID;
    mName = inName;
	mDescription = i18n("This source is provided by the nVidia GPU card driver tools");

	mRefreshTimer = new TQTimer(this, "default refresh handler" );
	// connect the timer
	connect(mRefreshTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(fetchValue()));
	connect(this, TQ_SIGNAL(enabledChanged(bool, Source*)), this, TQ_SLOT(enable(bool)));
}

NVidiaThermalSrc::~NVidiaThermalSrc(){
#ifndef HAVE_NVCONTROL
	delete mProcess;
#endif
}

std::list<Source*>NVidiaThermalSrc::createInstances(TQWidget* inParent){
	std::list<Source*> list;
#ifndef HAVE_NVCONTROL 
	// see if the path contains nvidia-settings. if yes, 
	// execute it and look for the query type "GPUCoreTemp"
	// and "GPUAmbientTemp" and create two instances for each
	// of them
	// start nvidia-settings, if available and wait for it to exit.
	KProcIO proc;
    proc << "nvidia-settings"
	     << "-n" // don't load config
	     << "-q" << "GPUCoreTemp"
	     << "-q" << "GPUAmbientTemp";
	if(!proc.start(TDEProcess::Block))
		return list;
	
	// now see what it printed...
    TQString ln;
    TQString pout;
    while(proc.readln(ln) != -1)
        pout+= ln + '\n';

	if(pout.contains("Attribute 'GPUCoreTemp'"))
		list.push_back(new NVidiaThermalSrc(inParent, "GPUCoreTemp", "NVidiaCore"));
	if(pout.contains("Attribute 'GPUAmbientTemp'"))
		list.push_back(new NVidiaThermalSrc(inParent, "GPUAmbientTemp", "NVidiaAmbient"));
#else
    int evt_base = 0, err_base = 0, temp;
    Display * dpy = TQPaintDevice::x11AppDisplay();
    
    // do we have the XNVCtrl extension loaded?
    if(!XNVCTRLQueryExtension(dpy, &evt_base, &err_base))
        return list;
    
    // core temp support?
    if(XNVCTRLQueryAttribute (dpy, 0, 0, 
       NV_CTRL_GPU_CORE_TEMPERATURE, &temp)
      )
         list.push_back(new NVidiaThermalSrc(inParent, "GPUCoreTemp", "NVidiaCore",
                        NV_CTRL_GPU_CORE_TEMPERATURE));
    
    // ambient temp support?
    if(XNVCTRLQueryAttribute (dpy, 0, 0, 
       NV_CTRL_AMBIENT_TEMPERATURE, &temp)
      )
         list.push_back(new NVidiaThermalSrc(inParent, "GPUAmbientTemp", "NVidiaAmbient",
                        NV_CTRL_AMBIENT_TEMPERATURE));
#endif
	return list;
}

void NVidiaThermalSrc::enable(bool inEnable){
	if(inEnable && !mRefreshTimer->isActive()){ // start the timer
		fetchValue();
		mRefreshTimer->start(3000);
	}else if(!inEnable && mRefreshTimer->isActive()) // stops the timer
		mRefreshTimer->stop();
}


void NVidiaThermalSrc::evaluateStdout(){
#ifndef HAVE_NVCONTROL
		TQString val = i18n("n/a");
        
        // now see what it printed...
        TQString ln;
        TQString pout;
        while(mProcess->readln(ln) != -1)
            pout+= ln + '\n';
		TQRegExp regexp("Attribute\\s'" + mID + "'.*(\\d+)\\.");
		if(regexp.search(pout) != -1)
		    val = formatTemperature(regexp.cap(1));
		mValue = val;
		emit valueUpdated(mValue); // calls updateLabel(mValue) of LabelSource
        
        // delete the object, to be ready for a new run
        delete mProcess;
        mProcess = 0;
#endif
}

#ifndef HAVE_NVCONTROL
void NVidiaThermalSrc::createProcess() {
    mProcess = new KProcIO;
    connect(mProcess, TQ_SIGNAL(processExited(TDEProcess*)), this, TQ_SLOT(evaluateStdout()));
    *mProcess << "nvidia-settings" << "-n"
                << "-q" << mID;
}
#endif

TQString NVidiaThermalSrc::fetchValue(){
#ifndef HAVE_NVCONTROL
	if(!mProcess) {
        createProcess();
		if(!mProcess->start()) {
			mValue = "n/a";
            delete mProcess;
            mProcess = 0;
        }
    }
	return getValue();
#else
    int temp;
    Display * dpy = TQPaintDevice::x11AppDisplay();
    if(XNVCTRLQueryAttribute (dpy, 0, 0, mAttrib, &temp))
        mValue = formatTemperature(TQString::number(temp));
    else
        mValue = "n/a";
    emit valueUpdated(mValue); // calls updateLabel(mValue) of LabelSource
    return mValue;
#endif
}
#include "nvidiathermalsrc.moc"