2 Commits

Author SHA1 Message Date
ruglory 12a2ff2051 debian dir added for deb build
git-svn-id: https://svn.code.sf.net/p/qlscribe/svn/tags/release-0.7@70 cac9541e-1b8d-4bfa-827e-589bba606050
2009-02-20 20:44:10 +00:00
ruglory 24d1ce7e0b Tagging the 0.7 release
git-svn-id: https://svn.code.sf.net/p/qlscribe/svn/tags/release-0.7@69 cac9541e-1b8d-4bfa-827e-589bba606050
2009-02-16 01:53:03 +00:00
35 changed files with 538 additions and 1898 deletions
+8 -8
View File
@@ -22,15 +22,15 @@ PROJECT( qlscribe )
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0)
SET( CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake )
# lightSribe provides library only for m32 (yet?)
IF( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND CMAKE_COMPILER_IS_GNUCXX )
ADD_DEFINITIONS( -m32 )
SET( CMAKE_EXE_LINKER_FLAGS "-m32 ${CMAKE_EXE_LINKER_FLAGS}" )
ENDIF( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND CMAKE_COMPILER_IS_GNUCXX )
SET( QLSCRIBE_DBUS_SERVICE org.lightscribe )
SET( QLSCRIBE_DBUS_MANAGER_SERVICE ${QLSCRIBE_DBUS_SERVICE}.Manager )
SET( QLSCRIBE_DBUS_DRIVES_SERVICE ${QLSCRIBE_DBUS_SERVICE}.drives )
SET( QLSCRIBE_DBUS_PATH /org/lightscribe )
SET( QLSCRIBE_DBUS_MANAGER_PATH ${QLSCRIBE_DBUS_PATH}/Manager ) # path to manager
SET( QLSCRIBE_DBUS_DRIVES_PATH ${QLSCRIBE_DBUS_PATH}/drives ) # base path under which drives located
SET( CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake )
FIND_PACKAGE( Qt4 REQUIRED )
FIND_PACKAGE( LightScribe REQUIRED )
SUBDIRS( src )
SUBDIRS( resources )
SUBDIRS( lscribed )
+11 -16
View File
@@ -4,36 +4,31 @@ Qt lightScribe Installaton instructions
To compile and install, first download release from http://qlscribe.sourceforge.net/
or check out project from subversion repository for particular release:
svn co https://qlscribe.svn.sourceforge.net/svnroot/qlscribe/tags/release-N.M qlscribe
svn co https://qlscribe.svn.sourceforge.net/svnroot/qlscribe/tags/release-N.M qlscribe
or if you want to test latest development version:
svn co https://qlscribe.svn.sourceforge.net/svnroot/qlscribe/trunk qlscribe
svn co https://qlscribe.svn.sourceforge.net/svnroot/qlscribe/trunk qlscribe
Then go to the source directory and type:
mkdir build
cd build
cmake ..
mkdir build
cd build
cmake ..
(If you want to install in a different path, use instead:
cmake .. -DCMAKE_INSTALL_PREFIX=/install/path)
make
sudo make install
cmake .. -DCMAKE_INSTALL_PREFIX=/install/path)
make
sudo make install
If cmake fails to find lightScribe API specify environment variable LIGHTSCRIBEDIR:
LIGHTSCRIBEDIR=/opt/lightscribe cmake ..
LIGHTSCRIBEDIR=/opt/lightscribe cmake ..
Include files should be in ${LIGHTSCRIBEDIR}/include and lib in ${LIGHTSCRIBEDIR}/lib
You need manually install dbus config and service files. They are located in INSTALL_PATH/share/qlscribe
So on my ubuntu system I do
sudo cp /usr/local/share/qlscribe/lightscribe.conf /etc/dbus-1/system.d/
sudo cp /usr/local/share/qlscribe/org.lightscribe.Manager.service /usr/share/dbus-1/system-services/
sudo /etc/init.d/dbus reload
Your system may have different path please refer dbus system daemon documentation
Once installed, you can start Qt lightScribe by typing "qlscribe", but due to API
requirement if you want to burn qlscribe has to be started by root as "sudo qlscribe"
You need to download lightScribe SDK for qlscribe to build and lightScribe runtime
for qlscribe to run. For details see lightScribe webpage:
-6
View File
@@ -1,11 +1,5 @@
NEWS - list of user-visible changes between releases of qlscribe
New in 0.8:
Application is splitted into 2 parts: qlscribe and dbus daemon lscribed
qlscribe does not require sticky bit and can be compiled in 64 bit mode if necessary
lscribed provides lightScribe service through system bus
lscribed is activated by dbus daemon and automatically terminates after 5 minutes of inactivity
New in 0.7:
Z-order of items saved and resored
Bugfix for not loading radius for round text
-55
View File
@@ -1,55 +0,0 @@
# qlscribe - Qt based application to print lightScribe discs
#
# Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# $Id$
FIND_PATH( DBUS_INCLUDE_DIR dbus/dbus.h
PATH_SUFFIXES dbus-1.0 )
IF( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" )
FIND_LIBRARY( DBUS_LIBRARY dbus-1
PATHS /lib32 /usr/lib32 /usr/local/lib32
NO_DEFAULT_PATH )
ENDIF( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" )
FIND_LIBRARY( DBUS_LIBRARY dbus-1 )
get_filename_component( _dbusLibPath ${DBUS_LIBRARY} PATH )
FIND_PATH( DBUS_LIBINCLUDE_DIR dbus/dbus-arch-deps.h
PATHS /lib /usr/lib /usr/local/lib ${_dbusLibPath}
PATH_SUFFIXES dbus-1.0/include )
if( DBUS_INCLUDE_DIR AND DBUS_LIBINCLUDE_DIR AND DBUS_LIBRARY )
SET( Dbus32_FOUND TRUE )
SET( DBUS_LIBRARIES ${DBUS_LIBRARY} )
INCLUDE_DIRECTORIES(${DBUS_INCLUDE_DIR} ${DBUS_LIBINCLUDE_DIR} )
ENDIF( DBUS_INCLUDE_DIR AND DBUS_LIBINCLUDE_DIR AND DBUS_LIBRARY )
IF( Dbus32_FOUND )
IF( NOT Dbus32_FIND_QUIETLY )
MESSAGE( STATUS "Found dbus include: ${DBUS_INCLUDE_DIR}" )
MESSAGE( STATUS "Found dbus libraries: ${DBUS_LIBRARIES}" )
ENDIF( NOT Dbus32_FIND_QUIETLY )
ELSE( Dbus32_FOUND )
IF( Dbus32_FIND_REQUIRED )
MESSAGE( FATAL_ERROR "Could not find dbus" )
ENDIF( Dbus32_FIND_REQUIRED )
ENDIF( Dbus32_FOUND )
MARK_AS_ADVANCED( Dbus32_FOUND DBUS_INCLUDE_DIR DBUS_LIBRARY DBUS_LIBINCLUDE_DIR )
-1
View File
@@ -39,4 +39,3 @@ ELSE( LSCRIBE_FOUND )
ENDIF( LightScribe_FIND_REQUIRED )
ENDIF( LSCRIBE_FOUND )
MARK_AS_ADVANCED( LSCRIBE_INCLUDE_DIR LSCRIBE_LIBRARY LSCRIBE_FOUND )
-50
View File
@@ -1,50 +0,0 @@
# qlscribe - Qt based application to print lightScribe discs
#
# Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# $Id$
FIND_PACKAGE( Dbus32 REQUIRED )
FIND_PACKAGE( LightScribe REQUIRED )
SET( LSCRIBED_CONF_FILE ${CMAKE_CURRENT_BINARY_DIR}/lightscribe.conf )
SET( LSCRIBED_SERVICE_FILE ${CMAKE_CURRENT_BINARY_DIR}/${QLSCRIBE_DBUS_SERVICE}.Manager.service )
CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/lscribed.h.in ${CMAKE_CURRENT_BINARY_DIR}/lscribed.h @ONLY )
CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/lightscribe.conf.in ${LSCRIBED_CONF_FILE} @ONLY )
CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/service.in ${LSCRIBED_SERVICE_FILE} @ONLY )
# lightSribe provides library only for m32 (yet?)
IF( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND CMAKE_COMPILER_IS_GNUCXX )
ADD_DEFINITIONS( -m32 )
SET( CMAKE_EXE_LINKER_FLAGS "-m32 -pthread ${CMAKE_EXE_LINKER_FLAGS}" )
ENDIF( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND CMAKE_COMPILER_IS_GNUCXX )
SET( LSCRIBED_SRCS main.cpp dbuscpp.cpp drives.cpp managerhandler.cpp drivehandler.cpp
introspecthandler.cpp )
ADD_DEFINITIONS( -Wall )
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} )
ADD_EXECUTABLE( lscribed ${LSCRIBED_SRCS} )
TARGET_LINK_LIBRARIES( lscribed ${LSCRIBE_LIBRARIES} ${DBUS_LIBRARIES} )
INSTALL( TARGETS lscribed DESTINATION sbin )
INSTALL( FILES ${LSCRIBED_CONF_FILE} ${LSCRIBED_SERVICE_FILE} DESTINATION share/qlscribe )
-219
View File
@@ -1,219 +0,0 @@
/* qlscribe - Qt based application to print lightScribe discs
Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$ */
#include "dbuscpp.h"
#include "lscribed.h"
using namespace DBusCpp;
MessageHandler::~MessageHandler()
{
}
std::string MessageHandler::generateInrospectHeader( const std::string &nodename )
{
std::string rez = "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" "
"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">";
rez += " <node";
if( !nodename.empty() )
rez += "=\"" + nodename + "\"";
rez += "> <interface name=\"org.freedesktop.DBus.Introspectable\">"
" <method name=\"Introspect\">"
" <arg name=\"data\" direction=\"out\" type=\"s\"/>"
" </method>"
"</interface>";
return rez;
}
namespace {
DBusObjectPathVTable vtable;
DBusHandlerResult processMessage( DBusConnection *connPtr,
DBusMessage *messagePtr,
void *data )
{
Message message = Message::parameter( messagePtr );
lastActivity = time( 0 );
return reinterpret_cast< MessageHandler * >( data )->processMessage( message );
}
}
Connection::Connection( DBusConnection *conn )
: m_connection( conn )
{
if( !vtable.message_function )
vtable.message_function = processMessage;
}
Connection::~Connection()
{
for( Handlers::iterator it = m_handlers.begin(); it != m_handlers.end(); ++it ) {
dbus_connection_unregister_object_path( m_connection, it->first.c_str() );
delete it->second;
}
}
dbus_uint32_t Connection::send( const Message &msg )
{
dbus_uint32_t rez;
dbus_connection_send( m_connection, msg.m_message, &rez );
return rez;
}
void Connection::registerHandler( const std::string &path, MessageHandler *handler, bool fallback )
{
handler->m_connection = this;
m_handlers.insert( std::make_pair( path, handler ) );
if( fallback )
dbus_connection_register_fallback( m_connection, path.c_str(), &vtable, handler );
else
dbus_connection_register_object_path( m_connection, path.c_str(), &vtable, handler );
}
MessageIter::MessageIter( const MessageIter &an )
: m_iter( an.m_iter ), m_container( an.m_container )
{
if( m_container )
const_cast< MessageIter & >( an ).m_container = 0;
}
MessageIter::~MessageIter()
{
if( m_container )
dbus_message_iter_close_container( m_container, &m_iter );
}
MessageIter MessageIter::openContainer( int elemType, const char *signature )
{
MessageIter rez;
dbus_message_iter_open_container( &m_iter, elemType, signature, &rez.m_iter );
rez.m_container = &m_iter;
return rez;
}
void MessageIter::append( const char *str )
{
dbus_message_iter_append_basic( &m_iter, DBUS_TYPE_STRING, &str );
}
std::string MessageConstIter::signature() const
{
char *ptr = dbus_message_iter_get_signature( const_cast< DBusMessageIter *>( &m_iter ) );
std::string rez( ptr );
dbus_free( ptr );
return rez;
}
MessageConstIter MessageConstIter::recurse() const
{
MessageConstIter rez;
dbus_message_iter_recurse( const_cast< DBusMessageIter *>( &m_iter ), &rez.m_iter );
return rez;
}
void *MessageConstIter::getFixedArray( int &elements ) const
{
void *data =0;
dbus_message_iter_get_fixed_array( const_cast< DBusMessageIter *>( &m_iter ), &data, &elements );
return data;
}
Message::Message( int type )
{
m_message = dbus_message_new( type );
}
Message::Message( const Message &msg )
: m_message( msg.m_message )
{
dbus_message_ref( m_message );
}
Message::Message( DBusMessage *msg, bool ownership )
: m_message( msg )
{
if( !ownership )
dbus_message_ref( m_message );
}
Message::~Message()
{
dbus_message_unref( m_message );
}
Message Message::newSignal( const std::string &path,
const std::string &interface,
const std::string &name )
{
return Message( dbus_message_new_signal( path.c_str(), interface.c_str(), name.c_str() ),
true );
}
Message Message::newMethodReturn() const
{
return Message( dbus_message_new_method_return( m_message ), true );
}
Message Message::newError( const char *error, const char *message ) const
{
return Message( dbus_message_new_error( m_message, error, message ), true );
}
MessageConstIter Message::constIter() const
{
MessageConstIter rez;
dbus_message_iter_init( m_message, &rez.m_iter );
return rez;
}
MessageIter Message::appendIter()
{
MessageIter rez;
dbus_message_iter_init_append( m_message, &rez.m_iter );
return rez;
}
void Message::append( const char *str )
{
dbus_message_append_args( m_message, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID );
}
void Message::append( int32_t i )
{
dbus_message_append_args( m_message, DBUS_TYPE_INT32, &i, DBUS_TYPE_INVALID );
}
const char *Message::path() const
{
return dbus_message_get_path( m_message );
}
const char *Message::interface() const
{
return dbus_message_get_interface( m_message );
}
const char *Message::member() const
{
return dbus_message_get_member( m_message );
}
-144
View File
@@ -1,144 +0,0 @@
/* qlscribe - Qt based application to print lightScribe discs
Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$ */
#ifndef DBUSCPP_H
#define DBUSCPP_H
#include <dbus/dbus.h>
#include <string>
#include <map>
namespace DBusCpp {
class Message;
class Connection;
class MessageHandler {
public:
MessageHandler() : m_connection( 0 ) {}
virtual ~MessageHandler();
virtual DBusHandlerResult processMessage( const Message &msg ) = 0;
Connection *connection() const { return m_connection; }
static std::string generateInrospectHeader( const std::string &nodename = std::string() );
friend class Connection;
private:
Connection *m_connection;
};
class Connection {
public:
Connection( DBusConnection *conn );
Connection( const Connection &conn ) : m_connection( conn.m_connection ) {}
~Connection();
dbus_uint32_t send( const Message &msg );
void registerHandler( const std::string &path, MessageHandler *handler, bool fallback );
void flush() { dbus_connection_flush( m_connection ); }
DBusConnection *ptr() const { return m_connection; }
private:
typedef std::map< std::string, MessageHandler * > Handlers;
DBusConnection *m_connection;
Handlers m_handlers;
};
class MessageIter {
public:
MessageIter( const MessageIter &an );
~MessageIter();
MessageIter openContainer( int eemType, const char *signature );
void append( const std::string &str ) { append( str.c_str() ); }
void append( const char *str );
friend class Message;
private:
MessageIter() : m_container( 0 ) {}
DBusMessageIter m_iter;
DBusMessageIter *m_container;
};
class MessageConstIter {
public:
MessageConstIter recurse() const;
std::string signature() const;
bool next() { return dbus_message_iter_next( &m_iter ); }
bool hasNext() const { return dbus_message_iter_has_next( const_cast< DBusMessageIter *>( &m_iter ) ); }
void *getFixedArray( int &elements ) const;
template <typename T> T getValue() const
{
T rez = T();
dbus_message_iter_get_basic( const_cast< DBusMessageIter *>( &m_iter ), &rez );
return rez;
}
friend class Message;
private:
DBusMessageIter m_iter;
};
class Message {
public:
explicit Message( int type );
Message( const Message &msg );
~Message();
static Message parameter( DBusMessage *msg ) { return Message( msg, false ); }
Message newMethodReturn() const;
Message newError( const char *error, const char *message ) const;
static Message newSignal( const std::string &path,
const std::string &interface,
const std::string &name );
bool isMethodCall( const char *interface, const char *method ) const
{ return dbus_message_is_method_call( m_message, interface, method ); }
MessageConstIter constIter() const;
MessageIter appendIter();
void append( const std::string &str ) { append( str.c_str() ); }
void append( const char *str );
void append( int32_t i );
const char *path() const;
const char *interface() const;
const char *member() const;
friend class Connection;
private:
Message( DBusMessage *msg, bool ownership );
DBusMessage *m_message;
};
}
#endif // DBUSCPP_H
-116
View File
@@ -1,116 +0,0 @@
/* qlscribe - Qt based application to print lightScribe discs
Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$ */
#include <iostream>
#include <string.h>
#include "lscribed.h"
#include "drivehandler.h"
#include "drives.h"
using namespace DBusCpp;
static const char *strDriveIntrospect =
"<interface name=\"org.lightscribe.drive\">\
<signal name=\"prepareProgress\">\
<arg name=\"current\" type=\"i\" direction=\"out\"/>\
<arg name=\"final\" type=\"i\" direction=\"out\"/>\
</signal>\
<signal name=\"labelProgress\">\
<arg name=\"current\" type=\"i\" direction=\"out\"/>\
<arg name=\"final\" type=\"i\" direction=\"out\"/>\
</signal>\
<signal name=\"timeEstimate\">\
<arg name=\"time\" type=\"i\" direction=\"out\"/>\
</signal>\
<signal name=\"finished\">\
<arg name=\"status\" type=\"i\" direction=\"out\"/>\
</signal>\
<method name=\"preview\">\
<arg type=\"s\" direction=\"out\"/>\
<arg name=\"params\" type=\"(iiii)\" direction=\"in\"/>\
<arg name=\"image\" type=\"ay\" direction=\"in\"/>\
<arg name=\"previewSize\" type=\"(ii)\" direction=\"in\"/>\
</method>\
<method name=\"print\">\
<arg name=\"params\" type=\"(iiii)\" direction=\"in\"/>\
<arg name=\"image\" type=\"ay\" direction=\"in\"/>\
</method>\
<method name=\"abort\">\
</method>\
<method name=\"name\">\
<arg direction=\"out\" type=\"s\"/>\
</method>\
</interface>";
DBusHandlerResult DriveHandler::processMessage( const Message &msg )
{
DBusHandlerResult rez = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
const char *path = msg.path();
if( !path )
return rez;
const char *item = strrchr( path, '/' );
if( !item )
return rez;
if( item[ 0 ] == '/' ) ++item;
DrivesManager &manager = DrivesManager::instance();
if( msg.isMethodCall( "org.freedesktop.DBus.Introspectable", "Introspect" ) ) {
std::string introspect = generateInrospectHeader();
if( strcmp( item, "drives" ) == 0 ) {
for( DrivesManager::const_iterator it = manager.begin(); it != manager.end(); ++it )
introspect += "<node name=\"" + (*it)->path() + "\"/>";
}
else
introspect += strDriveIntrospect;
introspect += "</node>";
Message reply = msg.newMethodReturn();
reply.append( introspect );
connection()->send( reply );
return rez = DBUS_HANDLER_RESULT_HANDLED;
}
const char *interface = msg.interface();
if( !interface || strcmp( interface, "org.lightscribe.drive" ) )
return rez;
const char *member = msg.member();
if( !member )
return rez;
DrivesManager::const_iterator f = manager.find( item );
if( f == manager.end() )
return rez;
rez = DBUS_HANDLER_RESULT_HANDLED;
std::cout << "calling method " << member << " on item " << item << std::endl;
(*f)->invoke( member, msg );
return rez;
}
-35
View File
@@ -1,35 +0,0 @@
/* qlscribe - Qt based application to print lightScribe discs
Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$ */
#ifndef DRIVEHANDLER_H
#define DRIVEHANDLER_H
#include "dbuscpp.h"
namespace DBusCpp {
class DriveHandler : public MessageHandler {
public:
virtual DBusHandlerResult processMessage( const Message &msg );
};
}
#endif // DRIVEHANDLER_H
-406
View File
@@ -1,406 +0,0 @@
/* qlscribe - Qt based application to print lightScribe discs
Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$ */
#include "drives.h"
#include "lscribed.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <lightscribe_cxx.h>
#include <fstream>
#include <iostream>
using namespace LightScribe;
static pthread_key_t drivesKey;
static Drive *getDriveForThread()
{
return reinterpret_cast<Drive *>( pthread_getspecific( drivesKey ) );
}
static bool clAbortLabel()
{
Drive *drive = getDriveForThread();
return drive ? drive->isAborted() : true;
}
static void clReportPrepareProgress( long current, long final )
{
Drive *drive = getDriveForThread();
if( drive ) {
DBusCpp::Message msg = DBusCpp::Message::newSignal( drive->fullPath(),
"org.lightscribe.drive",
"prepareProgress" );
msg.append( current );
msg.append( final );
DrivesManager::instance().connection().send( msg );
}
}
static void clReportLabelProgress( long current, long final )
{
Drive *drive = getDriveForThread();
if( drive ) {
DBusCpp::Message msg = DBusCpp::Message::newSignal( drive->fullPath(),
"org.lightscribe.drive",
"labelProgress" );
msg.append( current );
msg.append( final );
DrivesManager::instance().connection().send( msg );
}
}
void clReportFinished( LSError status )
{
Drive *drive = getDriveForThread();
if( drive ) {
DBusCpp::Message msg = DBusCpp::Message::newSignal( drive->fullPath(),
"org.lightscribe.drive",
"finished" );
msg.append( status );
DrivesManager::instance().connection().send( msg );
}
}
static bool clReportLabelTimeEstimate( long time )
{
Drive *drive = getDriveForThread();
if( drive ) {
DBusCpp::Message msg = DBusCpp::Message::newSignal( drive->fullPath(),
"org.lightscribe.drive",
"timeEstimate" );
msg.append( time );
DrivesManager::instance().connection().send( msg );
}
return false;
}
static std::string generateTmp()
{
char *temp = tempnam( 0, ".bmp" );
std::string rez( temp );
free( temp );
return rez;
}
Drive::Drive( int index, const std::string &path, const std::string &name )
: m_index( index ), m_path( path ), m_name( name ), m_threadStarted( false ), m_message( 0 )
{
}
Drive::~Drive()
{
if( m_threadStarted ) {
pthread_cancel( m_thread );
pthread_join( m_thread, 0 );
pthread_cond_destroy( &m_cond );
}
}
std::string Drive::fullPath() const
{
return std::string( DBusDrivesPath ) + "/" + path();
}
bool Drive::active() const
{
return m_message != 0;
}
void *routine( void *ptr )
{
reinterpret_cast< Drive * >( ptr )->routine();
return ptr;
}
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void Drive::invoke( const std::string &method, const DBusCpp::Message &msg )
{
DrivesManager &man = DrivesManager::instance();
if( method == "name" ) {
DBusCpp::Message reply = msg.newMethodReturn();
reply.append( name() );
man.connection().send( reply );
return;
}
if( method == "abort" ) {
m_aborted = true;
DBusCpp::Message reply = msg.newMethodReturn();
man.connection().send( reply );
return;
}
if( method == "preview" || method == "print" ) {
if( !m_threadStarted ) {
m_threadStarted = true;
pthread_cond_init( &m_cond, 0 );
pthread_create( &m_thread, 0, ::routine, this );
}
pthread_mutex_lock( &mutex );
if( m_message ) {
DBusCpp::Message reply = msg.newError( DBUS_ERROR_FAILED, "drive is busy, try again later" );
man.connection().send( reply );
}
m_aborted = false;
m_message = new DBusCpp::Message( msg );
pthread_cond_signal( &m_cond );
pthread_mutex_unlock( &mutex );
return;
}
DBusCpp::Message reply = msg.newError( DBUS_ERROR_UNKNOWN_METHOD, "method is not supported" );
man.connection().send( reply );
}
void Drive::routine()
{
pthread_setspecific( drivesKey, this );
DrivesManager &man = DrivesManager::instance();
bool first = true;
while( true ) {
pthread_mutex_lock( &mutex );
if( first )
first = false;
else {
delete m_message;
m_message = 0;
}
while( !m_message )
pthread_cond_wait( &m_cond, &mutex );
pthread_mutex_unlock( &mutex );
bool preview = strcmp( m_message->member(), "preview" ) == 0;
LS_LabelMode mode;
LS_DrawOptions options;
LS_PrintQuality quality;
LS_MediaOptimizationLevel level;
char *image = 0;
int imageSize = 0;
LS_Size size;
try {
DBusCpp::MessageConstIter iter = m_message->constIter();
if( iter.signature() != "(iiii)" )
throw std::string( "invalid argument for params: " ) + iter.signature() + ", (iiii) expected";
DBusCpp::MessageConstIter sub = iter.recurse();
mode = LS_LabelMode( sub.getValue<int32_t>() ); sub.next();
options = LS_DrawOptions( sub.getValue<int32_t>() ); sub.next();
quality = LS_PrintQuality( sub.getValue<int32_t>() ); sub.next();
level = LS_MediaOptimizationLevel( sub.getValue<int32_t>() );
if( !iter.next() )
throw std::string( "image argument missing" );
if( iter.signature() != "ay" )
throw std::string( "invalid argument for image: " ) + iter.signature() + ", ay expected";
sub = iter.recurse();
image = reinterpret_cast< char * >( sub.getFixedArray( imageSize ) );
if( preview ) {
if( !iter.next() )
throw std::string( "size argument missing" );
if( iter.signature() != "(ii)" )
throw std::string( "invalid argument for size: " ) + iter.signature() + ", (ii) expected";
sub = iter.recurse();
size.x = sub.getValue<int32_t>(); sub.next();
size.y = sub.getValue<int32_t>();
}
}
catch( const std::string &str ) {
std::cout << "exception " << str << std::endl;
DBusCpp::Message reply = m_message->newError( DBUS_ERROR_INVALID_ARGS, str.c_str() );
man.connection().send( reply );
continue;
}
std::string tmpFile;
if( preview )
tmpFile = generateTmp();
if( m_index == -1 ) {
DBusCpp::Message reply = m_message->newMethodReturn();
if( preview ) { // this is debug drive, so just write input into output
std::ofstream out( tmpFile.c_str() );
out.write( image, imageSize );
out.close();
reply.append( tmpFile );
}
man.connection().send( reply );
continue;
}
const char *function = 0;
try {
const size_t bitmapHeaderSize = 54;
if( size_t( imageSize ) <= bitmapHeaderSize )
throw "Invalid image";
function = "LS_DiscPrintMgr_Create";
DiscPrintMgr manager;
function = "LS_DiscPrintMgr_EnumDiscPrinters";
EnumDiscPrinters printers = manager.EnumDiscPrinters();
if( m_index >= printers.Count() )
throw std::string( "internal error: invalid index" );
DiscPrinter printer = printers.Item( m_index );
function = "LS_DiscPrinter_OpenPrintSession";
DiscPrintSession session = printer.OpenPrintSession();
DBusCpp::Message reply = m_message->newMethodReturn();
if( preview ) {
function = "LS_DiscPrintSession_PrintPreview";
session.PrintPreview( LS_windows_bitmap,
mode,
options,
quality,
level,
image + 14,
bitmapHeaderSize - 14,
image + bitmapHeaderSize,
imageSize - bitmapHeaderSize,
const_cast< char *>( tmpFile.c_str() ),
LS_windows_bitmap,
size,
true );
reply.append( tmpFile );
man.connection().send( reply );
} else {
LS_PrintCallbacks callbacks;
callbacks.AbortLabel = clAbortLabel;
callbacks.ReportPrepareProgress = clReportPrepareProgress;
callbacks.ReportLabelProgress = clReportLabelProgress;
callbacks.ReportFinished = clReportFinished;
callbacks.ReportLabelTimeEstimate = clReportLabelTimeEstimate;
session.SetProgressCallback( &callbacks );
man.connection().send( reply );
function = 0;
session.PrintDisc( LS_windows_bitmap,
mode,
options,
quality,
level,
image + 14,
bitmapHeaderSize - 14,
image + bitmapHeaderSize,
imageSize - bitmapHeaderSize );
}
}
catch( LightScribe::LSException &ex ) {
if( function ) {
char message[ 255 ];
sprintf( message, "\"%s()\" failed with code 0x%X", function, ex.GetCode() );
DBusCpp::Message reply = m_message->newError( DBUS_ERROR_FAILED, message );
man.connection().send( reply );
} else
clReportFinished( ex.GetCode() );
continue;
}
catch( const std::string &str ) {
DBusCpp::Message reply = m_message->newError( DBUS_ERROR_FAILED, str.c_str() );
man.connection().send( reply );
continue;
}
}
}
DrivesManager::DrivesManager()
: m_connection( 0 )
{
}
void DrivesManager::init( DBusCpp::Connection conn, bool debug )
{
pthread_key_create( &drivesKey, 0 );
m_connection = conn;
if( debug )
m_drives.push_back( new Drive( -1, "drived", "Debug printer" ) );
DiscPrintMgr manager;
EnumDiscPrinters printers = manager.EnumDiscPrinters();
const unsigned count = printers.Count();
for( unsigned i = 0; i < count; ++i ) {
DiscPrinter printer = printers.Item( i );
char path[ 10 ];
sprintf( path, "drive%d", i );
m_drives.push_back( new Drive( i, path, printer.GetPrinterDisplayName() ) );
}
}
DrivesManager::~DrivesManager()
{
for( const_iterator f = begin(); f != end(); ++f )
delete *f;
}
DrivesManager &DrivesManager::instance()
{
static DrivesManager theManager;
return theManager;
}
bool DrivesManager::active() const
{
for( const_iterator f = begin(); f != end(); ++f )
if( (*f)->active() )
return true;
return false;
}
DrivesManager::const_iterator DrivesManager::find( const std::string &path ) const
{
const_iterator f;
for( f = begin(); f != end(); ++f )
if( (*f)->path() == path )
break;
return f;
}
-83
View File
@@ -1,83 +0,0 @@
/* qlscribe - Qt based application to print lightScribe discs
Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$ */
#ifndef DRIVES_H
#define DRIVES_H
#include <vector>
#include <string>
#include "dbuscpp.h"
class Drive {
public:
const std::string &path() const { return m_path; }
std::string fullPath() const;
const std::string &name() const { return m_name; }
bool isAborted() const { return m_aborted; }
void invoke( const std::string &method, const DBusCpp::Message &msg );
bool active() const;
friend class DrivesManager;
friend void *routine( void * );
private:
Drive( int index, const std::string &path, const std::string &name );
~Drive();
void routine();
int m_index;
std::string m_path;
std::string m_name;
bool m_aborted;
bool m_threadStarted;
pthread_t m_thread;
pthread_cond_t m_cond;
DBusCpp::Message *m_message;
};
class DrivesManager {
public:
typedef std::vector< Drive * > Drives;
typedef Drives::const_iterator const_iterator;
static DrivesManager &instance();
void init( DBusCpp::Connection conn, bool debug );
const_iterator begin() const { return m_drives.begin(); }
const_iterator end() const { return m_drives.end(); }
const_iterator find( const std::string &path ) const;
bool active() const;
DBusCpp::Connection connection() const { return m_connection; }
private:
DrivesManager();
~DrivesManager();
Drives m_drives;
DBusCpp::Connection m_connection;
};
#endif // DRIVES_H
-58
View File
@@ -1,58 +0,0 @@
/* qlscribe - Qt based application to print lightScribe discs
Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$ */
#include "introspecthandler.h"
#include "lscribed.h"
#include <string.h>
using namespace DBusCpp;
DBusHandlerResult IntrospectHandler::processMessage( const Message &msg )
{
if( msg.isMethodCall( "org.freedesktop.DBus.Introspectable", "Introspect" ) ) {
const char *path = msg.path();
if( !path )
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
int pathlen = strlen( path );
std::string introspect = generateInrospectHeader();
if( strncmp( path, DBusManagerPath, pathlen ) == 0 ) {
if( pathlen != 1 ) ++pathlen;
const char *end = strchr( DBusManagerPath + pathlen, '/' );
if( end ) {
const int sublen = end - DBusManagerPath - pathlen;
introspect += "<node name=\"" +
std::string( DBusManagerPath + pathlen, sublen )
+ "\"/>";
} else
introspect += "<node name=\"Manager\"/><node name=\"drives\"/>";
}
introspect += "</node>";
Message reply = msg.newMethodReturn();
reply.append( introspect );
connection()->send( reply );
return DBUS_HANDLER_RESULT_HANDLED;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
-35
View File
@@ -1,35 +0,0 @@
/* qlscribe - Qt based application to print lightScribe discs
Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$ */
#ifndef INTROSPECTHANDLER_H
#define INTROSPECTHANDLER_H
#include "dbuscpp.h"
namespace DBusCpp {
class IntrospectHandler : public MessageHandler {
public:
virtual DBusHandlerResult processMessage( const Message &msg );
};
}
#endif // INTROSPECTHANDLER_H
-21
View File
@@ -1,21 +0,0 @@
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- ../system.conf have denied everything, so we just punch some holes -->
<!-- Only root can own the service -->
<policy user="root">
<allow own="@QLSCRIBE_DBUS_MANAGER_SERVICE@"/>
<allow send_interface="@QLSCRIBE_DBUS_MANAGER_SERVICE@"/>
<allow send_interface="@QLSCRIBE_DBUS_DRIVES_SERVICE@"/>
</policy>
<!-- Allow anyone to invoke methods on the interfaces -->
<policy context="default">
<allow send_interface="@QLSCRIBE_DBUS_MANAGER_SERVICE@"/>
<allow send_interface="@QLSCRIBE_DBUS_DRIVES_SERVICE@"/>
<allow receive_interface="@QLSCRIBE_DBUS_DRIVES_SERVICE@"/>
</policy>
</busconfig>
-34
View File
@@ -1,34 +0,0 @@
/* qlscribe - Qt based application to print lightScribe discs
Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$ */
#ifndef LSCRIBED_H
#define LSCRIBED_H
#include <map>
#include <string>
const char * const DBusServiceName = "@QLSCRIBE_DBUS_MANAGER_SERVICE@";
const char * const DBusPath = "@QLSCRIBE_DBUS_PATH@";
const char * const DBusManagerPath = "@QLSCRIBE_DBUS_MANAGER_PATH@";
const char * const DBusDrivesPath = "@QLSCRIBE_DBUS_DRIVES_PATH@";
extern unsigned int lastActivity;
#endif // LSCRIBED_H
-20
View File
@@ -1,20 +0,0 @@
# -------------------------------------------------
# Project created by QtCreator 2009-02-22T16:31:18
# -------------------------------------------------
QT -= core \
gui
TARGET = lscribed
TEMPLATE = lib
INCLUDEPATH += /usr/include/dbus-1.0/
CONFIG += staticlib
SOURCES += main.cpp \
dbuscpp.cpp \
managerhandler.cpp \
drivehandler.cpp \
introspecthandler.cpp \
drives.cpp
HEADERS += dbuscpp.h \
drivehandler.h \
managerhandler.h \
introspecthandler.h \
drives.h
-129
View File
@@ -1,129 +0,0 @@
/* qlscribe - Qt based application to print lightScribe discs
Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$ */
#include <iostream>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include "lscribed.h"
#include "dbuscpp.h"
#include "introspecthandler.h"
#include "managerhandler.h"
#include "drivehandler.h"
#include "drives.h"
unsigned int lastActivity = 0;
unsigned int activityTimeout = 300; // 5 min by default
bool terminateOnTimeout = false;
int alarmInterval = 1;
bool debug = false;
void onAlarm( int )
{
alarm( alarmInterval );
unsigned int curr = time( 0 );
if( lastActivity == 0 ) {
lastActivity = curr;
return;
}
if( curr - lastActivity < activityTimeout )
return;
if( DrivesManager::instance().active() ) {
lastActivity = curr;
return;
}
terminateOnTimeout = true;
}
void usage()
{
std::cerr << "usage: lscribed [--help] [--timeout t] [--debug]" << std::endl;
std::cerr << "\t--help print this message" << std::endl;
std::cerr << "\t--timeout interval (seconds) to terminate after inactivity 0 - disable, default 300" << std::endl;
std::cerr << "\t--debug to enable virtual drive and print debug statements" << std::endl;
}
int main( int argc, char **argv )
{
for( int i = 1; i < argc; ++i ) {
if( strcmp( argv[i], "--help" ) == 0 ) {
usage();
return 1;
}
if( strcmp( argv[i], "--timeout" ) == 0 ) {
if( i == argc - 1 ) {
std::cerr << "Error: agrument for --timeout expected" << std::endl;
usage();
return 2;
}
activityTimeout = atoi( argv[ ++ i ] );
continue;
}
if( strcmp( argv[i], "--debug" ) == 0 ) {
debug = true;
continue;
}
std::cerr << "Error: unknown parameter " << argv[ i ] << std::endl;
usage();
return 3;
}
dbus_threads_init_default();
DBusError err;
dbus_error_init( &err );
DBusCpp::Connection conn ( dbus_bus_get_private( DBUS_BUS_SYSTEM, &err ) );
if( dbus_error_is_set( &err ) ) {
std::cerr << "dbus_bus_get() error: " << err.message << std::endl;
dbus_error_free( &err );
return 1;
}
int ret = dbus_bus_request_name( conn.ptr(), DBusServiceName, DBUS_NAME_FLAG_REPLACE_EXISTING, &err );
if( dbus_error_is_set( &err ) ) {
std::cerr << "dbus_bus_request_name error: " << err.message << std::endl;
dbus_error_free( &err );
return 2;
}
if( ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER ) {
std::cerr << "could not get ownership of \"" << DBusServiceName << "\" terminating" << std::endl;
return 3;
}
conn.registerHandler( "/", new DBusCpp::IntrospectHandler, true );
conn.registerHandler( DBusManagerPath, new DBusCpp::ManagerHandler, false );
conn.registerHandler( DBusDrivesPath, new DBusCpp::DriveHandler, true );
DrivesManager::instance().init( conn, debug );
if( activityTimeout ) {
signal( SIGALRM, onAlarm );
alarm( alarmInterval );
}
while( dbus_connection_read_write_dispatch( conn.ptr(), 10 ) ) {
if( terminateOnTimeout )
dbus_connection_close( conn.ptr() );
}
return 0;
}
-73
View File
@@ -1,73 +0,0 @@
/* qlscribe - Qt based application to print lightScribe discs
Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$ */
#include "lscribed.h"
#include "managerhandler.h"
#include "drives.h"
using namespace DBusCpp;
#include <stdio.h>
static const char *strManagerIntrospect =
"<interface name=\"org.lightscribe.printManager\">\
<method name=\"getDrives\">\
<arg type=\"a{ss}\" direction=\"out\"/>\
</method>\
</interface>";
DBusHandlerResult ManagerHandler::processMessage( const Message &msg )
{
if( msg.isMethodCall( "org.freedesktop.DBus.Introspectable", "Introspect" ) ) {
Message reply = msg.newMethodReturn();
std::string introspect = generateInrospectHeader();
introspect += strManagerIntrospect;
introspect += "</node>";
reply.append( introspect );
connection()->send( reply );
return DBUS_HANDLER_RESULT_HANDLED;
}
if( msg.isMethodCall( "org.lightscribe.printManager", "getDrives" ) ) {
Message reply = msg.newMethodReturn();
MessageIter args = reply.appendIter();
{
MessageIter sub = args.openContainer( DBUS_TYPE_ARRAY, "{ss}" );
DrivesManager &manager = DrivesManager::instance();
for( DrivesManager::const_iterator it = manager.begin(); it != manager.end(); ++it ) {
MessageIter itemIterator = sub.openContainer( DBUS_TYPE_DICT_ENTRY, 0 );
itemIterator.append( std::string( DBusDrivesPath ) + "/" + (*it)->path() );
itemIterator.append( (*it)->name() );
}
}
connection()->send( reply );
return DBUS_HANDLER_RESULT_HANDLED;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
-4
View File
@@ -1,4 +0,0 @@
[D-BUS Service]
Name=@QLSCRIBE_DBUS_MANAGER_SERVICE@
Exec=@CMAKE_INSTALL_PREFIX@/sbin/lscribed
User=root
+3 -28
View File
@@ -18,9 +18,6 @@
#
# $Id$
FIND_PACKAGE( Qt4 REQUIRED )
SET( QT_USE_QTDBUS 1 )
SET( QLSCRIBE_SRCS main.cpp mainwindow.cpp qcdscene.cpp qcdview.cpp
qdialogpixmap.cpp qdialogroundtext.cpp qdialogtext.cpp qlightroundtextitem.cpp
qlightscribe.cpp qshapefactory.cpp qlighttextitem.cpp qlightpixmapitem.cpp
@@ -35,39 +32,17 @@ SET( QLSCRIBE_MOC_HDRS mainwindow.h qcdscene.h qdialogpixmap.h qdialogroundtext.
ADD_DEFINITIONS( -Wall )
CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/qlscribe.h.in ${CMAKE_CURRENT_BINARY_DIR}/qlscribe.h @ONLY )
INCLUDE( ${QT_USE_FILE} )
QT4_WRAP_UI( QLSCRIBE_UI_HDRS ${QLSCRIBE_UIS} )
QT4_WRAP_CPP( QLSCRIBE_MOC_SRCS ${QLSCRIBE_MOC_HDRS} )
MACRO(ADD_DBUS_INTERFACE _sources _interface _basename)
GET_FILENAME_COMPONENT(_infile ${_interface} ABSOLUTE)
SET(_header ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.h)
SET(_impl ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp)
SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc)
INCLUDE_DIRECTORIES( ${CMAKE_BINARY_DIR}/src ${CMAKE_SOURCE_DIR}/src )
ADD_CUSTOM_COMMAND(OUTPUT ${_impl} ${_header}
COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} -m -i qlightscribe.h -p ${_basename} ${_infile}
DEPENDS ${_infile})
ADD_EXECUTABLE( qlscribe ${QLSCRIBE_SRCS} ${QLSCRIBE_MOC_SRCS} ${QLSCRIBE_UI_HDRS} )
SET_SOURCE_FILES_PROPERTIES(${_impl} PROPERTIES SKIP_AUTOMOC TRUE)
QT4_GENERATE_MOC(${_header} ${_moc})
SET(${_sources} ${${_sources}} ${_impl} ${_header} ${_moc})
MACRO_ADD_FILE_DEPENDENCIES(${_impl} ${_moc})
ENDMACRO(ADD_DBUS_INTERFACE)
ADD_DBUS_INTERFACE( QLSCRIBE_DBUS_SRCS lightscribe.xml lightscribe_interface )
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} )
ADD_EXECUTABLE( qlscribe ${QLSCRIBE_SRCS} ${QLSCRIBE_MOC_SRCS} ${QLSCRIBE_UI_HDRS} ${QLSCRIBE_DBUS_SRCS} )
TARGET_LINK_LIBRARIES( qlscribe ${QT_LIBRARIES} )
TARGET_LINK_LIBRARIES( qlscribe ${QT_LIBRARIES} ${LSCRIBE_LIBRARIES} )
INSTALL( TARGETS qlscribe
DESTINATION bin
-65
View File
@@ -1,65 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- qlscribe - Qt based application to print lightScribe discs
Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$
-->
<node>
<interface name="org.lightscribe.printManager">
<method name="getDrives">
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QObject2StringMap"/>
<arg type="a{ss}" direction="out"/>
</method>
</interface>
<interface name="org.lightscribe.drive">
<signal name="prepareProgress">
<arg name="current" type="i" direction="out"/>
<arg name="final" type="i" direction="out"/>
</signal>
<signal name="labelProgress">
<arg name="current" type="i" direction="out"/>
<arg name="final" type="i" direction="out"/>
</signal>
<signal name="timeEstimate">
<arg name="time" type="i" direction="out"/>
</signal>
<signal name="finished">
<arg name="status" type="i" direction="out"/>
</signal>
<method name="preview">
<annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="const PrintParameters &amp;"/>
<annotation name="com.trolltech.QtDBus.QtTypeName.In2" value="QSize"/>
<arg type="s" direction="out"/>
<arg name="params" type="(iiii)" direction="in"/>
<arg name="image" type="ay" direction="in"/>
<arg name="previewSize" type="(ii)" direction="in"/>
</method>
<method name="print">
<annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="const PrintParameters &amp;"/>
<arg name="params" type="(iiii)" direction="in"/>
<arg name="image" type="ay" direction="in"/>
</method>
<method name="abort">
</method>
<method name="name">
<arg type="s" direction="out"/>
</method>
</interface>
</node>
+33 -6
View File
@@ -28,6 +28,8 @@
#include <iostream>
uid_t realUserId;
std::ostream &operator<<( std::ostream &os, const QString &str )
{
return os << str.toAscii().data();
@@ -56,7 +58,7 @@ int main( int argc, char **argv )
QStringList files;
QCDScene::QString2String replacements;
int driveIndex = 0;
PrintParameters params;
QLightScribe::PrintParameters params;
bool labelModeOverriden = false;
for( int i = 1; i < arguments.size(); ++i ) {
@@ -106,6 +108,29 @@ int main( int argc, char **argv )
return 3;
}
bool enablePrint = false;
if( geteuid() ) {
if( !doPrint ) {
if( QMessageBox::question( 0,
QObject::tr( "Confirmation" ),
QObject::tr( "Print functionality requires setuid (sticky) flag set on the application\n"
"This program does not seem to have it set, print functionality will be disabled\n"
"You still will be able to do print preview and edit documents\n"
"Do you want to continue?" ),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No )
== QMessageBox::No )
return 4;
} else {
std::cerr << "Error: setuid flag is not set, cannot print" << std::endl;
return 4;
}
} else {
realUserId = getuid();
setreuid( 0, realUserId );
enablePrint = true;
}
int rez = 0;
if( doPrint ) {
@@ -126,17 +151,19 @@ int main( int argc, char **argv )
std::cerr << "Error: drive " << driveIndex << " specified, but there are only " << drives.size() << " drives" << std::endl;
return 6;
}
QConsolePrintProgress progress;
std::cout << "Printing label " << files.front() << std::endl;
QLightDrive *drive = drives[driveIndex];
QConsolePrintProgress progress( drive );
drive->print( params, &scene );
scribe->print( drives[driveIndex], params, &scene );
rez = app.exec();
} else {
MainWindow mwindow( true );
MainWindow mwindow( enablePrint );
mwindow.show();
mwindow.open( files );
rez = app.exec();
}
QLightScribe *scribe = QLightScribe::instance();
scribe->stopThread();
scribe->wait( 1000 );
return rez;
}
+6 -11
View File
@@ -313,14 +313,14 @@ void MainWindow::onMenuPrintPreview()
if( !cdscene )
return;
PrintParameters params;
QLightScribe::PrintParameters params;
params.m_labelMode = cdscene->labelMode();
QLightDrive *drive = QDialogPrint::exec( this, params );
if( !drive )
return;
try {
QPixmap pixmap = drive->preview( params, cdscene, QSize( 400, 400 ) );
QPixmap pixmap = QLightScribe::instance()->preview( drive, params, cdscene, QSize( 400, 400 ) );
QLabel *label = new QLabel;
label->setPixmap( pixmap );
@@ -329,7 +329,7 @@ void MainWindow::onMenuPrintPreview()
subWindow->show();
}
catch( const QString &err ) {
QMessageBox::critical( this, tr( "Error on print preview" ), err );
QMessageBox::critical( this, tr( "Error" ), err );
}
}
@@ -337,14 +337,9 @@ void MainWindow::onMenuPrint()
{
QCDScene *cdscene = getScene( m_mdiArea );
if( !cdscene )
return;
try {
QDialogProgress::exec( this, cdscene );
}
catch( const QString &err ) {
QMessageBox::critical( this, tr( "Error on print" ), err );
}
QDialogProgress::exec( this, cdscene );
}
void MainWindow::onMenuAbout()
@@ -352,7 +347,7 @@ void MainWindow::onMenuAbout()
QMessageBox::about( this,
tr( "About" ),
tr( "<h3>qlscribe - Qt lisghtScribe</h3>"
"<p>release 0.8 $Revision$</p>"
"<p>release 0.7 $Revision$</p>"
"<p>visit project at home page "
"<a href=\"http://qlscribe.sourceforge.net/\">qlscribe.sourceforge.net</a></p>" ) );
}
+10 -11
View File
@@ -5,15 +5,14 @@
#include <iostream>
std::ostream &operator<<( std::ostream &os, const QString &str );
QConsolePrintProgress::QConsolePrintProgress( QLightDrive *drive )
: m_drive( drive )
QConsolePrintProgress::QConsolePrintProgress()
{
connect( drive, SIGNAL(prepareProgress(int,int)), this, SLOT(onPrepareProgress(int,int)) );
connect( drive, SIGNAL(labelProgress(int,int)), this, SLOT(onLabelProgress(int,int)) );
connect( drive, SIGNAL(timeEstimate(int)), this, SLOT(onTimeEstimate(int)) );
connect( drive, SIGNAL(finished(int)), this, SLOT(onFinished(int)) );
QLightScribe *scribe = QLightScribe::instance();
connect( scribe, SIGNAL(prepareProgress(long,long)), this, SLOT(onPrepareProgress(long,long)) );
connect( scribe, SIGNAL(labelProgress(long,long)), this, SLOT(onLabelProgress(long,long)) );
connect( scribe, SIGNAL(timeEstimate(long)), this, SLOT(onTimeEstimate(long)) );
connect( scribe, SIGNAL(finished(int)), this, SLOT(onFinished(int)) );
}
@@ -21,17 +20,17 @@ QConsolePrintProgress::~QConsolePrintProgress()
{
}
void QConsolePrintProgress::onPrepareProgress( int current, int final )
void QConsolePrintProgress::onPrepareProgress( long current, long final )
{
std::cout << "Preparing label: " << current << '/' << final << " \r";
}
void QConsolePrintProgress::onLabelProgress( int current, int final )
void QConsolePrintProgress::onLabelProgress( long current, long final )
{
std::cout << "Printing label: " << current << '/' << final << " \r";
}
void QConsolePrintProgress::onTimeEstimate( int time )
void QConsolePrintProgress::onTimeEstimate( long time )
{
std::cout << std::endl;
}
+4 -9
View File
@@ -3,22 +3,17 @@
#include <QObject>
class QLightDrive;
class QConsolePrintProgress : public QObject {
Q_OBJECT
public:
QConsolePrintProgress( QLightDrive *drive );
QConsolePrintProgress();
~QConsolePrintProgress();
private slots:
void onPrepareProgress( int current, int final );
void onLabelProgress( int current, int final );
void onTimeEstimate( int time );
void onPrepareProgress( long current, long final );
void onLabelProgress( long current, long final );
void onTimeEstimate( long time );
void onFinished(int status );
private:
QLightDrive *m_drive;
};
#endif // QCONSOLEPRINTPROGRESS_H
+5 -5
View File
@@ -46,7 +46,7 @@ void QDialogPrint::changeEvent(QEvent *e)
}
}
QLightDrive *QDialogPrint::exec( QWidget *parent, PrintParameters &params )
QLightDrive *QDialogPrint::exec( QWidget *parent, QLightScribe::PrintParameters &params )
{
QList<QLightDrive *> drives = QLightScribe::instance()->getDrives();
if( drives.isEmpty() ) {
@@ -67,7 +67,7 @@ QLightDrive *QDialogPrint::exec( QWidget *parent, PrintParameters &params )
if( dialog.QDialog::exec() == Rejected )
return 0;
params = PrintParameters(); // reset to default
params = QLightScribe::PrintParameters(); // reset to default
if( dialog.m_ui->radioModeFull->isChecked() )
params.m_labelMode = modeFull;
@@ -79,13 +79,13 @@ QLightDrive *QDialogPrint::exec( QWidget *parent, PrintParameters &params )
params.m_labelMode = modeContent;
if( dialog.m_ui->radioQualityNormal->isChecked() )
params.m_printQuality = qualityNormal;
params.m_printQuality = QLightScribe::qualityNormal;
if( dialog.m_ui->radioQualityDraft->isChecked() )
params.m_printQuality = qualityDraft;
params.m_printQuality = QLightScribe::qualityDraft;
if( dialog.m_ui->radioMediaGeneric->isChecked() )
params.m_mediaOptimizationLevel = mediaGeneric;
params.m_mediaOptimizationLevel = QLightScribe::mediaGeneric;
return drives.at( dialog.m_ui->comboDrive->currentIndex() );
}
+1 -1
View File
@@ -33,7 +33,7 @@ class QDialogPrint : public QDialog {
Q_OBJECT
Q_DISABLE_COPY(QDialogPrint)
public:
static QLightDrive *exec( QWidget *parent, PrintParameters &params );
static QLightDrive *exec( QWidget *parent, QLightScribe::PrintParameters &params );
protected:
explicit QDialogPrint(QWidget *parent = 0);
+15 -15
View File
@@ -29,10 +29,9 @@
#include <QTime>
#include <QTimer>
QDialogProgress::QDialogProgress( QWidget *parent, QLightDrive *drive )
: QDialog(parent),
QDialogProgress::QDialogProgress(QWidget *parent) :
QDialog(parent),
m_ui(new Ui::QDialogProgress),
m_drive( drive ),
m_start( new QTime ),
m_timer( new QTimer( this ) )
{
@@ -62,22 +61,23 @@ void QDialogProgress::changeEvent(QEvent *e)
bool QDialogProgress::exec( QWidget *parent, QCDScene *scene )
{
PrintParameters params;
QLightScribe::PrintParameters params;
params.m_labelMode = scene->labelMode();
QLightDrive *drive = QDialogPrint::exec( parent, params );
if( !drive )
return false;
QDialogProgress dialog( parent, drive );
QLightScribe *scribe = QLightScribe::instance();
QDialogProgress dialog( parent );
dialog.setWindowTitle( tr( "Printing: " ) + scene->name() );
connect( dialog.m_ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), &dialog, SLOT(onButtonClicked(QAbstractButton*)) );
connect( drive, SIGNAL(prepareProgress(int,int)), &dialog, SLOT(onPrepareProgress(int,int)) );
connect( drive, SIGNAL(labelProgress(int,int)), &dialog, SLOT(onLabelProgress(int,int)) );
connect( drive, SIGNAL(timeEstimate(int)), &dialog, SLOT(onTimeEstimate(int)) );
connect( drive, SIGNAL(finished(int)), &dialog, SLOT(onFinished(int)) );
connect( scribe, SIGNAL(prepareProgress(long,long)), &dialog, SLOT(onPrepareProgress(long,long)) );
connect( scribe, SIGNAL(labelProgress(long,long)), &dialog, SLOT(onLabelProgress(long,long)) );
connect( scribe, SIGNAL(timeEstimate(long)), &dialog, SLOT(onTimeEstimate(long)) );
connect( scribe, SIGNAL(finished(int)), &dialog, SLOT(onFinished(int)) );
drive->print( params, scene );
scribe->print( drive, params, scene );
dialog.QDialog::exec();
return true;
}
@@ -90,32 +90,32 @@ void QDialogProgress::onButtonClicked( QAbstractButton *button )
tr( "Are you sure you want to interrupt?" ),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No ) == QMessageBox::Yes ) {
m_drive->abort();
QLightScribe::instance()->abort();
button->setDisabled( true );
}
} else
done( 0 );
}
void QDialogProgress::onPrepareProgress( int current, int final )
void QDialogProgress::onPrepareProgress( long current, long final )
{
m_ui->progressPreparation->setMaximum( final );
m_ui->progressPreparation->setValue( current );
}
void QDialogProgress::onLabelProgress( int current, int final )
void QDialogProgress::onLabelProgress( long current, long final )
{
m_ui->progressPrinting->setMaximum( final );
m_ui->progressPrinting->setValue( current );
if( current && final / double( current ) < 10.0 ) {
int elapsed = m_start->elapsed();
int estimate = int( double( elapsed ) / current * final );
int estimate = double( elapsed ) / current * final;
m_ui->timeEstimated->setTime( QTime().addMSecs( estimate ) );
}
}
void QDialogProgress::onTimeEstimate( int time )
void QDialogProgress::onTimeEstimate( long time )
{
m_ui->timeEstimated->setTime( QTime().addSecs( time ) );
}
+4 -6
View File
@@ -31,7 +31,6 @@ class QCDScene;
class QAbstractButton;
class QTime;
class QTimer;
class QLightDrive;
class QDialogProgress : public QDialog {
Q_OBJECT
@@ -41,9 +40,9 @@ public:
protected slots:
void onButtonClicked( QAbstractButton* button );
void onPrepareProgress( int current, int final );
void onLabelProgress( int current, int final );
void onTimeEstimate( int time );
void onPrepareProgress( long current, long final );
void onLabelProgress( long current, long final );
void onTimeEstimate( long time );
void onFinished(int status );
void onTimeout();
@@ -51,11 +50,10 @@ protected:
virtual void changeEvent(QEvent *e);
private:
QDialogProgress(QWidget *parent, QLightDrive *drive );
explicit QDialogProgress(QWidget *parent = 0);
virtual ~QDialogProgress();
Ui::QDialogProgress *m_ui;
QLightDrive *m_drive;
QTime *m_start;
QTimer *m_timer;
};
+334 -100
View File
@@ -20,41 +20,33 @@
#include "qlightscribe.h"
#include "qcdscene.h"
#include "lightscribe_interface.h"
#include <QApplication>
#include <QMutex>
#include <QWaitCondition>
#include <QPainter>
#include <QBuffer>
#include <QTemporaryFile>
#include <QDBusConnection>
#include <QDBusArgument>
#include <QMessageBox>
//#include <lightscribe_cxx.h>
#include <lightscribe_cxx.h>
//using namespace LightScribe;
// Marshall the PrintParameters data into a D-BUS argument
QDBusArgument &operator<<( QDBusArgument &argument, const PrintParameters &p )
{
argument.beginStructure();
argument << p.m_labelMode << p.m_drawOptions << p.m_printQuality << p.m_mediaOptimizationLevel;
argument.endStructure();
return argument;
}
using namespace LightScribe;
// Retrieve the PrintProperties data from the D-BUS argument
const QDBusArgument &operator>>( const QDBusArgument &argument, PrintParameters &p )
{
argument.beginStructure();
int drawOptions = 0, labelMode = 0, mediaOptimizationLevel = 0, printQuality = 0;
argument >> labelMode >> drawOptions >> printQuality >> mediaOptimizationLevel;
argument.endStructure();
p = PrintParameters( LabelMode( labelMode ),
DrawOptions( drawOptions ),
PrintQuality( printQuality ),
MediaOptimizationLevel( mediaOptimizationLevel ) );
return argument;
}
struct QLightScribe::Task {
enum Action { getDrives, preview, print, stop };
Action m_action;
bool m_done;
QLightDrive *m_selectedDrive;
PrintParameters m_parameters;
QSize m_size;
QImage *m_image;
QList< QLightDrive * > m_drives;
QTemporaryFile m_tmpFile;
QString m_error;
Task( Action action ) : m_action( action ), m_done( false ), m_selectedDrive( 0 ), m_image( 0 ) {}
~Task() { delete m_image; }
};
QLightScribe *QLightScribe::instance()
{
@@ -63,108 +55,350 @@ QLightScribe *QLightScribe::instance()
}
QLightScribe::QLightScribe()
: m_managerPrx( new OrgLightscribePrintManagerInterface( DBusServiceName,
DBusManagerPath,
QDBusConnection::systemBus(),
this ) )
: m_task( 0 ),
m_aborted( false ),
m_mutex( new QMutex ),
m_waitQueue( new QWaitCondition ),
m_waitDone( new QWaitCondition )
{
qDBusRegisterMetaType<PrintParameters>();
qDBusRegisterMetaType<QObject2StringMap>();
start();
}
QLightScribe::~QLightScribe()
{
delete m_waitDone;
delete m_waitQueue;
delete m_mutex;
}
QList< QLightDrive * > QLightScribe::getDrives()
QList< QLightDrive * > QLightScribe::getDrives( bool refresh )
{
if( m_drives.empty() ) {
qApp->setOverrideCursor( Qt::WaitCursor );
QDBusReply<QObject2StringMap> reply = m_managerPrx->getDrives();
qApp->restoreOverrideCursor();
if( !reply.isValid() ) {
QMessageBox::critical( 0, tr( "DBus Error" ), tr( "Error on request: " ) + reply.error().message() );
} else {
const QObject2StringMap &map = reply.value();
for( QObject2StringMap::const_iterator i = map.begin(); i != map.end(); ++i )
m_drives.push_back( new QLightDrive( this, i.key(), i.value() ) );
if( m_drives.empty() || refresh ) {
QMutexLocker lock( m_mutex );
if( m_task ) // what should we do?
return m_drives;
m_task = new Task( Task::getDrives );
m_waitQueue->wakeOne();
while( !m_task->m_done )
m_waitDone->wait( m_mutex );
while( m_drives.count() ) {
delete m_drives.front();
m_drives.erase( m_drives.begin() );
}
m_drives = m_task->m_drives;
delete m_task;
m_task = 0;
}
return m_drives;
}
QLightDrive::QLightDrive( QObject *parent, const QString &path, const QString &name )
: QObject( parent ),
m_drivePrx( new OrgLightscribeDriveInterface( DBusServiceName, path, QDBusConnection::systemBus(), this ) ),
m_displayName( name ),
m_path( path )
{
connect( m_drivePrx, SIGNAL(finished(int)), this, SIGNAL(finished(int)) );
connect( m_drivePrx, SIGNAL(prepareProgress( int, int )), this, SIGNAL(prepareProgress( int, int )) );
connect( m_drivePrx, SIGNAL(labelProgress( int , int )), this, SIGNAL(labelProgress( int, int )) );
connect( m_drivePrx, SIGNAL(timeEstimate( int )), this, SIGNAL(timeEstimate( int )) );
}
static
void printScene( QCDScene *scene, QByteArray &array )
QImage *printScene( QCDScene *scene )
{
QImage image( 2772, 2772, QImage::Format_RGB888 );
image.fill( 0xFFFFFFFF );
QImage *image = new QImage( 2772, 2772, QImage::Format_RGB888 );
image->fill( 0xFFFFFFFF );
scene->clearSelection();
{
QPainter painter( &image );
scene->render( &painter, image.rect() );
QPainter painter( image );
scene->render( &painter, image->rect() );
}
image.setDotsPerMeterX( 23622 );
image.setDotsPerMeterY( 23622 );
image->setDotsPerMeterX( 23622 );
image->setDotsPerMeterY( 23622 );
array.clear();
QBuffer buffer( &array );
buffer.open( QIODevice::WriteOnly );
image.save( &buffer, "bmp", 100 );
return image;
}
QPixmap QLightDrive::preview( const PrintParameters &params, QCDScene *scene, const QSize &size ) throw( QString )
QPixmap QLightScribe::preview( QLightDrive *drive, const PrintParameters &params, QCDScene *scene, const QSize &size ) throw( QString )
{
qApp->setOverrideCursor( Qt::WaitCursor );
QByteArray array;
printScene( scene, array );
QMutexLocker lock( m_mutex );
if( m_task ) // what should we do?
return QPixmap();
/*QList<QVariant> argumentList;
argumentList << qVariantFromValue( params ) << qVariantFromValue( array )
<< qVariantFromValue( size );
QDBusReply<QString> reply = m_drivePrx->callWithArgumentList( QDBus::BlockWithGui,
QLatin1String( "preview" ),
argumentList);*/
QDBusReply<QString> reply = m_drivePrx->preview( params, array, size );
qApp->restoreOverrideCursor();
if( !reply.isValid() )
throw QString( "DBus error: (%1) %2" ).arg( reply.error().name(), reply.error().message() );
m_task = new Task( Task::preview );
m_task->m_selectedDrive = drive;
m_task->m_parameters = params;
m_task->m_size = size;
m_task->m_image = printScene( scene );
m_aborted = false;
m_waitQueue->wakeOne();
while( !m_task->m_done )
m_waitDone->wait( m_mutex );
QString err = m_task->m_error;
QPixmap pixmap;
if( err.isEmpty() )
pixmap.load( m_task->m_tmpFile.fileName(), "bmp" );
delete m_task;
m_task = 0;
if( !err.isEmpty() )
throw err;
QString fname = reply.value();
QPixmap pixmap( fname );
QFile( fname ).remove();
return pixmap;
}
void QLightDrive::print( const PrintParameters &params, QCDScene *scene ) throw( QString )
void QLightScribe::print( QLightDrive *drive, const PrintParameters &params, QCDScene *scene )
{
qApp->setOverrideCursor( Qt::WaitCursor );
QByteArray array;
printScene( scene, array );
/*QList<QVariant> argumentList;
argumentList << qVariantFromValue( params ) << qVariantFromValue( array );
QDBusReply<void> reply = callWithArgumentList( QDBus::BlockWithGui,
QLatin1String( "print" ),
argumentList);*/
QDBusReply<void> reply = m_drivePrx->print( params, array );
qApp->restoreOverrideCursor();
if( !reply.isValid() )
throw QString( "DBus error: (%1) %2" ).arg( reply.error().name(), reply.error().message() );
QMutexLocker lock( m_mutex );
if( m_task ) // what should we do?
return;
m_task = new Task( Task::print );
m_task->m_selectedDrive = drive;
m_task->m_parameters = params;
m_task->m_image = printScene( scene );
m_aborted = false;
m_waitQueue->wakeOne();
}
void QLightDrive::abort()
void QLightScribe::abort()
{
m_drivePrx->abort();
m_aborted = true;
}
void QLightScribe::stopThread()
{
QMutexLocker lock( m_mutex );
delete m_task;
m_task = new Task( Task::stop );
m_waitQueue->wakeOne();
}
bool QLightScribe::clAbortLabel()
{
return QLightScribe::instance()->m_aborted;
}
void QLightScribe::clReportPrepareProgress(long current, long final)
{
emit instance()->prepareProgress( current, final );
}
void QLightScribe::clReportLabelProgress(long current, long final)
{
emit instance()->labelProgress( current, final );
}
void QLightScribe::clReportFinished(LSError status)
{
emit instance()->finished( status );
}
bool QLightScribe::clReportLabelTimeEstimate(long time)
{
emit instance()->timeEstimate( time );
return false;
}
namespace {
class AutoUidSetter {
public:
AutoUidSetter() : m_saved( 0 ) {}
AutoUidSetter( uid_t userId ) : m_saved( 0 ) { set( userId ); }
~AutoUidSetter() { unset(); }
void set( uid_t userId )
{
if( userId ) {
setreuid( userId, 0 );
m_saved = userId;
}
}
void unset()
{
if( m_saved ) {
setreuid( 0, m_saved );
m_saved = 0;
}
}
private:
uid_t m_saved;
};
typedef void (LightScribe::DiscPrinter::*DiscPrinterOp)();
template<DiscPrinterOp dlock, DiscPrinterOp dunlock >
class AutoOp {
public:
AutoOp( LightScribe::DiscPrinter &printer ) : m_printer( &printer ), m_locked( false ) {}
AutoOp() { unlock(); }
void lock()
{
if( !m_locked ) {
(m_printer->*dlock)();
m_locked = true;
}
}
void unlock()
{
if( m_locked ) {
try {
(m_printer->*dunlock)();
}
catch(...){}
m_locked = false;
}
}
private:
LightScribe::DiscPrinter *m_printer;
bool m_locked;
};
}
extern uid_t realUserId;
void QLightScribe::run()
{
QMutexLocker lock( m_mutex );
while( true ) {
while( m_task == 0 || m_task->m_done )
m_waitQueue->wait( m_mutex );
if( m_task->m_action == Task::stop )
break;
QString function;
try {
function = "LS_DiscPrintMgr_Create";
DiscPrintMgr manager;
function = "LS_DiscPrintMgr_EnumDiscPrinters";
EnumDiscPrinters printers = manager.EnumDiscPrinters();
function = "";
if( m_task->m_action == Task::getDrives ) {
const unsigned count = printers.Count();
for( unsigned i = 0; i < count; ++i ) {
DiscPrinter printer = printers.Item( i );
QLightDrive *drive = new QLightDrive;
drive->m_displayName = QString::fromStdString( printer.GetPrinterDisplayName() );
drive->m_productName = QString::fromStdString( printer.GetPrinterProductName() );
drive->m_vendorName = QString::fromStdString( printer.GetPrinterVendorName() );
drive->m_path = QString::fromStdString( printer.GetPrinterPath() );
drive->m_innerRadius = printer.GetDriveInnerRadius() / 1000.0;
drive->m_outerRadius = printer.GetDriveOuterRadius() / 1000.0;
m_task->m_drives.append( drive );
}
} else {
QByteArray ba;
QBuffer buffer( &ba );
buffer.open( QIODevice::WriteOnly );
m_task->m_image->save( &buffer, "bmp", 100 );
int found = -1;
for( size_t i = 0; i < printers.Count(); ++i )
if( printers.Item( i ).GetPrinterDisplayName() == m_task->m_selectedDrive->displayName().toStdString() ) {
found = i;
break;
}
if( found == -1 )
throw tr( "Cannot find drive: \"" ) + m_task->m_selectedDrive->displayName() + "\"";
DiscPrinter printer = printers.Item( found );
AutoUidSetter autoUid;
AutoOp< &DiscPrinter::AddExclusiveUse, &DiscPrinter::ReleaseExclusiveUse > autoExclusive( printer );
AutoOp< &DiscPrinter::LockDriveTray, &DiscPrinter::UnlockDriveTray > autoLock( printer );
if( m_task->m_action == Task::print ) {
autoUid.set( realUserId );
function = "LS_DiscPrinter_AddExclusiveUse";
autoExclusive.lock();
function = "LS_DiscPrinter_LockDriveTray";
autoLock.lock();
}
{
function = "LS_DiscPrinter_OpenPrintSession";
DiscPrintSession session = printer.OpenPrintSession();
LS_PrintCallbacks callbacks;
callbacks.AbortLabel = clAbortLabel;
callbacks.ReportPrepareProgress = clReportPrepareProgress;
callbacks.ReportLabelProgress = clReportLabelProgress;
callbacks.ReportFinished = clReportFinished;
callbacks.ReportLabelTimeEstimate = clReportLabelTimeEstimate;
session.SetProgressCallback( &callbacks );
const size_t bitmapHeaderSize = 54;
if( m_task->m_action == Task::preview ) {
LS_Size size;
size.x = m_task->m_size.width();
size.y = m_task->m_size.height();
m_task->m_tmpFile.open();
function = "LS_DiscPrintSession_PrintPreview";
session.PrintPreview( LS_windows_bitmap,
LS_LabelMode( m_task->m_parameters.m_labelMode ),
LS_DrawOptions( m_task->m_parameters.m_drawOptions ),
LS_PrintQuality( m_task->m_parameters.m_printQuality ),
LS_MediaOptimizationLevel( m_task->m_parameters.m_mediaOptimizationLevel ),
ba.data() + 14,
bitmapHeaderSize - 14,
ba.data() + bitmapHeaderSize,
ba.size() - bitmapHeaderSize,
m_task->m_tmpFile.fileName().toAscii().data(),
LS_windows_bitmap,
size,
true );
} else {
PrintParameters params = m_task->m_parameters;
delete m_task;
m_task = 0;
lock.unlock();
// print here
session.PrintDisc( LS_windows_bitmap,
LS_LabelMode( params.m_labelMode ),
LS_DrawOptions( params.m_drawOptions ),
LS_PrintQuality( params.m_printQuality ),
LS_MediaOptimizationLevel( params.m_mediaOptimizationLevel ),
ba.data() + 14,
bitmapHeaderSize - 14,
ba.data() + bitmapHeaderSize,
ba.size() - bitmapHeaderSize );
}
}
function = "";
}
}
catch( LightScribe::LSException &ex ) {
if( m_task )
m_task->m_error = function + tr( " failed with code 0x" ) + QString::number( ex.GetCode(), 16 );
}
catch( const QString &err ) {
if( m_task )
m_task->m_error = err;
}
if( m_task ) {
m_task->m_done = true;
m_waitDone->wakeAll();
}
}
}
+90 -53
View File
@@ -23,53 +23,106 @@
#include "qlscribe.h"
#include <QThread>
#include <QPixmap>
#include <QMap>
#include <QMetaType>
#include <map>
#include <lightscribe_errors.h>
class QCDScene;
class QMutex;
class QWaitCondition;
class QLightDrive;
struct PrintParameters {
LabelMode m_labelMode;
DrawOptions m_drawOptions;
PrintQuality m_printQuality;
MediaOptimizationLevel m_mediaOptimizationLevel;
PrintParameters()
: m_labelMode( modeFull ), m_drawOptions( drawDefault ),
m_printQuality( qualityBest ), m_mediaOptimizationLevel( mediaRecognized ) {}
PrintParameters( LabelMode labelMode, DrawOptions drawOptions, PrintQuality printQuality, MediaOptimizationLevel mediaOptimizationLevel )
: m_labelMode( labelMode ), m_drawOptions( drawOptions ),
m_printQuality( printQuality ), m_mediaOptimizationLevel( mediaOptimizationLevel ) {}
};
Q_DECLARE_METATYPE( PrintParameters );
typedef QMap<QString,QString> QObject2StringMap;
Q_DECLARE_METATYPE( QObject2StringMap );
class OrgLightscribePrintManagerInterface;
class QLightScribe : public QObject {
class QLightScribe : public QThread {
Q_OBJECT
public:
enum DrawOptions {
/** disable scaling of bitmaps; they will be cropped if needed */
drawDefault=0,
/** Fit the height to the label size */
drawFitHeightToLabel=1,
/** Fit the width to the label size */
drawFitWidthToLabel=2,
/** Fit the smallest dimension to the label size */
drawFitSmallestToLabel=4
};
enum PrintQuality {
/** Best and slowest. */
qualityBest=0,
/** OK for everyday use. */
qualityNormal=1,
/** Fast but lower contrast. */
qualityDraft=2
};
enum MediaOptimizationLevel {
/** Require that media is present and optimized labeling
* parameters are available */
mediaRecognized,
/** Require that media is present but optimized labeling
* parameters are not available */
mediaGeneric
};
struct PrintParameters {
LabelMode m_labelMode;
DrawOptions m_drawOptions;
PrintQuality m_printQuality;
MediaOptimizationLevel m_mediaOptimizationLevel;
PrintParameters()
: m_labelMode( modeFull ), m_drawOptions( drawDefault ),
m_printQuality( qualityBest ), m_mediaOptimizationLevel( mediaRecognized ) {}
PrintParameters( LabelMode labelMode, DrawOptions drawOptions, PrintQuality printQuality, MediaOptimizationLevel mediaOptimizationLevel )
: m_labelMode( labelMode ), m_drawOptions( drawOptions ),
m_printQuality( printQuality ), m_mediaOptimizationLevel( mediaOptimizationLevel ) {}
};
static QLightScribe *instance();
QList<QLightDrive *> getDrives();
QList< QLightDrive * > getDrives( bool refresh = false );
QPixmap preview( QLightDrive *drive, const PrintParameters &params, QCDScene *scene, const QSize &size ) throw( QString );
void print( QLightDrive *drive, const PrintParameters &params, QCDScene *scene );
friend bool clAbortLabel();
public slots:
void abort();
void stopThread();
signals:
void prepareProgress( long current, long final );
void labelProgress( long current, long final );
void timeEstimate( long time );
void finished( int status );
protected:
virtual void run ();
private:
static bool clAbortLabel();
static void clReportPrepareProgress(long current, long final);
static void clReportLabelProgress(long current, long final);
static void clReportFinished(LSError status);
static bool clReportLabelTimeEstimate(long time);
QLightScribe();
virtual ~QLightScribe();
OrgLightscribePrintManagerInterface *m_managerPrx;
QList< QLightDrive * > m_drives;
struct Task;
QList< QLightDrive * > m_drives;
Task *m_task;
bool m_aborted;
QMutex *m_mutex;
QWaitCondition *m_waitQueue;
QWaitCondition *m_waitDone;
};
class OrgLightscribeDriveInterface;
class QLightDrive : public QObject {
Q_OBJECT
class QLightDrive {
public:
const QString &productName() const { return m_productName; }
const QString &vendorName() const { return m_vendorName; }
@@ -79,32 +132,16 @@ public:
double innerRadius() const { return m_innerRadius; }
double outerRadius() const { return m_outerRadius; }
QPixmap preview( const PrintParameters &params, QCDScene *scene, const QSize &size ) throw( QString );
void print( const PrintParameters &params, QCDScene *scene ) throw( QString );
friend class QLightScribe;
public slots:
void abort();
signals:
void prepareProgress( int current, int final );
void labelProgress( int current, int final );
void timeEstimate( int time );
void finished( int status );
private:
QLightDrive( QObject *parent, const QString &path, const QString &name );
QString m_productName;
QString m_vendorName;
QString m_displayName;
QString m_path;
OrgLightscribeDriveInterface *m_drivePrx;
QString m_productName;
QString m_vendorName;
QString m_displayName;
QString m_path;
double m_innerRadius;
double m_outerRadius;
double m_innerRadius;
double m_outerRadius;
};
#endif // QLIGHTSCRIBE_H
+13 -10
View File
@@ -18,18 +18,21 @@
$Id$ */
#ifndef MANAGERHANDLER_H
#define MANAGERHANDLER_H
#ifndef QLSCRIBE_H
#define QLSCRIBE_H
#include "dbuscpp.h"
#include <iostream>
#include <QString>
namespace DBusCpp {
class ManagerHandler : public MessageHandler {
public:
virtual DBusHandlerResult processMessage( const Message &msg );
enum LabelMode {
/** label the entire disc */
modeFull=0,
/** label within the title mode constraints */
modeTitle=1,
/** label within the content mode constraints */
modeContent=2
};
}
std::ostream &operator<<( std::ostream &os, const QString &str );
#endif // INTROSPECTHANDLER_H
#endif // QLSCRIBE_H
-65
View File
@@ -1,65 +0,0 @@
/* qlscribe - Qt based application to print lightScribe discs
Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$ */
#ifndef QLSCRIBE_H
#define QLSCRIBE_H
enum LabelMode {
/** label the entire disc */
modeFull=0,
/** label within the title mode constraints */
modeTitle=1,
/** label within the content mode constraints */
modeContent=2
};
enum DrawOptions {
/** disable scaling of bitmaps; they will be cropped if needed */
drawDefault=0,
/** Fit the height to the label size */
drawFitHeightToLabel=1,
/** Fit the width to the label size */
drawFitWidthToLabel=2,
/** Fit the smallest dimension to the label size */
drawFitSmallestToLabel=4
};
enum PrintQuality {
/** Best and slowest. */
qualityBest=0,
/** OK for everyday use. */
qualityNormal=1,
/** Fast but lower contrast. */
qualityDraft=2
};
enum MediaOptimizationLevel {
/** Require that media is present and optimized labeling
* parameters are available */
mediaRecognized,
/** Require that media is present but optimized labeling
* parameters are not available */
mediaGeneric
};
const char * const DBusServiceName = "@QLSCRIBE_DBUS_MANAGER_SERVICE@";
const char * const DBusManagerPath = "@QLSCRIBE_DBUS_MANAGER_PATH@";
#endif // QLSCRIBE_H
+1
View File
@@ -35,6 +35,7 @@ HEADERS += mainwindow.h \
qdialogprogress.h \
qlighttextitem.h \
qlightpixmapitem.h \
qlscribe.h \
qdialogcdproperties.h \
qconsoleprintprogress.h
FORMS += qdialogtext.ui \