summaryrefslogtreecommitdiff
authorschurig <schurig>2004-09-10 12:18:17 (UTC)
committer schurig <schurig>2004-09-10 12:18:17 (UTC)
commit9d0ccc1c5ca687bc017b2b515a9d3a47e98ce521 (patch) (side-by-side diff)
tree53927c6a19c69d54bb3d0e092ac57180bcb60222
parented70ec4945c7816ec6e899207ec8b99e20e10da5 (diff)
downloadopie-9d0ccc1c5ca687bc017b2b515a9d3a47e98ce521.zip
opie-9d0ccc1c5ca687bc017b2b515a9d3a47e98ce521.tar.gz
opie-9d0ccc1c5ca687bc017b2b515a9d3a47e98ce521.tar.bz2
added support for DEVFS
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/applets/vmemo/vmemo.cpp10
-rw-r--r--core/applets/vtapplet/vt.cpp8
-rw-r--r--libopie/odevice.cpp4
-rw-r--r--libopie2/opiemm/osoundsystem.cpp5
-rw-r--r--library/qpeapplication.cpp16
5 files changed, 40 insertions, 3 deletions
diff --git a/core/applets/vmemo/vmemo.cpp b/core/applets/vmemo/vmemo.cpp
index e747a19..07ef15c 100644
--- a/core/applets/vmemo/vmemo.cpp
+++ b/core/applets/vmemo/vmemo.cpp
@@ -30,636 +30,640 @@ extern "C" {
typedef struct _waveheader {
u_long main_chunk; /* 'RIFF' */
u_long length; /* filelen */
u_long chunk_type; /* 'WAVE' */
u_long sub_chunk; /* 'fmt ' */
u_long sc_len; /* length of sub_chunk, =16
(chunckSize) format len */
u_short format; /* should be 1 for PCM-code (formatTag) */
u_short modus; /* 1 Mono, 2 Stereo (channels) */
u_long sample_fq; /* samples per second (samplesPerSecond) */
u_long byte_p_sec; /* avg bytes per second (avgBytePerSecond) */
u_short byte_p_spl; /* samplesize; 1 or 2 bytes (blockAlign) */
u_short bit_p_spl; /* 8, 12 or 16 bit (bitsPerSample) */
u_long data_chunk; /* 'data' */
u_long data_length;/* samplecount */
} WaveHeader;
#define RIFF 0x46464952
#define WAVE 0x45564157
#define FMT 0x20746D66
#define DATA 0x61746164
#define PCM_CODE 1
#define WAVE_MONO 1
#define WAVE_STEREO 2
struct adpcm_state encoder_state;
//struct adpcm_state decoder_state;
#define WAVE_FORMAT_DVI_ADPCM (0x0011)
#define WAVE_FORMAT_PCM (0x0001)
#include "vmemo.h"
#include <opie2/otaskbarapplet.h>
#include <qpe/qpeapplication.h>
#include <qpe/config.h>
#include <qpainter.h>
#include <qmessagebox.h>
int seq = 0;
/* XPM */
static char * vmemo_xpm[] = {
"16 16 102 2",
" c None",
". c #60636A",
"+ c #6E6E72",
"@ c #68696E",
"# c #4D525C",
"$ c #6B6C70",
"% c #E3E3E8",
"& c #EEEEF2",
"* c #EAEAEF",
"= c #CACAD0",
"- c #474A51",
"; c #171819",
"> c #9B9B9F",
", c #EBEBF0",
"' c #F4F4F7",
") c #F1F1F5",
"! c #DEDEE4",
"~ c #57575C",
"{ c #010101",
"] c #A2A2A6",
"^ c #747477",
"/ c #B5B5B8",
"( c #AEAEB2",
"_ c #69696D",
": c #525256",
"< c #181C24",
"[ c #97979B",
"} c #A7A7AC",
"| c #B0B0B4",
"1 c #C8C8D1",
"2 c #75757B",
"3 c #46464A",
"4 c #494A4F",
"5 c #323234",
"6 c #909095",
"7 c #39393B",
"8 c #757578",
"9 c #87878E",
"0 c #222224",
"a c #414144",
"b c #6A6A6E",
"c c #020C16",
"d c #6B6B6F",
"e c #68686D",
"f c #5B5B60",
"g c #8A8A8F",
"h c #6B6B6E",
"i c #ADADB2",
"j c #828289",
"k c #3E3E41",
"l c #CFCFD7",
"m c #4C4C50",
"n c #000000",
"o c #66666A",
"p c #505054",
"q c #838388",
"r c #A1A1A7",
"s c #A9A9AE",
"t c #A8A8B0",
"u c #5E5E63",
"v c #3A3A3E",
"w c #BDBDC6",
"x c #59595E",
"y c #76767C",
"z c #373738",
"A c #717174",
"B c #727278",
"C c #1C1C1E",
"D c #3C3C3F",
"E c #ADADB6",
"F c #54555A",
"G c #8B8C94",
"H c #5A5A5F",
"I c #BBBBC3",
"J c #C4C4CB",
"K c #909098",
"L c #737379",
"M c #343437",
"N c #8F8F98",
"O c #000407",
"P c #2D3137",
"Q c #B0B1BC",
"R c #3B3C40",
"S c #6E6E74",
"T c #95959C",
"U c #74747A",
"V c #1D1D1E",
"W c #91929A",
"X c #42444A",
"Y c #22282E",
"Z c #B0B2BC",
"` c #898A90",
" . c #65656A",
".. c #999AA2",
"+. c #52535A",
"@. c #151B21",
"#. c #515257",
"$. c #B5B5BE",
"%. c #616167",
"&. c #1A1D22",
"*. c #000713",
"=. c #1F1F21",
" ",
" . + @ # ",
" $ % & * = - ",
" ; > , ' ) ! ~ ",
" { ] ^ / ( _ : ",
" < [ } | 1 2 3 ",
" 4 5 6 7 8 9 0 a b c ",
" d e f g h i j 3 k l m n ",
" o p q r s t u v w n ",
" o x y z A B C D E n ",
" F G H I J K L M N O ",
" P Q R S T U V W X ",
" Y Z ` b ...+. ",
" @.#.$.%.&. ",
" *.B =. ",
" n n n n n n n n n "};
using namespace Opie::Ui;
VMemo::VMemo( QWidget *parent, const char *_name )
: QWidget( parent, _name ) {
setFixedHeight( 18 );
setFixedWidth( 14 );
t_timer = new QTimer( this );
connect( t_timer, SIGNAL( timeout() ), SLOT( timerBreak() ) );
Config vmCfg("Vmemo");
vmCfg.setGroup("Defaults");
int toggleKey = setToggleButton(vmCfg.readNumEntry("toggleKey", -1));
useADPCM = vmCfg.readBoolEntry("use_ADPCM", 0);
odebug << "toggleKey " << toggleKey << "" << oendl;
// if ( QFile::exists ( "/dev/sharp_buz" ) || QFile::exists ( "/dev/sharp_led" ))
// systemZaurus=TRUE;
// else
systemZaurus = FALSE;
myChannel = new QCopChannel( "QPE/VMemo", this );
connect( myChannel, SIGNAL(received(const QCString&,const QByteArray&)),
this, SLOT(receive(const QCString&,const QByteArray&)) );
if( toggleKey != -1 ) {
odebug << "Register key " << toggleKey << "" << oendl;
QCopEnvelope e("QPE/Launcher", "keyRegister(int,QCString,QCString)");
// e << 4096; // Key_Escape
// e << Key_F5; //4148
e << toggleKey;
e << QString("QPE/VMemo");
e << QString("toggleRecord()");
}
if(toggleKey == 1)
usingIcon = TRUE;
else
usingIcon = FALSE;
// if( vmCfg.readNumEntry("hideIcon",0) == 1)
if (!usingIcon)
hide();
recording = FALSE;
// }
}
VMemo::~VMemo() {
}
int VMemo::position()
{
return 6;
}
void VMemo::receive( const QCString &msg, const QByteArray &data ) {
odebug << "Vmemo receive" << oendl;
QDataStream stream( data, IO_ReadOnly );
if (msg == "toggleRecord()") {
if (recording) {
fromToggle = TRUE;
stopRecording();
} else {
fromToggle = TRUE;
startRecording();
}
}
}
void VMemo::paintEvent( QPaintEvent* ) {
QPainter p(this);
p.drawPixmap( 0, 1,( const char** ) vmemo_xpm );
}
void VMemo::mousePressEvent( QMouseEvent * /*me*/) {
/* No mousePress/mouseRelease recording on the iPAQ. The REC button on the iPAQ calls these functions
mousePressEvent and mouseReleaseEvent with a NULL parameter. */
// if (!systemZaurus && me != NULL)
// return;
// }
if(!recording)
startRecording();
else
stopRecording();
}
void VMemo::mouseReleaseEvent( QMouseEvent * ) {
}
bool VMemo::startRecording() {
Config config( "Vmemo" );
config.setGroup( "System" );
useAlerts = config.readBoolEntry("Alert",1);
if(useAlerts) {
msgLabel = new QLabel( 0, "alertLabel" );
msgLabel->setText("<B><P><font size=+2>VMemo-Recording</font></B>");
msgLabel->show();
}
odebug << "Start recording engines" << oendl;
recording = TRUE;
if (openDSP() == -1) {
recording = FALSE;
return FALSE;
}
config.setGroup("Defaults");
date = TimeString::dateString( QDateTime::currentDateTime(),false,true);
date.replace(QRegExp("'"),"");
date.replace(QRegExp(" "),"_");
date.replace(QRegExp(":"),"-");
date.replace(QRegExp(","),"");
QString fName;
config.setGroup( "System" );
fName = QPEApplication::documentDir() ;
fileName = config.readEntry("RecLocation", fName);
int s;
s=fileName.find(':');
if(s)
fileName=fileName.right(fileName.length()-s-2);
odebug << "pathname will be "+fileName << oendl;
if( fileName.left(1).find('/') == -1)
fileName="/"+fileName;
if( fileName.right(1).find('/') == -1)
fileName+="/";
fName = "vm_"+ date + ".wav";
fileName+=fName;
odebug << "filename is " + fileName << oendl;
// open tmp file here
char *pointer;
pointer=tmpnam(NULL);
odebug << "Opening tmp file " << pointer << "" << oendl;
if(openWAV(pointer ) == -1) {
QString err("Could not open the temp file\n");
err += fileName;
QMessageBox::critical(0, "vmemo", err, "Abort");
::close(dsp);
return FALSE;
}
if( record() ) {
QString cmd;
if( fileName.find(".wav",0,TRUE) == -1)
fileName += ".wav";
cmd.sprintf("mv %s "+fileName, pointer);
// move tmp file to regular file here
system(cmd.latin1());
QArray<int> cats(1);
cats[0] = config.readNumEntry("Category", 0);
QString dlName("vm_");
dlName += date;
DocLnk l;
l.setFile(fileName);
l.setName(dlName);
l.setType("audio/x-wav");
l.setCategories(cats);
l.writeLink();
return TRUE;
} else
return FALSE;
}
void VMemo::stopRecording() {
// show();
odebug << "Stopped recording" << oendl;
recording = FALSE;
if(useAlerts) {
msgLabel->close();
msgLabel=0;
delete msgLabel;
}
t_timer->stop();
Config cfg("Vmemo");
cfg.setGroup("Defaults");
// if( cfg.readNumEntry("hideIcon",0) == 1 )
// hide();
}
int VMemo::openDSP() {
Config cfg("Vmemo");
cfg.setGroup("Record");
speed = cfg.readNumEntry("SampleRate", 22050);
channels = cfg.readNumEntry("Stereo", 1) ? 2 : 1; // 1 = stereo(2), 0 = mono(1)
if (cfg.readNumEntry("SixteenBit", 1)==1) {
format = AFMT_S16_LE;
resolution = 16;
} else {
format = AFMT_U8;
resolution = 8;
}
odebug << "samplerate: " << speed << ", channels " << channels << ", resolution " << resolution << "" << oendl;
if(systemZaurus) {
dsp = open("/dev/dsp1", O_RDONLY); //Zaurus needs /dev/dsp1
channels=1; //zaurus has one input channel
} else {
+#ifdef QT_QWS_DEVFS
+ dsp = open("/dev/sound/dsp", O_RDONLY);
+#else
dsp = open("/dev/dsp", O_RDONLY);
+#endif
}
- if(dsp == -1) {
+ if (dsp == -1) {
msgLabel->close();
msgLabel=0;
delete msgLabel;
perror("open(\"/dev/dsp\")");
errorMsg="open(\"/dev/dsp\")\n "+(QString)strerror(errno);
- QMessageBox::critical(0, "vmemo", errorMsg, "Abort");
- return -1;
+ QMessageBox::critical(0, "vmemo", errorMsg, "Abort");
+ return -1;
}
if(ioctl(dsp, SNDCTL_DSP_SETFMT , &format)==-1) {
perror("ioctl(\"SNDCTL_DSP_SETFMT\")");
return -1;
}
if(ioctl(dsp, SNDCTL_DSP_CHANNELS , &channels)==-1) {
perror("ioctl(\"SNDCTL_DSP_CHANNELS\")");
return -1;
}
if(ioctl(dsp, SNDCTL_DSP_SPEED , &speed)==-1) {
perror("ioctl(\"SNDCTL_DSP_SPEED\")");
return -1;
}
if(ioctl(dsp, SOUND_PCM_READ_RATE , &rate)==-1) {
perror("ioctl(\"SOUND_PCM_READ_RATE\")");
return -1;
}
QCopEnvelope( "QPE/System", "volumeChange(bool)" ) << FALSE; //mute
return 1;
}
int VMemo::openWAV(const char *filename) {
track.setName(filename);
if(!track.open(IO_WriteOnly|IO_Truncate|IO_Raw)) {
errorMsg=filename;
return -1;
}
wav=track.handle();
Config vmCfg("Vmemo");
vmCfg.setGroup("Defaults");
useADPCM = vmCfg.readBoolEntry("use_ADPCM", 0);
WaveHeader wh;
wh.main_chunk = RIFF;
wh.length=0;
wh.chunk_type = WAVE;
wh.sub_chunk = FMT;
wh.sc_len = 16;
if(useADPCM)
wh.format = WAVE_FORMAT_DVI_ADPCM;//PCM_CODE;
else
wh.format = PCM_CODE;
wh.modus = channels;
wh.sample_fq = speed;
wh.byte_p_sec = speed * channels * resolution/8;
wh.byte_p_spl = channels * (resolution / 8);
wh.bit_p_spl = resolution;
wh.data_chunk = DATA;
wh.data_length= 0;
// odebug << "Write header channels " << wh.modus << ", speed " << wh.sample_fq << ", b/s "
// << wh.byte_p_sec << ", blockalign " << wh.byte_p_spl << ", bitrate " << wh.bit_p_spl << oendl;
write (wav, &wh, sizeof(WaveHeader));
return 1;
}
bool VMemo::record() {
length = 0;
int bytesWritten = 0;
int result = 0;
int value = 0;
QString msg;
msg.sprintf("Recording format %d", format);
odebug << msg << oendl;
Config config("Vmemo");
config.setGroup("Record");
int sRate = config.readNumEntry("SizeLimit", 30);
odebug << "VMEMO rate" << sRate << oendl;
if(sRate > 0) {
t_timer->start( sRate * 1000+1000, TRUE);
}
msg.sprintf("Recording format other");
odebug << msg << oendl;
config.setGroup("Defaults");
useADPCM = config.readBoolEntry("use_ADPCM", 0);
int bufsize = config.readNumEntry("BufferSize",1024);
unsigned short sound[bufsize]; //, monoBuffer[bufsize];
char abuf[bufsize / 2];
short sbuf[bufsize];
odebug << "ready to record"<< oendl;
if(useADPCM) {
odebug << "usr ADPCM" << oendl;
while(recording) {
result = ::read(dsp, sbuf, bufsize); // adpcm read
if( result <= 0) {
perror("recording error ");
QMessageBox::message(tr("Note"),tr("error recording"));
recording = FALSE;
break;
return FALSE;
}
adpcm_coder( sbuf, abuf, result/2, &encoder_state);
bytesWritten = ::write(wav, abuf, result/4); // adpcm write
length += bytesWritten;
if(length < 0) {
recording = false;
perror("dev/dsp's is a lookin' messy");
QMessageBox::message("Vmemo","Error writing to file\n"+ fileName);
break;
return FALSE;
}
printf("%d\r", length);
fflush(stdout);
qApp->processEvents();
}
} else {
odebug << "use regular wav" << oendl;
while(recording) {
result = ::read(dsp, sound, bufsize); // read
if( result <= 0) {
perror("recording error ");
QMessageBox::message(tr("Note"),tr("error recording"));
recording = FALSE;
break;
return FALSE;
}
bytesWritten = ::write(wav, sound, result); // write
length += bytesWritten;
if(length < 0) {
recording = false;
perror("dev/dsp's is a lookin' messy");
QMessageBox::message("Vmemo","Error writing to file\n"+ fileName);
break;
return FALSE;
}
// printf("%d\r", length);
// fflush(stdout);
qApp->processEvents();
}
// odebug << "result is " << result << oendl;
}
odebug << "file has length of " << length << " lasting " << (( length / speed) / channels) / 2 << " seconds" << oendl;
value = length + 36;
lseek(wav, 4, SEEK_SET);
write(wav, &value, 4);
lseek(wav, 40, SEEK_SET);
write(wav, &length, 4);
track.close();
odebug << "Track closed" << oendl;
if( ioctl( dsp, SNDCTL_DSP_RESET,0) == -1)
perror("ioctl(\"SNDCTL_DSP_RESET\")");
::close(dsp);
Config cfgO("OpieRec");
cfgO.setGroup("Sounds");
int nFiles = cfgO.readNumEntry( "NumberofFiles",0);
QString currentFileName = fileName;
QString currentFile = "vm_"+ date;
float numberOfRecordedSeconds = (float) length / (float)speed * (float)2;
cfgO.writeEntry( "NumberofFiles", nFiles + 1);
cfgO.writeEntry( QString::number( nFiles + 1), currentFile);
cfgO.writeEntry( currentFile, currentFileName);
QString time;
time.sprintf("%.2f", numberOfRecordedSeconds);
cfgO.writeEntry( currentFileName, time );
// odebug << "writing config numberOfRecordedSeconds "+time << oendl;
cfgO.write();
odebug << "done recording "+fileName << oendl;
Config cfg("qpe");
cfg.setGroup("Volume");
QString foo = cfg.readEntry("Mute","TRUE");
if(foo.find("TRUE",0,TRUE) != -1)
QCopEnvelope( "QPE/System", "volumeChange(bool)" ) << TRUE; //mute
return TRUE;
}
int VMemo::setToggleButton(int tog) {
for( int i=0; i < 10;i++) {
switch (tog) {
case 0:
return -1;
break;
case 1:
return 0;
break;
case 2:
return Key_F24; //was Escape
break;
case 3:
return Key_Space;
break;
case 4:
return Key_F12;
break;
case 5:
return Key_F9;
break;
case 6:
return Key_F10;
break;
case 7:
return Key_F11;
break;
case 8:
return Key_F13;
break;
};
}
return -1;
}
void VMemo::timerBreak() {
//stop
stopRecording();
QMessageBox::message("Vmemo","Vmemo recording has ended");
}
EXPORT_OPIE_APPLET_v1( VMemo )
diff --git a/core/applets/vtapplet/vt.cpp b/core/applets/vtapplet/vt.cpp
index aec63c3..7832ee0 100644
--- a/core/applets/vtapplet/vt.cpp
+++ b/core/applets/vtapplet/vt.cpp
@@ -1,164 +1,172 @@
/**********************************************************************
** Copyright (C) 2003-2004 Michael 'Mickey' Lauer <mickey@Vanille.de>
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
**********************************************************************/
#include "vt.h"
/* OPIE */
#include <opie2/odebug.h>
#include <qpe/resource.h>
using namespace Opie::Core;
/* QT */
#include <qpopupmenu.h>
/* STD */
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/vt.h>
VTApplet::VTApplet ( )
: QObject ( 0, "VTApplet" )
{
}
VTApplet::~VTApplet ( )
{
}
int VTApplet::position ( ) const
{
return 2;
}
QString VTApplet::name ( ) const
{
return tr( "VT shortcut" );
}
QString VTApplet::text ( ) const
{
return tr( "Terminal" );
}
/*
QString VTApplet::tr( const char* s ) const
{
return qApp->translate( "VTApplet", s, 0 );
}
QString VTApplet::tr( const char* s, const char* p ) const
{
return qApp->translate( "VTApplet", s, p );
}
*/
QIconSet VTApplet::icon ( ) const
{
QPixmap pix;
QImage img = Resource::loadImage ( "terminal" );
if ( !img. isNull ( ))
pix. convertFromImage ( img. smoothScale ( 14, 14 ));
return pix;
}
QPopupMenu *VTApplet::popup ( QWidget* parent ) const
{
odebug << "VTApplet::popup" << oendl;
struct vt_stat vtstat;
+#ifdef QT_QWS_DEVFS
+ int fd = ::open( "/dev/vc/0", O_RDWR );
+#else
int fd = ::open( "/dev/tty0", O_RDWR );
+#endif
if ( fd == -1 ) return 0;
if ( ioctl( fd, VT_GETSTATE, &vtstat ) == -1 ) return 0;
m_subMenu = new QPopupMenu( parent );
m_subMenu->setCheckable( true );
for ( int i = 1; i < 10; ++i )
{
int id = m_subMenu->insertItem( QString::number( i ), 500+i );
m_subMenu->setItemChecked( id, id-500 == vtstat.v_active );
}
::close( fd );
connect( m_subMenu, SIGNAL( activated(int) ), this, SLOT( changeVT(int) ) );
connect( m_subMenu, SIGNAL( aboutToShow() ), this, SLOT( updateMenu() ) );
return m_subMenu;
}
void VTApplet::changeVT( int index )
{
//odebug << "VTApplet::changeVT( " << index-500 << " )" << oendl;
+#ifdef QT_QWS_DEVFS
+ int fd = ::open("/dev/vc/0", O_RDWR);
+#else
int fd = ::open("/dev/tty0", O_RDWR);
+#endif
if ( fd == -1 ) return;
ioctl( fd, VT_ACTIVATE, index-500 );
}
void VTApplet::updateMenu()
{
//odebug << "VTApplet::updateMenu()" << oendl;
int fd = ::open( "/dev/console", O_RDONLY );
if ( fd == -1 ) return;
for ( int i = 1; i < 10; ++i )
{
int result = ioctl( fd, VT_DISALLOCATE, i );
/*
if ( result == -1 )
odebug << "VT " << i << " disallocated == free" << oendl;
else
odebug << "VT " << i << " _not_ disallocated == busy" << oendl;
*/
m_subMenu->setItemEnabled( 500+i, result == -1 );
}
::close( fd );
}
void VTApplet::activated()
{
odebug << "VTApplet::activated()" << oendl;
}
QRESULT VTApplet::queryInterface ( const QUuid &uuid, QUnknownInterface **iface )
{
*iface = 0;
if ( uuid == IID_QUnknown )
*iface = this;
else if ( uuid == IID_MenuApplet )
*iface = this;
else
return QS_FALSE;
if ( *iface )
(*iface)-> addRef ( );
return QS_OK;
}
Q_EXPORT_INTERFACE( )
{
Q_CREATE_INSTANCE( VTApplet )
}
diff --git a/libopie/odevice.cpp b/libopie/odevice.cpp
index 21070bf..9d0bbbf 100644
--- a/libopie/odevice.cpp
+++ b/libopie/odevice.cpp
@@ -214,769 +214,773 @@ struct i_button {
char *utext;
char *pix;
char *fpressedservice;
char *fpressedaction;
char *fheldservice;
char *fheldaction;
} ipaq_buttons [] = {
{ Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx,
Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"),
"devicebuttons/ipaq_calendar",
"datebook", "nextView()",
"today", "raise()" },
{ Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx,
Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"),
"devicebuttons/ipaq_contact",
"addressbook", "raise()",
"addressbook", "beamBusinessCard()" },
{ Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx,
Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"),
"devicebuttons/ipaq_menu",
"QPE/TaskBar", "toggleMenu()",
"QPE/TaskBar", "toggleStartMenu()" },
{ Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx,
Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Mail Button"),
"devicebuttons/ipaq_mail",
"mail", "raise()",
"mail", "newMail()" },
{ Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx,
Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"),
"devicebuttons/ipaq_home",
"QPE/Launcher", "home()",
"buttonsettings", "raise()" },
{ Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx,
Qt::Key_F24, QT_TRANSLATE_NOOP("Button", "Record Button"),
"devicebuttons/ipaq_record",
"QPE/VMemo", "toggleRecord()",
"sound", "raise()" },
};
struct z_button {
Qt::Key code;
char *utext;
char *pix;
char *fpressedservice;
char *fpressedaction;
char *fheldservice;
char *fheldaction;
} z_buttons [] = {
{ Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"),
"devicebuttons/z_calendar",
"datebook", "nextView()",
"today", "raise()" },
{ Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"),
"devicebuttons/z_contact",
"addressbook", "raise()",
"addressbook", "beamBusinessCard()" },
{ Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"),
"devicebuttons/z_home",
"QPE/Launcher", "home()",
"buttonsettings", "raise()" },
{ Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"),
"devicebuttons/z_menu",
"QPE/TaskBar", "toggleMenu()",
"QPE/TaskBar", "toggleStartMenu()" },
{ Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Mail Button"),
"devicebuttons/z_mail",
"mail", "raise()",
"mail", "newMail()" },
};
struct z_button z_buttons_c700 [] = {
{ Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"),
"devicebuttons/z_calendar",
"datebook", "nextView()",
"today", "raise()" },
{ Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"),
"devicebuttons/z_contact",
"addressbook", "raise()",
"addressbook", "beamBusinessCard()" },
{ Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"),
"devicebuttons/z_home",
"QPE/Launcher", "home()",
"buttonsettings", "raise()" },
{ Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"),
"devicebuttons/z_menu",
"QPE/TaskBar", "toggleMenu()",
"QPE/TaskBar", "toggleStartMenu()" },
{ Qt::Key_F14, QT_TRANSLATE_NOOP("Button", "Display Rotate"),
"devicebuttons/z_hinge",
"QPE/Rotation", "rotateDefault()",
"QPE/Dummy", "doNothing()" },
};
struct s_button {
uint model;
Qt::Key code;
char *utext;
char *pix;
char *fpressedservice;
char *fpressedaction;
char *fheldservice;
char *fheldaction;
} simpad_buttons [] = {
{ Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Lower+Up"),
"devicebuttons/simpad_lower_up",
"datebook", "nextView()",
"today", "raise()" },
{ Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Lower+Down"),
"devicebuttons/simpad_lower_down",
"addressbook", "raise()",
"addressbook", "beamBusinessCard()" },
{ Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Lower+Right"),
"devicebuttons/simpad_lower_right",
"QPE/TaskBar", "toggleMenu()",
"QPE/TaskBar", "toggleStartMenu()" },
{ Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Lower+Left"),
"devicebuttons/simpad_lower_left",
"mail", "raise()",
"mail", "newMail()" },
{ Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
Qt::Key_F5, QT_TRANSLATE_NOOP("Button", "Upper+Up"),
"devicebuttons/simpad_upper_up",
"QPE/Launcher", "home()",
"buttonsettings", "raise()" },
{ Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
Qt::Key_F6, QT_TRANSLATE_NOOP("Button", "Upper+Down"),
"devicebuttons/simpad_upper_down",
"addressbook", "raise()",
"addressbook", "beamBusinessCard()" },
{ Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
Qt::Key_F7, QT_TRANSLATE_NOOP("Button", "Upper+Right"),
"devicebuttons/simpad_upper_right",
"QPE/TaskBar", "toggleMenu()",
"QPE/TaskBar", "toggleStartMenu()" },
{ Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Upper+Left"),
"devicebuttons/simpad_upper_left",
"QPE/Rotation", "flip()",
"QPE/Rotation", "flip()" },
/*
{ Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Lower+Upper"),
"devicebuttons/simpad_lower_upper",
"QPE/Launcher", "home()",
"buttonsettings", "raise()" },
{ Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Lower+Upper"),
"devicebuttons/simpad_upper_lower",
"QPE/Launcher", "home()",
"buttonsettings", "raise()" },
*/
};
class Yopy : public ODevice {
protected:
virtual void init ( );
virtual void initButtons ( );
public:
virtual bool suspend ( );
virtual bool setDisplayBrightness ( int b );
virtual int displayBrightnessResolution ( ) const;
static bool isYopy ( );
};
struct yopy_button {
Qt::Key code;
char *utext;
char *pix;
char *fpressedservice;
char *fpressedaction;
char *fheldservice;
char *fheldaction;
} yopy_buttons [] = {
{ Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Action Button"),
"devicebuttons/yopy_action",
"datebook", "nextView()",
"today", "raise()" },
{ Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "OK Button"),
"devicebuttons/yopy_ok",
"addressbook", "raise()",
"addressbook", "beamBusinessCard()" },
{ Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "End Button"),
"devicebuttons/yopy_end",
"QPE/Launcher", "home()",
"buttonsettings", "raise()" },
};
static QCString makeChannel ( const char *str )
{
if ( str && !::strchr ( str, '/' ))
return QCString ( "QPE/Application/" ) + str;
else
return str;
}
static inline bool isQWS()
{
return qApp ? ( qApp-> type ( ) == QApplication::GuiServer ) : false;
}
ODevice *ODevice::inst ( )
{
static ODevice *dev = 0;
if ( !dev ) {
if ( QFile::exists ( "/proc/hal/model" ))
dev = new iPAQ ( );
else if ( Zaurus::isZaurus() )
dev = new Zaurus ( );
else if ( QFile::exists ( "/proc/ucb1x00" ) && QFile::exists ( "/proc/cs3" ))
dev = new SIMpad ( );
else if ( Yopy::isYopy() )
dev = new Yopy ( );
else if ( Jornada::isJornada() )
dev = new Jornada ( );
else if ( QFile::exists ( "/proc/sys/board/sys_name" ))
dev = new Ramses ( );
else
dev = new ODevice ( );
dev-> init ( );
}
return dev;
}
/**************************************************
*
* common
*
**************************************************/
ODevice::ODevice ( )
{
d = new ODeviceData;
d-> m_modelstr = "Unknown";
d-> m_model = Model_Unknown;
d-> m_vendorstr = "Unknown";
d-> m_vendor = Vendor_Unknown;
d-> m_systemstr = "Unknown";
d-> m_system = System_Unknown;
d-> m_sysverstr = "0.0";
d-> m_rotation = Rot0;
d-> m_direction = CW;
d-> m_holdtime = 1000; // 1000ms
d-> m_buttons = 0;
d-> m_cpu_frequencies = new QStrList;
}
void ODevice::systemMessage ( const QCString &msg, const QByteArray & )
{
if ( msg == "deviceButtonMappingChanged()" ) {
reloadButtonMapping ( );
}
}
void ODevice::init ( )
{
}
/**
* This method initialises the button mapping
*/
void ODevice::initButtons ( )
{
if ( d-> m_buttons )
return;
// Simulation uses iPAQ 3660 device buttons
qDebug ( "init Buttons" );
d-> m_buttons = new QValueList <ODeviceButton>;
for ( uint i = 0; i < ( sizeof( ipaq_buttons ) / sizeof( i_button )); i++ ) {
i_button *ib = ipaq_buttons + i;
ODeviceButton b;
if (( ib-> model & Model_iPAQ_H36xx ) == Model_iPAQ_H36xx ) {
b. setKeycode ( ib-> code );
b. setUserText ( QObject::tr ( "Button", ib-> utext ));
b. setPixmap ( Resource::loadPixmap ( ib-> pix ));
b. setFactoryPresetPressedAction ( OQCopMessage ( makeChannel ( ib-> fpressedservice ), ib-> fpressedaction ));
b. setFactoryPresetHeldAction ( OQCopMessage ( makeChannel ( ib-> fheldservice ), ib-> fheldaction ));
d-> m_buttons-> append ( b );
}
}
reloadButtonMapping ( );
QCopChannel *sysch = new QCopChannel ( "QPE/System", this );
connect ( sysch, SIGNAL( received(const QCString&,const QByteArray&)), this, SLOT( systemMessage(const QCString&,const QByteArray&)));
}
ODevice::~ODevice ( )
{
// we leak m_devicebuttons and m_cpu_frequency
// but it's a singleton and it is not so importantant
// -zecke
delete d;
}
bool ODevice::setSoftSuspend ( bool /*soft*/ )
{
return false;
}
//#include <linux/apm_bios.h>
#define APM_IOC_SUSPEND OD_IO( 'A', 2 )
/**
* This method will try to suspend the device
* It only works if the user is the QWS Server and the apm application
* is installed.
* It tries to suspend and then waits some time cause some distributions
* do have asynchronus apm implementations.
* This method will either fail and return false or it'll suspend the
* device and return once the device got woken up
*
* @return if the device got suspended
*/
bool ODevice::suspend ( )
{
qDebug("ODevice::suspend");
if ( !isQWS( ) ) // only qwsserver is allowed to suspend
return false;
if ( d-> m_model == Model_Unknown ) // better don't suspend in qvfb / on unkown devices
return false;
bool res = false;
struct timeval tvs, tvn;
::gettimeofday ( &tvs, 0 );
::sync ( ); // flush fs caches
res = ( ::system ( "apm --suspend" ) == 0 );
// This is needed because the iPAQ apm implementation is asynchronous and we
// can not be sure when exactly the device is really suspended
// This can be deleted as soon as a stable familiar with a synchronous apm implementation exists.
if ( res ) {
do { // wait at most 1.5 sec: either suspend didn't work or the device resumed
::usleep ( 200 * 1000 );
::gettimeofday ( &tvn, 0 );
} while ((( tvn. tv_sec - tvs. tv_sec ) * 1000 + ( tvn. tv_usec - tvs. tv_usec ) / 1000 ) < 1500 );
}
return res;
}
//#include <linux/fb.h> better not rely on kernel headers in userspace ...
#define FBIOBLANK OD_IO( 'F', 0x11 ) // 0x4611
/* VESA Blanking Levels */
#define VESA_NO_BLANKING 0
#define VESA_VSYNC_SUSPEND 1
#define VESA_HSYNC_SUSPEND 2
#define VESA_POWERDOWN 3
/**
* This sets the display on or off
*/
bool ODevice::setDisplayStatus ( bool on )
{
qDebug("ODevice::setDisplayStatus(%d)", on);
if ( d-> m_model == Model_Unknown )
return false;
bool res = false;
int fd;
+#ifdef QT_QWS_DEVFS
+ if (( fd = ::open ( "/dev/fb/0", O_RDWR )) >= 0 ) {
+#else
if (( fd = ::open ( "/dev/fb0", O_RDWR )) >= 0 ) {
+#endif
res = ( ::ioctl ( fd, FBIOBLANK, on ? VESA_NO_BLANKING : VESA_POWERDOWN ) == 0 );
::close ( fd );
}
return res;
}
/**
* This sets the display brightness
*
* @param p The brightness to be set on a scale from 0 to 255
* @return success or failure
*/
bool ODevice::setDisplayBrightness ( int p)
{
Q_UNUSED( p )
return false;
}
/**
* @return returns the number of steppings on the brightness slider
* in the Light-'n-Power settings.
*/
int ODevice::displayBrightnessResolution ( ) const
{
return 16;
}
/**
* This sets the display contrast
* @param p The contrast to be set on a scale from 0 to 255
* @return success or failure
*/
bool ODevice::setDisplayContrast ( int p)
{
Q_UNUSED( p )
return false;
}
/**
* @return return the max value for the brightness settings slider
* or 0 if the device doesn't support setting of a contrast
*/
int ODevice::displayContrastResolution ( ) const
{
return 0;
}
/**
* This returns the vendor as string
* @return Vendor as QString
*/
QString ODevice::vendorString ( ) const
{
return d-> m_vendorstr;
}
/**
* This returns the vendor as one of the values of OVendor
* @return OVendor
*/
OVendor ODevice::vendor ( ) const
{
return d-> m_vendor;
}
/**
* This returns the model as a string
* @return A string representing the model
*/
QString ODevice::modelString ( ) const
{
return d-> m_modelstr;
}
/**
* This does return the OModel used
*/
OModel ODevice::model ( ) const
{
return d-> m_model;
}
/**
* This does return the systen name
*/
QString ODevice::systemString ( ) const
{
return d-> m_systemstr;
}
/**
* Return System as OSystem value
*/
OSystem ODevice::system ( ) const
{
return d-> m_system;
}
/**
* @return the version string of the base system
*/
QString ODevice::systemVersionString ( ) const
{
return d-> m_sysverstr;
}
/**
* @return the current Transformation
*/
Transformation ODevice::rotation ( ) const
{
VirtRotation rot;
ODevice* that =(ODevice* )this;
that->virtual_hook( VIRTUAL_ROTATION, &rot );
return rot.trans;
}
/**
* @return the current rotation direction
*/
ODirection ODevice::direction ( ) const
{
VirtDirection dir;
ODevice* that =(ODevice* )this;
that->virtual_hook( VIRTUAL_DIRECTION, &dir );
return dir.direct;
}
/**
* This plays an alarmSound
*/
void ODevice::alarmSound ( )
{
#ifndef QT_NO_SOUND
static Sound snd ( "alarm" );
if ( snd. isFinished ( ))
snd. play ( );
#endif
}
/**
* This plays a key sound
*/
void ODevice::keySound ( )
{
#ifndef QT_NO_SOUND
static Sound snd ( "keysound" );
if ( snd. isFinished ( ))
snd. play ( );
#endif
}
/**
* This plays a touch sound
*/
void ODevice::touchSound ( )
{
#ifndef QT_NO_SOUND
static Sound snd ( "touchsound" );
if ( snd. isFinished ( ))
snd. play ( );
#endif
}
/**
* This method will return a list of leds
* available on this device
* @return a list of LEDs.
*/
QValueList <OLed> ODevice::ledList ( ) const
{
return QValueList <OLed> ( );
}
/**
* This does return the state of the LEDs
*/
QValueList <OLedState> ODevice::ledStateList ( OLed /*which*/ ) const
{
return QValueList <OLedState> ( );
}
/**
* @return the state for a given OLed
*/
OLedState ODevice::ledState ( OLed /*which*/ ) const
{
return Led_Off;
}
/**
* Set the state for a LED
* @param which Which OLed to use
* @param st The state to set
* @return success or failure
*/
bool ODevice::setLedState ( OLed which, OLedState st )
{
Q_UNUSED( which )
Q_UNUSED( st )
return false;
}
/**
* @return if the device has a light sensor
*/
bool ODevice::hasLightSensor ( ) const
{
return false;
}
/**
* @return a value from the light sensor
*/
int ODevice::readLightSensor ( )
{
return -1;
}
/**
* @return the light sensor resolution
*/
int ODevice::lightSensorResolution ( ) const
{
return 0;
}
/**
* @return if the device has a hinge sensor
*/
bool ODevice::hasHingeSensor ( ) const
{
VirtHasHinge hing;
ODevice* that =(ODevice* )this;
that->virtual_hook( VIRTUAL_HAS_HINGE, &hing );
return hing.hasHinge;
}
/**
* @return a value from the hinge sensor
*/
OHingeStatus ODevice::readHingeSensor ( )
{
VirtHingeStatus hing;
virtual_hook( VIRTUAL_HINGE, &hing );
return hing.hingeStat;
}
/**
* @return a list with CPU frequencies supported by the hardware
*/
const QStrList &ODevice::allowedCpuFrequencies ( ) const
{
return *d->m_cpu_frequencies;
}
/**
* Set desired CPU frequency
*
* @param index index into d->m_cpu_frequencies of the frequency to be set
*/
bool ODevice::setCurrentCpuFrequency(uint index)
{
if (index >= d->m_cpu_frequencies->count())
return false;
char *freq = d->m_cpu_frequencies->at(index);
qWarning("set freq to %s", freq);
int fd;
if ((fd = ::open("/proc/sys/cpu/0/speed", O_WRONLY)) >= 0) {
char writeCommand[50];
const int count = sprintf(writeCommand, "%s\n", freq);
int res = (::write(fd, writeCommand, count) != -1);
::close(fd);
return res;
}
return false;
}
/**
* @return a list of hardware buttons
*/
const QValueList <ODeviceButton> &ODevice::buttons ( )
{
initButtons ( );
return *d-> m_buttons;
}
/**
* @return The amount of time that would count as a hold
*/
uint ODevice::buttonHoldTime ( ) const
{
return d-> m_holdtime;
}
/**
* This method return a ODeviceButton for a key code
* or 0 if no special hardware button is available for the device
*
* @return The devicebutton or 0l
* @see ODeviceButton
*/
const ODeviceButton *ODevice::buttonForKeycode ( ushort code )
{
initButtons ( );
for ( QValueListConstIterator<ODeviceButton> it = d-> m_buttons-> begin ( ); it != d-> m_buttons-> end ( ); ++it ) {
if ( (*it). keycode ( ) == code )
return &(*it);
}
return 0;
}
void ODevice::reloadButtonMapping ( )
{
initButtons ( );
Config cfg ( "ButtonSettings" );
for ( uint i = 0; i < d-> m_buttons-> count ( ); i++ ) {
ODeviceButton &b = ( *d-> m_buttons ) [i];
QString group = "Button" + QString::number ( i );
QCString pch, hch;
QCString pm, hm;
QByteArray pdata, hdata;
if ( cfg. hasGroup ( group )) {
cfg. setGroup ( group );
pch = cfg. readEntry ( "PressedActionChannel" ). latin1 ( );
pm = cfg. readEntry ( "PressedActionMessage" ). latin1 ( );
// pdata = decodeBase64 ( buttonFile. readEntry ( "PressedActionArgs" ));
hch = cfg. readEntry ( "HeldActionChannel" ). latin1 ( );
hm = cfg. readEntry ( "HeldActionMessage" ). latin1 ( );
// hdata = decodeBase64 ( buttonFile. readEntry ( "HeldActionArgs" ));
}
b. setPressedAction ( OQCopMessage ( pch, pm, pdata ));
b. setHeldAction ( OQCopMessage ( hch, hm, hdata ));
}
}
void ODevice::remapPressedAction ( int button, const OQCopMessage &action )
{
initButtons ( );
QString mb_chan;
if ( button >= (int) d-> m_buttons-> count ( ))
return;
ODeviceButton &b = ( *d-> m_buttons ) [button];
b. setPressedAction ( action );
mb_chan=b. pressedAction ( ). channel ( );
Config buttonFile ( "ButtonSettings" );
buttonFile. setGroup ( "Button" + QString::number ( button ));
buttonFile. writeEntry ( "PressedActionChannel", (const char*) mb_chan);
buttonFile. writeEntry ( "PressedActionMessage", (const char*) b. pressedAction ( ). message ( ));
// buttonFile. writeEntry ( "PressedActionArgs", encodeBase64 ( b. pressedAction ( ). data ( )));
QCopEnvelope ( "QPE/System", "deviceButtonMappingChanged()" );
}
void ODevice::remapHeldAction ( int button, const OQCopMessage &action )
{
initButtons ( );
if ( button >= (int) d-> m_buttons-> count ( ))
return;
diff --git a/libopie2/opiemm/osoundsystem.cpp b/libopie2/opiemm/osoundsystem.cpp
index 763ff65..17e5cb0 100644
--- a/libopie2/opiemm/osoundsystem.cpp
+++ b/libopie2/opiemm/osoundsystem.cpp
@@ -1,317 +1,322 @@
/*
                This file is part of the Opie Project
              (C) 2003 Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de>
=.
.=l.
           .>+-=
 _;:,     .>    :=|. This program is free software; you can
.> <`_,   >  .   <= redistribute it and/or modify it under
:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
.="- .-=="i,     .._ License as published by the Free Software
 - .   .-<_>     .<> Foundation; either version 2 of the License,
     ._= =}       : or (at your option) any later version.
    .%`+i>       _;_.
    .i_,=:_.      -<s. 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
..}^=.=       =       ; Library General Public License for more
++=   -.     .`     .: details.
 :     =  ...= . :.=-
 -.   .:....=;==+<; You should have received a copy of the GNU
  -_. . .   )=.  = Library General Public License along with
    --        :-=` this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include <opie2/osoundsystem.h>
#include <opie2/odebug.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/soundcard.h>
#include <sys/stat.h>
using namespace Opie::Core;
using namespace Opie::MM;
/*======================================================================================
* OSoundSystem
*======================================================================================*/
OSoundSystem* OSoundSystem::_instance = 0;
OSoundSystem::OSoundSystem()
{
odebug << "OSoundSystem::OSoundSystem()" << oendl;
synchronize();
}
void OSoundSystem::synchronize()
{
// gather available interfaces by inspecting /dev
//FIXME: we could use SIOCGIFCONF here, but we aren't interested in virtual (e.g. eth0:0) devices
//FIXME: Use SIOCGIFCONF anway, because we can disable listing of aliased devices
_interfaces.clear();
_interfaces.insert( "soundcard", new OSoundCard( this, "soundcard" ) );
/*
QString str;
QFile f( "/dev/sound" );
bool hasFile = f.open( IO_ReadOnly );
if ( !hasFile )
{
odebug << "OSoundSystem: /dev/sound not existing. No sound devices available" << oendl;
return;
}
QTextStream s( &f );
s.readLine();
s.readLine();
while ( !s.atEnd() )
{
s >> str;
str.truncate( str.find( ':' ) );
odebug << "OSoundSystem: found interface '" << str << "'" << oendl;
OAudioInterface* iface;
iface = new OAudioInterface( this, (const char*) str );
_interfaces.insert( str, iface );
s.readLine();
}
*/
}
int OSoundSystem::count() const
{
return _interfaces.count();
}
OSoundCard* OSoundSystem::card( const QString& iface ) const
{
return _interfaces[iface];
}
OSoundSystem* OSoundSystem::instance()
{
if ( !_instance ) _instance = new OSoundSystem();
return _instance;
}
OSoundSystem::CardIterator OSoundSystem::iterator() const
{
return OSoundSystem::CardIterator( _interfaces );
}
/*======================================================================================
* OSoundCard
*======================================================================================*/
OSoundCard::OSoundCard( QObject* parent, const char* name )
:QObject( parent, name ), _audio( 0 ), _mixer( 0 )
{
odebug << "OSoundCard::OSoundCard()" << oendl;
init();
}
OSoundCard::~OSoundCard()
{
}
void OSoundCard::init()
{
+#ifdef QT_QWS_DEVFS
+ _audio = new OAudioInterface( this, "/dev/sound/dsp" );
+ _mixer = new OMixerInterface( this, "/dev/sound/mixer" );
+#else
_audio = new OAudioInterface( this, "/dev/dsp" );
_mixer = new OMixerInterface( this, "/dev/mixer" );
+#endif
}
/*======================================================================================
* OAudioInterface
*======================================================================================*/
OAudioInterface::OAudioInterface( QObject* parent, const char* name )
:QObject( parent, name ), _sfd(0)
{
odebug << "OAudioInterface::OAudioInterface()" << oendl;
init();
}
OAudioInterface::~OAudioInterface()
{
}
void OAudioInterface::init()
{
}
/*======================================================================================
* OMixerInterface
*======================================================================================*/
OMixerInterface::OMixerInterface( QObject* parent, const char* name )
:QObject( parent, name )
{
odebug << "OMixerInterface::OMixerInterface()" << oendl;
init();
}
OMixerInterface::~OMixerInterface()
{
}
void OMixerInterface::init()
{
// open the device
_fd = ::open( name(), O_RDWR );
if ( _fd == -1 )
{
owarn << "OMixerInterface::init(): Can't open mixer." << oendl;
return;
}
// construct the device capabilities
int devmask = 0;
if ( ioctl( _fd, SOUND_MIXER_READ_DEVMASK, &devmask ) != -1 )
{
if ( devmask & ( 1 << SOUND_MIXER_VOLUME ) ) _channels.insert( "PlayVolume", SOUND_MIXER_VOLUME );
if ( devmask & ( 1 << SOUND_MIXER_BASS ) ) _channels.insert( "PlayBass", SOUND_MIXER_BASS );
if ( devmask & ( 1 << SOUND_MIXER_TREBLE ) ) _channels.insert( "PlayTreble", SOUND_MIXER_TREBLE );
if ( devmask & ( 1 << SOUND_MIXER_SYNTH ) ) _channels.insert( "PlaySynth", SOUND_MIXER_SYNTH );
if ( devmask & ( 1 << SOUND_MIXER_PCM ) ) _channels.insert( "PlayPCM", SOUND_MIXER_PCM );
if ( devmask & ( 1 << SOUND_MIXER_SPEAKER ) ) _channels.insert( "PlaySpeaker", SOUND_MIXER_SPEAKER );
if ( devmask & ( 1 << SOUND_MIXER_LINE ) ) _channels.insert( "PlayLine", SOUND_MIXER_LINE );
if ( devmask & ( 1 << SOUND_MIXER_MIC ) ) _channels.insert( "PlayMic", SOUND_MIXER_MIC );
if ( devmask & ( 1 << SOUND_MIXER_CD ) ) _channels.insert( "PlayCD", SOUND_MIXER_CD );
if ( devmask & ( 1 << SOUND_MIXER_IMIX ) ) _channels.insert( "PlayInputMix", SOUND_MIXER_IMIX );
if ( devmask & ( 1 << SOUND_MIXER_ALTPCM ) ) _channels.insert( "PlayAltPCM", SOUND_MIXER_ALTPCM );
if ( devmask & ( 1 << SOUND_MIXER_RECLEV ) ) _channels.insert( "PlayRecord", SOUND_MIXER_RECLEV );
if ( devmask & ( 1 << SOUND_MIXER_IGAIN ) ) _channels.insert( "PlayInputGain", SOUND_MIXER_IGAIN );
if ( devmask & ( 1 << SOUND_MIXER_OGAIN ) ) _channels.insert( "PlayOutputGain", SOUND_MIXER_OGAIN );
//odebug << "devmask available and constructed." << oendl;
}
devmask = 0;
if ( ioctl( _fd, SOUND_MIXER_READ_RECMASK, &devmask ) != -1 )
{
if ( devmask & ( 1 << SOUND_MIXER_VOLUME ) ) _channels.insert( "RecVolume", SOUND_MIXER_VOLUME );
if ( devmask & ( 1 << SOUND_MIXER_BASS ) ) _channels.insert( "RecBass", SOUND_MIXER_BASS );
if ( devmask & ( 1 << SOUND_MIXER_TREBLE ) ) _channels.insert( "RecTreble", SOUND_MIXER_TREBLE );
if ( devmask & ( 1 << SOUND_MIXER_SYNTH ) ) _channels.insert( "RecSynth", SOUND_MIXER_SYNTH );
if ( devmask & ( 1 << SOUND_MIXER_PCM ) ) _channels.insert( "RecPCM", SOUND_MIXER_PCM );
if ( devmask & ( 1 << SOUND_MIXER_SPEAKER ) ) _channels.insert( "RecSpeaker", SOUND_MIXER_SPEAKER );
if ( devmask & ( 1 << SOUND_MIXER_LINE ) ) _channels.insert( "RecLine", SOUND_MIXER_LINE );
if ( devmask & ( 1 << SOUND_MIXER_MIC ) ) _channels.insert( "RecMic", SOUND_MIXER_MIC );
if ( devmask & ( 1 << SOUND_MIXER_CD ) ) _channels.insert( "RecCD", SOUND_MIXER_CD );
if ( devmask & ( 1 << SOUND_MIXER_IMIX ) ) _channels.insert( "RecInputMix", SOUND_MIXER_IMIX );
if ( devmask & ( 1 << SOUND_MIXER_ALTPCM ) ) _channels.insert( "RecAltPCM", SOUND_MIXER_ALTPCM );
if ( devmask & ( 1 << SOUND_MIXER_RECLEV ) ) _channels.insert( "RecRecord", SOUND_MIXER_RECLEV );
if ( devmask & ( 1 << SOUND_MIXER_IGAIN ) ) _channels.insert( "RecInputGain", SOUND_MIXER_IGAIN );
if ( devmask & ( 1 << SOUND_MIXER_OGAIN ) ) _channels.insert( "RecOutputGain", SOUND_MIXER_OGAIN );
//odebug << "recmask available and constructed." << oendl;
}
/* ChannelIterator it;
for ( it = _channels.begin(); it != _channels.end(); ++it )
{
odebug << "Channel " << it.key() << " available (bit " << it.data() << ")" << oendl;
odebug << " +--- Volume: " << volume( it.key() ) & 0xff << " | " << volume( it.key() ) >> 8 << "" << oendl;
}
*/
}
QStringList OMixerInterface::allChannels() const
{
ChannelIterator it = _channels.begin();
QStringList channels;
while ( it != _channels.end() )
{
channels += it.key();
it++;
}
return channels;
}
QStringList OMixerInterface::recChannels() const
{
owarn << "NYI" << oendl;
return QStringList();
}
QStringList OMixerInterface::playChannels() const
{
owarn << "NYI" << oendl;
return QStringList();
}
bool OMixerInterface::hasChannel( const QString& channel )
{
return _channels.contains( channel );
}
void OMixerInterface::setVolume( const QString& channel, int left, int right )
{
int volume = left;
volume |= ( right == -1 ) ? left << 8 : right << 8;
if ( _channels.contains( channel ) )
{
int result = ioctl( _fd, MIXER_WRITE( _channels[channel] ), &volume );
if ( result == -1 )
{
owarn << "Can't set volume: " << strerror( errno ) << oendl;
}
else
{
if ( result & 0xff != left )
{
owarn << "Device adjusted volume from " << left << " to " << (result & 0xff) << oendl;
}
}
}
}
int OMixerInterface::volume( const QString& channel ) const
{
int volume;
if ( _channels.contains( channel ) )
{
if ( ioctl( _fd, MIXER_READ( _channels[channel] ), &volume ) == -1 )
{
owarn << "Can't get volume: " << strerror( errno ) << oendl;
}
else return volume;
}
return -1;
}
diff --git a/library/qpeapplication.cpp b/library/qpeapplication.cpp
index c6d9cfd..ca90427 100644
--- a/library/qpeapplication.cpp
+++ b/library/qpeapplication.cpp
@@ -184,840 +184,856 @@ public:
if (!qcopQok )
return;
QCopRec * r;
while((r=qcopq.dequeue())) {
// remove from queue before sending...
// event loop can come around again before getting
// back from sendLocally
#ifndef QT_NO_COP
QCopChannel::sendLocally( r->channel, r->message, r->data );
#endif
delete r;
}
}
static void show_mx(QWidget* mw, bool nomaximize, QString &strName)
{
if ( mw->inherits("QMainWindow") || mw->isA("QMainWindow") )
{
( ( QMainWindow* ) mw )->setUsesBigPixmaps( useBigPixmaps );
}
QPoint p;
QSize s;
bool max;
if ( mw->isVisible() ) {
if ( read_widget_rect(strName, max, p, s) && validate_widget_size(mw, p, s) ) {
mw->resize(s);
mw->move(p);
}
mw->raise();
} else {
if ( mw->layout() && mw->inherits("QDialog") ) {
if ( read_widget_rect(strName, max, p, s) && validate_widget_size(mw, p, s) ) {
mw->resize(s);
mw->move(p);
if ( max && !nomaximize ) {
mw->showMaximized();
} else {
mw->show();
}
} else {
qpe_show_dialog((QDialog*)mw,nomaximize);
}
} else {
if ( read_widget_rect(strName, max, p, s) && validate_widget_size(mw, p, s) ) {
mw->resize(s);
mw->move(p);
} else { //no stored rectangle, make an estimation
int x = (qApp->desktop()->width()-mw->frameGeometry().width())/2;
int y = (qApp->desktop()->height()-mw->frameGeometry().height())/2;
mw->move( QMAX(x,0), QMAX(y,0) );
#ifdef Q_WS_QWS
if ( !nomaximize )
mw->showMaximized();
#endif
}
if ( max && !nomaximize )
mw->showMaximized();
else
mw->show();
}
}
}
static void qpe_show_dialog( QDialog* d, bool nomax )
{
QSize sh = d->sizeHint();
int w = QMAX(sh.width(),d->width());
int h = QMAX(sh.height(),d->height());
if ( d->parentWidget() && !d->parentWidget()->topLevelWidget()->isMaximized() )
nomax = TRUE;
#ifndef Q_WS_QWS
QSize s(qApp->desktop()->width(), qApp->desktop()->height() );
#else
QSize s(qt_maxWindowRect.width(), qt_maxWindowRect.height() );
#endif
int maxX = s.width() - (d->frameGeometry().width() - d->geometry().width());
int maxY = s.height() - (d->frameGeometry().height() - d->geometry().height());
if ( (w >= maxX && h >= maxY) || ( (!nomax) && ( w > s.width()*3/4 || h > s.height()*3/4 ) ) ) {
d->showMaximized();
} else {
// try centering the dialog around its parent
QPoint p(0,0);
if ( d->parentWidget() ) {
QPoint pp = d->parentWidget()->mapToGlobal( QPoint(0,0) );
p = QPoint( pp.x() + d->parentWidget()->width()/2,
pp.y() + d->parentWidget()->height()/ 2 );
} else {
p = QPoint( maxX/2, maxY/2 );
}
p = QPoint( p.x() - w/2, p.y() - h/2 );
// qDebug("p(x,y) is %d %d", p.x(), p.y() );
if ( w >= maxX ) {
if ( p.y() < 0 )
p.setY(0);
if ( p.y() + h > maxY )
p.setY( maxY - h);
d->resize(maxX, h);
d->move(0, p.y() );
} else if ( h >= maxY ) {
if ( p.x() < 0 )
p.setX(0);
if ( p.x() + w > maxX )
p.setX( maxX - w);
d->resize(w, maxY);
d->move(p.x(),0);
} else {
d->resize(w, h);
}
d->show();
}
}
static bool read_widget_rect(const QString &app, bool &maximized, QPoint &p, QSize &s)
{
maximized = TRUE;
// 350 is the trigger in qwsdefaultdecoration for providing a resize button
if ( qApp->desktop()->width() <= 350 )
return FALSE;
Config cfg( "qpe" );
cfg.setGroup("ApplicationPositions");
QString str = cfg.readEntry( app, QString::null );
QStringList l = QStringList::split(",", str);
if ( l.count() == 5) {
p.setX( l[0].toInt() );
p.setY( l[1].toInt() );
s.setWidth( l[2].toInt() );
s.setHeight( l[3].toInt() );
maximized = l[4].toInt();
return TRUE;
}
return FALSE;
}
static bool validate_widget_size(const QWidget *w, QPoint &p, QSize &s)
{
#ifndef Q_WS_QWS
QRect qt_maxWindowRect = qApp->desktop()->geometry();
#endif
int maxX = qt_maxWindowRect.width();
int maxY = qt_maxWindowRect.height();
int wWidth = s.width() + ( w->frameGeometry().width() - w->geometry().width() );
int wHeight = s.height() + ( w->frameGeometry().height() - w->geometry().height() );
// total window size is not allowed to be larger than desktop window size
if ( ( wWidth >= maxX ) && ( wHeight >= maxY ) )
return FALSE;
if ( wWidth > maxX ) {
s.setWidth( maxX - (w->frameGeometry().width() - w->geometry().width() ) );
wWidth = maxX;
}
if ( wHeight > maxY ) {
s.setHeight( maxY - (w->frameGeometry().height() - w->geometry().height() ) );
wHeight = maxY;
}
// any smaller than this and the maximize/close/help buttons will be overlapping
if ( wWidth < 80 || wHeight < 60 )
return FALSE;
if ( p.x() < 0 )
p.setX(0);
if ( p.y() < 0 )
p.setY(0);
if ( p.x() + wWidth > maxX )
p.setX( maxX - wWidth );
if ( p.y() + wHeight > maxY )
p.setY( maxY - wHeight );
return TRUE;
}
static void store_widget_rect(QWidget *w, QString &app)
{
// 350 is the trigger in qwsdefaultdecoration for providing a resize button
if ( qApp->desktop()->width() <= 350 )
return;
// we use these to map the offset of geometry and pos. ( we can only use normalGeometry to
// get the non-maximized version, so we have to do it the hard way )
int offsetX = w->x() - w->geometry().left();
int offsetY = w->y() - w->geometry().top();
QRect r;
if ( w->isMaximized() )
r = ( (HackWidget *) w)->normalGeometry();
else
r = w->geometry();
// Stores the window placement as pos(), size() (due to the offset mapping)
Config cfg( "qpe" );
cfg.setGroup("ApplicationPositions");
QString s;
s.sprintf("%d,%d,%d,%d,%d", r.left() + offsetX, r.top() + offsetY, r.width(), r.height(), w->isMaximized() );
cfg.writeEntry( app, s );
}
static bool setWidgetCaptionFromAppName( QWidget* /*mw*/, const QString& /*appName*/, const QString& /*appsPath*/ )
{
/*
// This works but disable it for now until it is safe to apply
// What is does is scan the .desktop files of all the apps for
// the applnk that has the corresponding argv[0] as this program
// then it uses the name stored in the .desktop file as the caption
// for the main widget. This saves duplicating translations for
// the app name in the program and in the .desktop files.
AppLnkSet apps( appsPath );
QList<AppLnk> appsList = apps.children();
for ( QListIterator<AppLnk> it(appsList); it.current(); ++it ) {
if ( (*it)->exec() == appName ) {
mw->setCaption( (*it)->name() );
return TRUE;
}
}
*/
return FALSE;
}
void show(QWidget* mw, bool nomax)
{
setWidgetCaptionFromAppName( mw, appName, QPEApplication::qpeDir() + "apps" );
nomaximize = nomax;
qpe_main_widget = mw;
qcopQok = TRUE;
#ifndef QT_NO_COP
sendQCopQ();
#endif
if ( preloaded ) {
if (forceshow)
show_mx(mw, nomax, appName);
}
else if ( keep_running ) {
show_mx(mw, nomax, appName);
}
}
void loadTextCodecs()
{
QString path = QPEApplication::qpeDir() + "/plugins/textcodecs";
#ifdef Q_OS_MACX
QDir dir( path, "lib*.dylib" );
#else
QDir dir( path, "lib*.so" );
#endif
QStringList list;
if ( dir. exists ( ))
list = dir.entryList();
QStringList::Iterator it;
for ( it = list.begin(); it != list.end(); ++it ) {
TextCodecInterface *iface = 0;
QLibrary *lib = new QLibrary( path + "/" + *it );
if ( lib->queryInterface( IID_QtopiaTextCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) {
QValueList<int> mibs = iface->mibEnums();
for (QValueList<int>::ConstIterator i = mibs.begin(); i != mibs.end(); ++i) {
(void)iface->createForMib(*i);
// ### it exists now; need to remember if we can delete it
}
}
else {
lib->unload();
delete lib;
}
}
}
void loadImageCodecs()
{
QString path = QPEApplication::qpeDir() + "/plugins/imagecodecs";
#ifdef Q_OS_MACX
QDir dir( path, "lib*.dylib" );
#else
QDir dir( path, "lib*.so" );
#endif
QStringList list;
if ( dir. exists ( ))
list = dir.entryList();
QStringList::Iterator it;
for ( it = list.begin(); it != list.end(); ++it ) {
ImageCodecInterface *iface = 0;
QLibrary *lib = new QLibrary( path + "/" + *it );
if ( lib->queryInterface( IID_QtopiaImageCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) {
QStringList formats = iface->keys();
for (QStringList::ConstIterator i = formats.begin(); i != formats.end(); ++i) {
(void)iface->installIOHandler(*i);
// ### it exists now; need to remember if we can delete it
}
}
else {
lib->unload();
delete lib;
}
}
}
};
class ResourceMimeFactory : public QMimeSourceFactory
{
public:
ResourceMimeFactory() : resImage( 0 )
{
setFilePath( Global::helpPath() );
setExtensionType( "html", "text/html;charset=UTF-8" );
}
~ResourceMimeFactory() {
delete resImage;
}
const QMimeSource* data( const QString& abs_name ) const
{
const QMimeSource * r = QMimeSourceFactory::data( abs_name );
if ( !r ) {
int sl = abs_name.length();
do {
sl = abs_name.findRev( '/', sl - 1 );
QString name = sl >= 0 ? abs_name.mid( sl + 1 ) : abs_name;
int dot = name.findRev( '.' );
if ( dot >= 0 )
name = name.left( dot );
QImage img = Resource::loadImage( name );
if ( !img.isNull() ) {
delete resImage;
resImage = new QImageDrag( img );
r = resImage;
}
}
while ( !r && sl > 0 );
}
return r;
}
private:
mutable QImageDrag *resImage;
};
static int& hack(int& i)
{
#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
// These should be created, but aren't in Qt 2.3.0
(void)new QUtf8Codec;
(void)new QUtf16Codec;
#endif
return i;
}
static int muted = 0;
static int micMuted = 0;
static void setVolume( int t = 0, int percent = -1 )
{
switch ( t ) {
case 0: {
Config cfg( "qpe" );
cfg.setGroup( "Volume" );
if ( percent < 0 )
percent = cfg.readNumEntry( "VolumePercent", 50 );
#ifndef QT_NO_SOUND
int fd = 0;
+#ifdef QT_QWS_DEVFS
+ if ( ( fd = open( "/dev/sound/mixer", O_RDWR ) ) >= 0 ) {
+#else
if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
+#endif
int vol = muted ? 0 : percent;
// set both channels to same volume
vol |= vol << 8;
ioctl( fd, MIXER_WRITE( SOUND_MIXER_VOLUME ), &vol );
::close( fd );
}
#endif
}
break;
}
}
static void setMic( int t = 0, int percent = -1 )
{
switch ( t ) {
case 0: {
Config cfg( "qpe" );
cfg.setGroup( "Volume" );
if ( percent < 0 )
percent = cfg.readNumEntry( "Mic", 50 );
#ifndef QT_NO_SOUND
int fd = 0;
int mic = micMuted ? 0 : percent;
+#ifdef QT_QWS_DEVFS
+ if ( ( fd = open( "/dev/sound/mixer", O_RDWR ) ) >= 0 ) {
+#else
if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
+#endif
ioctl( fd, MIXER_WRITE( SOUND_MIXER_MIC ), &mic );
::close( fd );
}
#endif
}
break;
}
}
static void setBass( int t = 0, int percent = -1 )
{
switch ( t ) {
case 0: {
Config cfg( "qpe" );
cfg.setGroup( "Volume" );
if ( percent < 0 )
percent = cfg.readNumEntry( "BassPercent", 50 );
#ifndef QT_NO_SOUND
int fd = 0;
int bass = percent;
+#ifdef QT_QWS_DEVFS
+ if ( ( fd = open( "/dev/sound/mixer", O_RDWR ) ) >= 0 ) {
+#else
if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
+#endif
ioctl( fd, MIXER_WRITE( SOUND_MIXER_BASS ), &bass );
::close( fd );
}
#endif
}
break;
}
}
static void setTreble( int t = 0, int percent = -1 )
{
switch ( t ) {
case 0: {
Config cfg( "qpe" );
cfg.setGroup( "Volume" );
if ( percent < 0 )
percent = cfg.readNumEntry( "TreblePercent", 50 );
#ifndef QT_NO_SOUND
int fd = 0;
int treble = percent;
+#ifdef QT_QWS_DEVFS
+ if ( ( fd = open( "/dev/sound/mixer", O_RDWR ) ) >= 0 ) {
+#else
if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
+#endif
ioctl( fd, MIXER_WRITE( SOUND_MIXER_TREBLE ), &treble );
::close( fd );
}
#endif
}
break;
}
}
/**
\class QPEApplication
\brief The QPEApplication class implements various system services
that are available to all Qtopia applications.
Simply by using QPEApplication instead of QApplication, a standard Qt
application becomes a Qtopia application. It automatically follows
style changes, quits and raises, and in the
case of \link docwidget.html document-oriented\endlink applications,
changes the currently displayed document in response to the environment.
To create a \link docwidget.html document-oriented\endlink
application use showMainDocumentWidget(); to create a
non-document-oriented application use showMainWidget(). The
keepRunning() function indicates whether the application will
continue running after it's processed the last \link qcop.html
QCop\endlink message. This can be changed using setKeepRunning().
A variety of signals are emitted when certain events occur, for
example, timeChanged(), clockChanged(), weekChanged(),
dateFormatChanged() and volumeChanged(). If the application receives
a \link qcop.html QCop\endlink message on the application's
QPE/Application/\e{appname} channel, the appMessage() signal is
emitted. There are also flush() and reload() signals, which
are emitted when synching begins and ends respectively - upon these
signals, the application should save and reload any data
files that are involved in synching. Most of these signals will initially
be received and unfiltered through the appMessage() signal.
This class also provides a set of useful static functions. The
qpeDir() and documentDir() functions return the respective paths.
The grabKeyboard() and ungrabKeyboard() functions are used to
control whether the application takes control of the device's
physical buttons (e.g. application launch keys). The stylus' mode of
operation is set with setStylusOperation() and retrieved with
stylusOperation(). There are also setInputMethodHint() and
inputMethodHint() functions.
\ingroup qtopiaemb
*/
/*!
\fn void QPEApplication::clientMoused()
\internal
*/
/*!
\fn void QPEApplication::timeChanged();
This signal is emitted when the time changes outside the normal
passage of time, i.e. if the time is set backwards or forwards.
*/
/*!
\fn void QPEApplication::clockChanged( bool ampm );
This signal is emitted when the user changes the clock's style. If
\a ampm is TRUE, the user wants a 12-hour AM/PM clock, otherwise,
they want a 24-hour clock.
*/
/*!
\fn void QPEApplication::volumeChanged( bool muted )
This signal is emitted whenever the mute state is changed. If \a
muted is TRUE, then sound output has been muted.
*/
/*!
\fn void QPEApplication::weekChanged( bool startOnMonday )
This signal is emitted if the week start day is changed. If \a
startOnMonday is TRUE then the first day of the week is Monday; if
\a startOnMonday is FALSE then the first day of the week is
Sunday.
*/
/*!
\fn void QPEApplication::dateFormatChanged(DateFormat)
This signal is emitted whenever the date format is changed.
*/
/*!
\fn void QPEApplication::flush()
###
*/
/*!
\fn void QPEApplication::reload()
*/
void QPEApplication::processQCopFile()
{
QString qcopfn("/tmp/qcop-msg-");
qcopfn += d->appName; // append command name
QFile f(qcopfn);
if ( f.open(IO_ReadWrite) ) {
#ifndef Q_OS_WIN32
flock(f.handle(), LOCK_EX);
#endif
QDataStream ds(&f);
QCString channel, message;
QByteArray data;
while(!ds.atEnd()) {
ds >> channel >> message >> data;
d->enqueueQCop(channel,message,data);
}
::ftruncate(f.handle(), 0);
#ifndef Q_OS_WIN32
f.flush();
flock(f.handle(), LOCK_UN);
#endif
}
#endif
}
/*!
\fn void QPEApplication::appMessage( const QCString& msg, const QByteArray& data )
This signal is emitted when a message is received on this
application's QPE/Application/<i>appname</i> \link qcop.html
QCop\endlink channel.
The slot to which you connect this signal uses \a msg and \a data
in the following way:
\code
void MyWidget::receive( const QCString& msg, const QByteArray& data )
{
QDataStream stream( data, IO_ReadOnly );
if ( msg == "someMessage(int,int,int)" ) {
int a,b,c;
stream >> a >> b >> c;
...
} else if ( msg == "otherMessage(QString)" ) {
...
}
}
\endcode
\sa qcop.html
Note that messages received here may be processed by qpe application
and emitted as signals, such as flush() and reload().
*/
/*!
Constructs a QPEApplication just as you would construct
a QApplication, passing \a argc, \a argv, and \a t.
For applications, \a t should be the default, GuiClient. Only
the Qtopia server passes GuiServer.
*/
QPEApplication::QPEApplication( int & argc, char **argv, Type t )
: QApplication( hack(argc), argv, t ), pidChannel( 0 )
{
QPixmapCache::setCacheLimit(256); // sensible default for smaller devices.
d = new QPEApplicationData;
d->loadTextCodecs();
d->loadImageCodecs();
setFont( QFont( d->fontFamily, d->fontSize ) );
AppLnk::setSmallIconSize( d->smallIconSize );
AppLnk::setBigIconSize( d->bigIconSize );
QMimeSourceFactory::setDefaultFactory( new ResourceMimeFactory );
connect( this, SIGNAL( lastWindowClosed() ), this, SLOT( hideOrQuit() ) );
sysChannel = new QCopChannel( "QPE/System", this );
connect( sysChannel, SIGNAL( received(const QCString&,const QByteArray&) ),
this, SLOT( systemMessage(const QCString&,const QByteArray&) ) );
/* COde now in initapp */
#if 0
#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
QString qcopfn( "/tmp/qcop-msg-" );
qcopfn += QString( argv[ 0 ] ); // append command name
QFile f( qcopfn );
if ( f.open( IO_ReadOnly ) ) {
flock( f.handle(), LOCK_EX );
}
QCString channel = QCString( argv[ 0 ] );
channel.replace( QRegExp( ".*/" ), "" );
d->appName = channel;
channel = "QPE/Application/" + channel;
pidChannel = new QCopChannel( channel, this );
connect( pidChannel, SIGNAL( received(const QCString&,const QByteArray&) ),
this, SLOT( pidMessage(const QCString&,const QByteArray&) ) );
if ( f.isOpen() ) {
d->keep_running = FALSE;
QDataStream ds( &f );
QCString channel, message;
QByteArray data;
while ( !ds.atEnd() ) {
ds >> channel >> message >> data;
d->enqueueQCop( channel, message, data );
}
flock( f.handle(), LOCK_UN );
f.close();
f.remove();
}
for ( int a = 0; a < argc; a++ ) {
if ( qstrcmp( argv[ a ], "-preload" ) == 0 ) {
argv[ a ] = argv[ a + 1 ];
a++;
d->preloaded = TRUE;
argc -= 1;
}
else if ( qstrcmp( argv[ a ], "-preload-show" ) == 0 ) {
argv[ a ] = argv[ a + 1 ];
a++;
d->preloaded = TRUE;
d->forceshow = TRUE;
argc -= 1;
}
}
/* overide stored arguments */
setArgs( argc, argv );
#endif
#else
initApp( argc, argv );
#endif
#ifdef Q_WS_QWS
/* load the font renderer factories */
FontDatabase::loadRenderers();
#endif
#ifndef QT_NO_TRANSLATION
d->langs = Global::languageList();
for ( QStringList::ConstIterator it = d->langs.begin(); it != d->langs.end(); ++it ) {
QString lang = *it;
installTranslation( lang + "/libopie.qm");
installTranslation( lang + "/libqpe.qm" );
installTranslation( lang + "/" + d->appName + ".qm" );
//###language/font hack; should look it up somewhere
#ifdef QWS
if ( lang == "ja" || lang == "zh_CN" || lang == "zh_TW" || lang == "ko" ) {
QFont fn = FontManager::unicodeFont( FontManager::Proportional );
setFont( fn );
}
#endif
}
#endif
applyStyle();
if ( type() == GuiServer ) {
setVolume();
}
installEventFilter( this );
QPEMenuToolFocusManager::initialize();
#ifdef QT_NO_QWS_CURSOR
// if we have no cursor, probably don't want tooltips
QToolTip::setEnabled( FALSE );
#endif
}
#ifdef QTOPIA_INTERNAL_INITAPP
void QPEApplication::initApp( int argc, char **argv )
{
delete pidChannel;
d->keep_running = TRUE;
d->preloaded = FALSE;
d->forceshow = FALSE;
QCString channel = QCString(argv[0]);
channel.replace(QRegExp(".*/"),"");
d->appName = channel;
#if QT_VERSION > 235
qt_fbdpy->setIdentity( channel ); // In Qt/E 2.3.6
#endif
channel = "QPE/Application/" + channel;
pidChannel = new QCopChannel( channel, this);
connect( pidChannel, SIGNAL(received(const QCString&,const QByteArray&)),
this, SLOT(pidMessage(const QCString&,const QByteArray&)));
processQCopFile();
d->keep_running = d->qcopq.isEmpty();
for (int a=0; a<argc; a++) {
if ( qstrcmp(argv[a],"-preload")==0 ) {
argv[a] = argv[a+1];
a++;
d->preloaded = TRUE;
argc-=1;
} else if ( qstrcmp(argv[a],"-preload-show")==0 ) {
argv[a] = argv[a+1];
a++;
d->preloaded = TRUE;
d->forceshow = TRUE;
argc-=1;
}
}
/* overide stored arguments */
setArgs(argc, argv);
/* install translation here */
for ( QStringList::ConstIterator it = d->langs.begin(); it != d->langs.end(); ++it )
installTranslation( (*it) + "/" + d->appName + ".qm" );
}
#endif
static QPtrDict<void>* inputMethodDict = 0;
static void createInputMethodDict()
{
if ( !inputMethodDict )
inputMethodDict = new QPtrDict<void>;
}
/*!
Returns the currently set hint to the system as to whether
widget \a w has any use for text input methods.
\sa setInputMethodHint() InputMethodHint
*/
QPEApplication::InputMethodHint QPEApplication::inputMethodHint( QWidget * w )
{
if ( inputMethodDict && w )
return ( InputMethodHint ) ( int ) inputMethodDict->find( w );
return Normal;
}
/*!
\enum QPEApplication::InputMethodHint
\value Normal the application sometimes needs text input (the default).
\value AlwaysOff the application never needs text input.
\value AlwaysOn the application always needs text input.
*/
/*!
Hints to the system that widget \a w has use for text input methods
as specified by \a mode.
\sa inputMethodHint() InputMethodHint
*/
void QPEApplication::setInputMethodHint( QWidget * w, InputMethodHint mode )
{
createInputMethodDict();