Import original source code KDE3 Asciiquarium-0.3.2 from https://store.kde.org/p/1124051.
KDE Asciiquarium is a screensaver based off Kirk Baucom's asciiquarium program (http://www.robobunny.com/projects/asciiquarium/). Code is GPL licensed, https://robobunny.com/projects/asciiquarium/gpl.txt Signed-off-by: gregory guy <gregory-tde@laposte.net>pull/16/head
parent
c628a69164
commit
66605c73af
@ -0,0 +1,32 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
|
||||||
|
###################################################################
|
||||||
|
# LOAD THE ENVIRONMENT AND SET UP THE TOOLS
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
## Load the builders in config
|
||||||
|
tools = [ 'default', 'generic', 'kde' ]
|
||||||
|
toolpath = [ './', './admin' ]
|
||||||
|
|
||||||
|
# Required as part of SCons
|
||||||
|
env = Environment(tools = tools, toolpath = toolpath)
|
||||||
|
|
||||||
|
# Pull in some default settings.
|
||||||
|
env.KDEuse("environ rpath nohelp")
|
||||||
|
#env.KDEuse("environ rpath lang_qt thread nohelp")
|
||||||
|
|
||||||
|
# Export the environment so that SConscript files in subdirs can access it.
|
||||||
|
Export('env')
|
||||||
|
|
||||||
|
###################################################################
|
||||||
|
# SCRIPTS FOR BUILDING THE TARGETS
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
distClean = env.Action("find %s -name '*.pyc' -exec rm {} \\;" % env.GetLaunchDir())
|
||||||
|
dist = env.Alias('dist', action = distClean)
|
||||||
|
|
||||||
|
env.Alias(dist, action = Delete("%s/cache" % env.GetLaunchDir()))
|
||||||
|
env.Clean(dist, ['cache'])
|
||||||
|
env.AlwaysBuild(dist)
|
||||||
|
|
||||||
|
env.subdirs('src')
|
@ -0,0 +1,506 @@
|
|||||||
|
## Thomas Nagy, 2005
|
||||||
|
|
||||||
|
"""
|
||||||
|
Detect and store the most common options
|
||||||
|
* kdecxxflags : debug=1 (-g) or debug=full (-g3, slower)
|
||||||
|
else use the user CXXFLAGS if any, - or -O2 by default
|
||||||
|
* prefix : the installation path
|
||||||
|
* extraincludes : a list of paths separated by ':'
|
||||||
|
ie: scons configure debug=full prefix=/usr/local extraincludes=/tmp/include:/usr/local
|
||||||
|
"""
|
||||||
|
|
||||||
|
BOLD ="\033[1m"
|
||||||
|
RED ="\033[91m"
|
||||||
|
GREEN ="\033[92m"
|
||||||
|
YELLOW ="\033[1m" #"\033[93m" # unreadable on white backgrounds
|
||||||
|
CYAN ="\033[96m"
|
||||||
|
NORMAL ="\033[0m"
|
||||||
|
|
||||||
|
import os, re, types, sys, string, shutil, stat
|
||||||
|
|
||||||
|
import SCons.Defaults
|
||||||
|
import SCons.Tool
|
||||||
|
import SCons.Util
|
||||||
|
from SCons.Script.SConscript import SConsEnvironment
|
||||||
|
from SCons.Options import Options, PathOption
|
||||||
|
|
||||||
|
class genobj:
|
||||||
|
def __init__(self, val, env):
|
||||||
|
if not val in "program shlib kioslave staticlib".split():
|
||||||
|
print "unknown genobj given: "+val
|
||||||
|
env.Exit(1)
|
||||||
|
|
||||||
|
self.type = val
|
||||||
|
self.orenv = env
|
||||||
|
self.env = None
|
||||||
|
self.executed = 0
|
||||||
|
|
||||||
|
self.target=''
|
||||||
|
self.src=None
|
||||||
|
|
||||||
|
self.cxxflags=''
|
||||||
|
self.cflags=''
|
||||||
|
self.includes=''
|
||||||
|
|
||||||
|
self.linkflags=''
|
||||||
|
self.libpaths=''
|
||||||
|
self.libs=''
|
||||||
|
|
||||||
|
# vars used by shlibs
|
||||||
|
self.vnum=''
|
||||||
|
self.libprefix=''
|
||||||
|
|
||||||
|
# a directory where to install the targets (optional)
|
||||||
|
self.instdir=''
|
||||||
|
# ignore the DESTDIR (optional)
|
||||||
|
self.nodestdir=''
|
||||||
|
|
||||||
|
# change the working directory before reading the targets
|
||||||
|
self.chdir=''
|
||||||
|
|
||||||
|
# these members are private
|
||||||
|
self.chdir_lock=None
|
||||||
|
self.old_os_dir=''
|
||||||
|
self.old_fs_dir=''
|
||||||
|
self.p_local_shlibs=[]
|
||||||
|
self.p_local_staticlibs=[]
|
||||||
|
self.p_global_shlibs=[]
|
||||||
|
|
||||||
|
#if not env.has_key('USE_THE_FORCE_LUKE'): env['USE_THE_FORCE_LUKE']=[self]
|
||||||
|
#else: env['USE_THE_FORCE_LUKE'].append(self)
|
||||||
|
|
||||||
|
def lockchdir(self):
|
||||||
|
if not self.chdir: return
|
||||||
|
self.chdir_lock=1
|
||||||
|
SConfFS=SCons.Node.FS.default_fs
|
||||||
|
self.old_fs_dir=SConfFS.getcwd()
|
||||||
|
self.old_os_dir=os.getcwd()
|
||||||
|
#os.chdir(old_os_dir+'/'+self.chdir)
|
||||||
|
SConfFS.chdir( SConfFS.Dir('#/'+self.chdir), change_os_dir=1)
|
||||||
|
|
||||||
|
def unlockchdir(self):
|
||||||
|
if not self.chdir: return
|
||||||
|
if self.chdir_lock:
|
||||||
|
#os.chdir(self.old_os_dir)
|
||||||
|
SCons.Node.FS.default_fs.chdir(self.old_fs_dir, change_os_dir=0)
|
||||||
|
self.chdir_lock=None
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
if self.orenv.has_key('DUMPCONFIG'):
|
||||||
|
print self.xml()
|
||||||
|
return
|
||||||
|
|
||||||
|
self.lockchdir()
|
||||||
|
|
||||||
|
self.env = self.orenv.Copy()
|
||||||
|
|
||||||
|
if not self.src or len(self.src) == 0:
|
||||||
|
print RED+"no source file given to object - self.src"+NORMAL
|
||||||
|
self.env.Exit(1)
|
||||||
|
if not self.env.has_key('nosmart_includes'): self.env.AppendUnique(CPPPATH=['./'])
|
||||||
|
if self.type == "kioslave": self.libprefix=''
|
||||||
|
|
||||||
|
if len(self.includes)>0: self.env.AppendUnique(CPPPATH=self.env.make_list(self.includes))
|
||||||
|
if len(self.cxxflags)>0: self.env.AppendUnique(CXXFLAGS=self.env.make_list(self.cxxflags))
|
||||||
|
if len(self.cflags)>0: self.env.AppendUnique(CCFLAGS=self.env.make_list(self.cflags))
|
||||||
|
|
||||||
|
llist=self.env.make_list(self.libs)
|
||||||
|
lext='.so .la'.split()
|
||||||
|
sext='.a'.split()
|
||||||
|
for l in llist:
|
||||||
|
sal=SCons.Util.splitext(l)
|
||||||
|
if len(sal)>1:
|
||||||
|
if sal[1] in lext: self.p_local_shlibs.append(sal[0]+'.so')
|
||||||
|
elif sal[1] in sext: self.p_local_staticlibs.append(sal[0]+'.a')
|
||||||
|
else: self.p_global_shlibs.append(l)
|
||||||
|
|
||||||
|
if len(self.p_global_shlibs)>0: self.env.AppendUnique(LIBS=self.p_global_shlibs)
|
||||||
|
if len(self.libpaths)>0: self.env.PrependUnique(LIBPATH=self.env.make_list(self.libpaths))
|
||||||
|
if len(self.linkflags)>0: self.env.PrependUnique(LINKFLAGS=self.env.make_list(self.linkflags))
|
||||||
|
|
||||||
|
# the target to return
|
||||||
|
ret=None
|
||||||
|
if self.type=='shlib' or self.type=='kioslave':
|
||||||
|
ret=self.env.bksys_shlib(self.target, self.src, self.instdir,
|
||||||
|
self.libprefix, self.vnum, nodestdir=self.nodestdir)
|
||||||
|
elif self.type=='program':
|
||||||
|
ret=self.env.Program(self.target, self.src)
|
||||||
|
if not self.env.has_key('NOAUTOINSTALL'):
|
||||||
|
self.env.bksys_install(self.instdir, ret, nodestdir=self.nodestdir)
|
||||||
|
elif self.type=='staticlib':
|
||||||
|
ret=self.env.StaticLibrary(self.target, self.src)
|
||||||
|
|
||||||
|
# we link the program against a shared library made locally, add the dependency
|
||||||
|
if len(self.p_local_shlibs)>0:
|
||||||
|
self.env.link_local_shlib(self.p_local_shlibs)
|
||||||
|
if ret: self.env.Depends( ret, self.p_local_shlibs )
|
||||||
|
if len(self.p_local_staticlibs)>0:
|
||||||
|
self.env.link_local_staticlib(self.p_local_staticlibs)
|
||||||
|
if ret: self.env.Depends( ret, self.p_local_staticlibs )
|
||||||
|
|
||||||
|
self.unlockchdir()
|
||||||
|
|
||||||
|
## Copy function that honors symlinks
|
||||||
|
def copy_bksys(dest, source, env):
|
||||||
|
if os.path.islink(source):
|
||||||
|
#print "symlinking "+source+" "+dest
|
||||||
|
if os.path.islink(dest):
|
||||||
|
os.unlink(dest)
|
||||||
|
os.symlink(os.readlink(source), dest)
|
||||||
|
else:
|
||||||
|
shutil.copy2(source, dest)
|
||||||
|
st=os.stat(source)
|
||||||
|
os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
## Return a list of things
|
||||||
|
def make_list(env, s):
|
||||||
|
if type(s) is types.ListType:
|
||||||
|
return s
|
||||||
|
else:
|
||||||
|
return s.split()
|
||||||
|
|
||||||
|
def exists(env):
|
||||||
|
return true
|
||||||
|
|
||||||
|
def generate(env):
|
||||||
|
## Bksys requires scons 0.96
|
||||||
|
env.EnsureSConsVersion(0, 96)
|
||||||
|
|
||||||
|
SConsEnvironment.make_list = make_list
|
||||||
|
|
||||||
|
env['HELP']=0
|
||||||
|
if '--help' in sys.argv or '-h' in sys.argv or 'help' in sys.argv:
|
||||||
|
env['HELP']=1
|
||||||
|
|
||||||
|
if env['HELP']:
|
||||||
|
print """
|
||||||
|
\033[1m*** Instructions ***
|
||||||
|
--------------------\033[0m
|
||||||
|
\033[1m* scons \033[0m: to compile
|
||||||
|
\033[1m* scons -j4 \033[0m: to compile with several instances
|
||||||
|
\033[1m* scons install \033[0m: to compile and install
|
||||||
|
\033[1m* scons -c install \033[0m: to uninstall
|
||||||
|
|
||||||
|
\033[1m*** Generic options ***
|
||||||
|
-----------------------\033[0m
|
||||||
|
\033[1m* debug \033[0m: debug=1 (-g) or debug=full (-g3, slower) else use environment CXXFLAGS, or -O2 by default
|
||||||
|
\033[1m* prefix \033[0m: the installation path
|
||||||
|
\033[1m* extraincludes \033[0m: a list of paths separated by ':'
|
||||||
|
\033[1mscons configure debug=full prefix=/usr/local extraincludes=/tmp/include:/usr/local\033[0m
|
||||||
|
"""
|
||||||
|
return
|
||||||
|
|
||||||
|
## Global cache directory
|
||||||
|
# Put all project files in it so a rm -rf cache will clean up the config
|
||||||
|
if not env.has_key('CACHEDIR'):
|
||||||
|
env['CACHEDIR'] = os.getcwd()+'/cache/'
|
||||||
|
if not os.path.isdir(env['CACHEDIR']):
|
||||||
|
os.mkdir(env['CACHEDIR'])
|
||||||
|
|
||||||
|
## SCons cache directory
|
||||||
|
# This avoids recompiling the same files over and over again:
|
||||||
|
# very handy when working with cvs
|
||||||
|
if os.getuid() != 0:
|
||||||
|
env.CacheDir(os.getcwd()+'/cache/objects')
|
||||||
|
|
||||||
|
# Avoid spreading .sconsign files everywhere - keep this line
|
||||||
|
env.SConsignFile(env['CACHEDIR']+'/scons_signatures')
|
||||||
|
|
||||||
|
def makeHashTable(args):
|
||||||
|
table = { }
|
||||||
|
for arg in args:
|
||||||
|
if len(arg) > 1:
|
||||||
|
lst=arg.split('=')
|
||||||
|
if len(lst) < 2:
|
||||||
|
continue
|
||||||
|
key=lst[0]
|
||||||
|
value=lst[1]
|
||||||
|
if len(key) > 0 and len(value) >0:
|
||||||
|
table[key] = value
|
||||||
|
return table
|
||||||
|
|
||||||
|
env['ARGS']=makeHashTable(sys.argv)
|
||||||
|
|
||||||
|
## Special trick for installing rpms ...
|
||||||
|
env['DESTDIR']=''
|
||||||
|
if 'install' in sys.argv:
|
||||||
|
dd=''
|
||||||
|
if os.environ.has_key('DESTDIR'):
|
||||||
|
dd=os.environ['DESTDIR']
|
||||||
|
if not dd:
|
||||||
|
if env['ARGS']: dd=env['ARGS']['DESTDIR']
|
||||||
|
if dd:
|
||||||
|
env['DESTDIR']=dd+'/'
|
||||||
|
print CYAN+'** Enabling DESTDIR for the project ** ' + NORMAL + env['DESTDIR']
|
||||||
|
|
||||||
|
## install symlinks for shared libraries properly
|
||||||
|
env['INSTALL'] = copy_bksys
|
||||||
|
|
||||||
|
## Use the same extension .o for all object files
|
||||||
|
env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
|
||||||
|
|
||||||
|
## load the options
|
||||||
|
cachefile=env['CACHEDIR']+'generic.cache.py'
|
||||||
|
opts = Options(cachefile)
|
||||||
|
opts.AddOptions(
|
||||||
|
( 'GENCCFLAGS', 'C flags' ),
|
||||||
|
( 'GENCXXFLAGS', 'debug level for the project : full or just anything' ),
|
||||||
|
( 'GENLINKFLAGS', 'additional link flags' ),
|
||||||
|
( 'PREFIX', 'prefix for installation' ),
|
||||||
|
( 'EXTRAINCLUDES', 'extra include paths for the project' ),
|
||||||
|
( 'ISCONFIGURED', 'is the project configured' ),
|
||||||
|
)
|
||||||
|
opts.Update(env)
|
||||||
|
|
||||||
|
# Use this to avoid an error message 'how to make target configure ?'
|
||||||
|
env.Alias('configure', None)
|
||||||
|
|
||||||
|
# Check if the following command line arguments have been given
|
||||||
|
# and set a flag in the environment to show whether or not it was
|
||||||
|
# given.
|
||||||
|
if 'install' in sys.argv:
|
||||||
|
env['_INSTALL']=1
|
||||||
|
else:
|
||||||
|
env['_INSTALL']=0
|
||||||
|
if 'configure' in sys.argv:
|
||||||
|
env['_CONFIGURE']=1
|
||||||
|
else:
|
||||||
|
env['_CONFIGURE']=0
|
||||||
|
|
||||||
|
# Configure the environment if needed
|
||||||
|
if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('ISCONFIGURED')):
|
||||||
|
|
||||||
|
# be paranoid, unset existing variables
|
||||||
|
for var in "GENCXXFLAGS GENCCFLAGS GENLINKFLAGS PREFIX EXTRAINCLUDES ISCONFIGURED EXTRAINCLUDES".split():
|
||||||
|
if env.has_key(var): env.__delitem__(var)
|
||||||
|
|
||||||
|
if env['ARGS'].get('debug', None):
|
||||||
|
debuglevel = env['ARGS'].get('debug', None)
|
||||||
|
print CYAN+'** Enabling debug for the project **' + NORMAL
|
||||||
|
if debuglevel == "full":
|
||||||
|
env['GENCXXFLAGS'] = ['-DDEBUG', '-g3', '-Wall']
|
||||||
|
else:
|
||||||
|
env['GENCXXFLAGS'] = ['-DDEBUG', '-g', '-Wall']
|
||||||
|
else:
|
||||||
|
if os.environ.has_key('CXXFLAGS'):
|
||||||
|
# user-defined flags (gentooers will be elighted)
|
||||||
|
env['GENCXXFLAGS'] = SCons.Util.CLVar( os.environ['CXXFLAGS'] )
|
||||||
|
env.Append( GENCXXFLAGS = ['-DNDEBUG', '-DNO_DEBUG'] )
|
||||||
|
else:
|
||||||
|
env.Append(GENCXXFLAGS = ['-O2', '-DNDEBUG', '-DNO_DEBUG'])
|
||||||
|
|
||||||
|
# Disable some unnecessary warnings.
|
||||||
|
env.Append(GENCXXFLAGS = ['-Wno-non-virtual-dtor', '-Wno-sign-compare', '-Wno-trigraphs'])
|
||||||
|
|
||||||
|
if os.environ.has_key('CFLAGS'):
|
||||||
|
env['GENCCFLAGS'] = SCons.Util.CLVar( os.environ['CFLAGS'] )
|
||||||
|
|
||||||
|
## FreeBSD settings (contributed by will at freebsd dot org)
|
||||||
|
if os.uname()[0] == "FreeBSD":
|
||||||
|
if os.environ.has_key('PTHREAD_LIBS'):
|
||||||
|
env.AppendUnique( GENLINKFLAGS = SCons.Util.CLVar( os.environ['PTHREAD_LIBS'] ) )
|
||||||
|
else:
|
||||||
|
syspf = os.popen('/sbin/sysctl kern.osreldate')
|
||||||
|
osreldate = int(syspf.read().split()[1])
|
||||||
|
syspf.close()
|
||||||
|
if osreldate < 500016:
|
||||||
|
env.AppendUnique( GENLINKFLAGS = ['-pthread'])
|
||||||
|
env.AppendUnique( GENCXXFLAGS = ['-D_THREAD_SAFE'])
|
||||||
|
elif osreldate < 502102:
|
||||||
|
env.AppendUnique( GENLINKFLAGS = ['-lc_r'])
|
||||||
|
env.AppendUnique( GENCXXFLAGS = ['-D_THREAD_SAFE'])
|
||||||
|
else:
|
||||||
|
env.AppendUnique( GENLINKFLAGS = ['-pthread'])
|
||||||
|
|
||||||
|
# User-specified prefix
|
||||||
|
if env['ARGS'].has_key('prefix'):
|
||||||
|
env['PREFIX'] = os.path.abspath( env['ARGS'].get('prefix', '') )
|
||||||
|
print (CYAN+'** installation prefix for the project set to : ' +
|
||||||
|
env['PREFIX'] +' **'+ NORMAL)
|
||||||
|
|
||||||
|
# User-specified include paths
|
||||||
|
env['EXTRAINCLUDES'] = env['ARGS'].get('extraincludes', None)
|
||||||
|
if env['EXTRAINCLUDES']:
|
||||||
|
print (CYAN+'** extra include paths for the project set to: ' +
|
||||||
|
env['EXTRAINCLUDES'] +' **'+ NORMAL)
|
||||||
|
|
||||||
|
env['ISCONFIGURED']=1
|
||||||
|
|
||||||
|
# And finally save the options in the cache
|
||||||
|
opts.Save(cachefile, env)
|
||||||
|
|
||||||
|
def bksys_install(lenv, subdir, files, destfile=None, nodestdir=None):
|
||||||
|
""" Install files on "scons install"
|
||||||
|
If the DESTDIR env variable has been set, (e.g. by
|
||||||
|
"scons install DESTDIR=$CURDIR/debian) then install files to that
|
||||||
|
directory, regardless of where the configure stage showed that
|
||||||
|
files should be installed.
|
||||||
|
This feature is useful for packagers, and users of GNU stow.
|
||||||
|
|
||||||
|
NB. The DESTDIR will be ignored if NODESTDIR is also set, although
|
||||||
|
the same effect can be acheived by not setting DESTDIR in the first
|
||||||
|
place."""
|
||||||
|
|
||||||
|
if not env['_INSTALL']:
|
||||||
|
return
|
||||||
|
basedir = env['DESTDIR']
|
||||||
|
if nodestdir or env.has_key('NODESTDIR') : basedir = "/"
|
||||||
|
install_list = None
|
||||||
|
if not destfile:
|
||||||
|
install_list = env.Install(basedir+subdir+'/', files)
|
||||||
|
else:
|
||||||
|
if subdir:
|
||||||
|
install_list = env.InstallAs(basedir+subdir+'/'+destfile, files)
|
||||||
|
else:
|
||||||
|
install_list = env.InstallAs(basedir+'/'+destfile, files)
|
||||||
|
env.Alias('install', install_list)
|
||||||
|
return install_list
|
||||||
|
|
||||||
|
def build_la_file(target, source, env):
|
||||||
|
""" Action for building libtool files.
|
||||||
|
Writes a .la file, as used by libtool."""
|
||||||
|
dest=open(target[0].path, 'w')
|
||||||
|
sname=source[0].name
|
||||||
|
dest.write("dlname='%s'\n" % sname)
|
||||||
|
if len(env['BKSYS_VNUM'])>0:
|
||||||
|
vnum=env['BKSYS_VNUM']
|
||||||
|
nums=vnum.split('.')
|
||||||
|
src=source[0].name
|
||||||
|
name = src.split('so.')[0] + 'so'
|
||||||
|
strn = src+" "+name+"."+str(nums[0])+" "+name
|
||||||
|
dest.write("library_names='%s'\n" % (strn) )
|
||||||
|
else:
|
||||||
|
dest.write("library_names='%s %s %s'\n" % (sname, sname, sname) )
|
||||||
|
dest.write("old_library=''\ndependency_libs=''\ncurrent=0\n")
|
||||||
|
dest.write("age=0\nrevision=0\ninstalled=yes\nshouldnotlink=no\n")
|
||||||
|
dest.write("dlopen=''\ndlpreopen=''\n")
|
||||||
|
dest.write("libdir='%s'" % env['BKSYS_DESTDIR'])
|
||||||
|
dest.close()
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def string_la_file(target, source, env):
|
||||||
|
print "building '%s' from '%s'" % (target[0].name, source[0].name)
|
||||||
|
la_file = env.Action(build_la_file, string_la_file, ['BKSYS_VNUM', 'BKSYS_DESTDIR'])
|
||||||
|
env['BUILDERS']['LaFile'] = env.Builder(action=la_file,suffix='.la',src_suffix=env['SHLIBSUFFIX'])
|
||||||
|
|
||||||
|
## Function for building shared libraries
|
||||||
|
def bksys_shlib(lenv, target, source, libdir, libprefix='lib', vnum='', noinst=None, nodestdir=None):
|
||||||
|
""" Install a shared library.
|
||||||
|
|
||||||
|
Installs a shared library, with or without a version number, and create a
|
||||||
|
.la file for use by libtool.
|
||||||
|
|
||||||
|
If library version numbering is to be used, the version number
|
||||||
|
should be passed as a period-delimited version number (e.g.
|
||||||
|
vnum = '1.2.3'). This causes the library to be installed
|
||||||
|
with its full version number, and with symlinks pointing to it.
|
||||||
|
|
||||||
|
For example, for libfoo version 1.2.3, install the file
|
||||||
|
libfoo.so.1.2.3, and create symlinks libfoo.so and
|
||||||
|
libfoo.so.1 that point to it.
|
||||||
|
"""
|
||||||
|
thisenv = lenv.Copy() # copying an existing environment is cheap
|
||||||
|
thisenv['BKSYS_DESTDIR']=libdir
|
||||||
|
thisenv['BKSYS_VNUM']=vnum
|
||||||
|
thisenv['SHLIBPREFIX']=libprefix
|
||||||
|
|
||||||
|
if len(vnum)>0:
|
||||||
|
thisenv['SHLIBSUFFIX']='.so.'+vnum
|
||||||
|
thisenv.Depends(target, thisenv.Value(vnum))
|
||||||
|
|
||||||
|
# Fix against a scons bug - shared libs and ordinal out of range(128)
|
||||||
|
if type(source) is types.ListType:
|
||||||
|
src2=[]
|
||||||
|
for i in source:
|
||||||
|
src2.append( str(i) )
|
||||||
|
source=src2
|
||||||
|
|
||||||
|
library_list = thisenv.SharedLibrary(target, source)
|
||||||
|
lafile_list = thisenv.LaFile(target, library_list)
|
||||||
|
|
||||||
|
## Install the libraries automatically
|
||||||
|
if not thisenv.has_key('NOAUTOINSTALL') and not noinst:
|
||||||
|
thisenv.bksys_install(libdir, library_list, nodestdir=nodestdir)
|
||||||
|
thisenv.bksys_install(libdir, lafile_list, nodestdir=nodestdir)
|
||||||
|
|
||||||
|
## Handle the versioning
|
||||||
|
if len(vnum)>0:
|
||||||
|
nums=vnum.split('.')
|
||||||
|
symlinkcom = ('cd $TARGET.dir && ' +
|
||||||
|
'rm -f $TARGET.name && ' +
|
||||||
|
'ln -s $SOURCE.name $TARGET.name')
|
||||||
|
tg = target+'.so.'+vnum
|
||||||
|
nm1 = target+'.so'
|
||||||
|
nm2 = target+'.so.'+nums[0]
|
||||||
|
|
||||||
|
thisenv.Command(nm1, tg, symlinkcom)
|
||||||
|
thisenv.Command(nm2, tg, symlinkcom)
|
||||||
|
|
||||||
|
#base=env['DESTDIR']+libdir+'/'
|
||||||
|
thisenv.bksys_install(libdir, nm1, nodestdir=nodestdir)
|
||||||
|
thisenv.bksys_install(libdir, nm2, nodestdir=nodestdir)
|
||||||
|
|
||||||
|
# Declare scons scripts to process
|
||||||
|
def subdirs(lenv, folderlist):
|
||||||
|
flist=[]
|
||||||
|
if type(folderlist) is types.ListType: flist = folderlist
|
||||||
|
else: flist = folderlist.split()
|
||||||
|
for i in flist:
|
||||||
|
lenv.SConscript(i+"/SConscript")
|
||||||
|
|
||||||
|
def link_local_shlib(lenv, str):
|
||||||
|
""" Links against a shared library made in the project """
|
||||||
|
lst = lenv.make_list(str)
|
||||||
|
for file in lst:
|
||||||
|
import re
|
||||||
|
reg = re.compile("(.*)/lib(.*).(la|so)")
|
||||||
|
result = reg.match(file)
|
||||||
|
if not result:
|
||||||
|
print "Unknown la file given "+file
|
||||||
|
continue
|
||||||
|
dir = result.group(1)
|
||||||
|
link = result.group(2)
|
||||||
|
lenv.AppendUnique(LIBS = [link])
|
||||||
|
lenv.PrependUnique(LIBPATH = [dir])
|
||||||
|
|
||||||
|
def link_local_staticlib(lenv, str):
|
||||||
|
""" Links against a shared library made in the project """
|
||||||
|
lst = lenv.make_list(str)
|
||||||
|
for file in lst:
|
||||||
|
import re
|
||||||
|
reg = re.compile("(.*)/(lib.*.a)")
|
||||||
|
result = reg.match(file)
|
||||||
|
if not result:
|
||||||
|
print "Unknown archive file given "+file
|
||||||
|
continue
|
||||||
|
|
||||||
|
f=SCons.Node.FS.default_fs.File(file)
|
||||||
|
lenv.Append(LINKFLAGS=[f.path])
|
||||||
|
|
||||||
|
#valid_targets = "program shlib kioslave staticlib".split()
|
||||||
|
SConsEnvironment.bksys_install = bksys_install
|
||||||
|
SConsEnvironment.bksys_shlib = bksys_shlib
|
||||||
|
SConsEnvironment.subdirs = subdirs
|
||||||
|
SConsEnvironment.link_local_shlib = link_local_shlib
|
||||||
|
SConsEnvironment.link_local_staticlib = link_local_staticlib
|
||||||
|
|
||||||
|
SConsEnvironment.genobj=genobj
|
||||||
|
|
||||||
|
if env.has_key('GENCXXFLAGS'):
|
||||||
|
env.AppendUnique( CPPFLAGS = env['GENCXXFLAGS'] )
|
||||||
|
|
||||||
|
if env.has_key('GENCCFLAGS'):
|
||||||
|
env.AppendUnique( CCFLAGS = env['GENCCFLAGS'] )
|
||||||
|
|
||||||
|
if env.has_key('GENLINKFLAGS'):
|
||||||
|
env.AppendUnique( LINKFLAGS = env['GENLINKFLAGS'] )
|
||||||
|
|
||||||
|
if env.has_key('EXTRAINCLUDES'):
|
||||||
|
if env['EXTRAINCLUDES']:
|
||||||
|
incpaths = []
|
||||||
|
for dir in str(env['EXTRAINCLUDES']).split(':'):
|
||||||
|
incpaths.append( dir )
|
||||||
|
env.Append(CPPPATH = incpaths)
|
||||||
|
|
||||||
|
env.Export('env')
|
@ -0,0 +1,821 @@
|
|||||||
|
# Made from scons qt.py and (heavily) modified into kde.py
|
||||||
|
# Thomas Nagy, 2004, 2005 <tnagy2^8@yahoo.fr>
|
||||||
|
|
||||||
|
"""
|
||||||
|
Run scons -h to display the associated help, or look below ..
|
||||||
|
"""
|
||||||
|
|
||||||
|
BOLD ="\033[1m"
|
||||||
|
RED ="\033[91m"
|
||||||
|
GREEN ="\033[92m"
|
||||||
|
YELLOW ="\033[1m" #"\033[93m" # unreadable on white backgrounds
|
||||||
|
CYAN ="\033[96m"
|
||||||
|
NORMAL ="\033[0m"
|
||||||
|
|
||||||
|
import os, re, types
|
||||||
|
from SCons.Script.SConscript import SConsEnvironment
|
||||||
|
|
||||||
|
# Returns the name of the shared object (i.e. libkdeui.so.4)
|
||||||
|
# referenced by a libtool archive (like libkdeui.la)
|
||||||
|
def getSOfromLA(lafile):
|
||||||
|
contents = open(lafile, 'r').read()
|
||||||
|
match = re.search("^dlname='([^']*)'$", contents, re.M)
|
||||||
|
if match:
|
||||||
|
return match.group(1)
|
||||||
|
return None
|
||||||
|
|
||||||
|
# A helper, needed .. everywhere
|
||||||
|
def KDEuse(lenv, flags):
|
||||||
|
if lenv['HELP']: lenv.Exit(0)
|
||||||
|
|
||||||
|
_flags=lenv.make_list(flags)
|
||||||
|
if 'environ' in _flags:
|
||||||
|
## The scons developers advise against using this but it is mostly innocuous :)
|
||||||
|
lenv.AppendUnique( ENV = os.environ )
|
||||||
|
if not 'lang_qt' in _flags:
|
||||||
|
## Use this define if you are using the kde translation scheme (.po files)
|
||||||
|
lenv.Append( CPPFLAGS = '-DQT_NO_TRANSLATION' )
|
||||||
|
if 'rpath' in _flags:
|
||||||
|
## Use this to set rpath - this may cause trouble if folders are moved (chrpath)
|
||||||
|
lenv.Append( RPATH = [lenv['QTLIBPATH'], lenv['KDELIBPATH'], lenv['KDEMODULE']] )
|
||||||
|
kdelibpaths=[]
|
||||||
|
if lenv['KDELIBPATH'] == lenv['KDELIB']:
|
||||||
|
kdelibpaths = [lenv['KDELIB']]
|
||||||
|
else:
|
||||||
|
kdelibpaths = [lenv['KDELIBPATH'], lenv['KDELIB']]
|
||||||
|
lenv.Append( RPATH = [lenv['QTLIBPATH'], lenv['KDEMODULE']]+kdelibpaths )
|
||||||
|
if 'thread' in _flags:
|
||||||
|
## Uncomment the following if you need threading support
|
||||||
|
lenv.KDEaddflags_cxx( ['-DQT_THREAD_SUPPORT', '-D_REENTRANT'] )
|
||||||
|
if 'fastmoc' in _flags:
|
||||||
|
lenv['BKSYS_FASTMOC']=1
|
||||||
|
if not 'nohelp' in _flags:
|
||||||
|
if lenv['_CONFIGURE'] or lenv['HELP']:
|
||||||
|
lenv.Exit(0)
|
||||||
|
if not 'nosmart' or not lenv.has_key('nosmart_includes'):
|
||||||
|
lenv.AppendUnique(CPPPATH=['#/'])
|
||||||
|
lst=[]
|
||||||
|
if lenv.has_key('USE_THE_FORCE_LUKE'):
|
||||||
|
lst=lenv['USE_THE_FORCE_LUKE']
|
||||||
|
lenv.__delitem__('USE_THE_FORCE_LUKE')
|
||||||
|
for v in lst:
|
||||||
|
v.execute()
|
||||||
|
else:
|
||||||
|
lenv['nosmart_includes']=1
|
||||||
|
|
||||||
|
## To use kdDebug(intvalue)<<"some trace"<<endl; you need to define -DDEBUG
|
||||||
|
## it is done in admin/generic.py automatically when you do scons configure debug=1
|
||||||
|
|
||||||
|
def exists(env):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def detect_kde(env):
|
||||||
|
""" Detect the qt and kde environment using kde-config mostly """
|
||||||
|
def getpath(varname):
|
||||||
|
if not env.has_key('ARGS'): return None
|
||||||
|
v=env['ARGS'].get(varname, None)
|
||||||
|
if v: v=os.path.abspath(v)
|
||||||
|
return v
|
||||||
|
|
||||||
|
prefix = getpath('prefix')
|
||||||
|
execprefix = getpath('execprefix')
|
||||||
|
datadir = getpath('datadir')
|
||||||
|
libdir = getpath('libdir')
|
||||||
|
kdeincludes = getpath('kdeincludes')
|
||||||
|
kdelibs = getpath('kdelibs')
|
||||||
|
qtincludes = getpath('qtincludes')
|
||||||
|
qtlibs = getpath('qtlibs')
|
||||||
|
libsuffix = ''
|
||||||
|
if env.has_key('ARGS'): libsuffix=env['ARGS'].get('libsuffix', '')
|
||||||
|
|
||||||
|
if libdir: libdir = libdir+libsuffix
|
||||||
|
|
||||||
|
## Detect the kde libraries
|
||||||
|
print "Checking for kde-config : ",
|
||||||
|
kde_config = os.popen("which kde-config 2>/dev/null").read().strip()
|
||||||
|
if len(kde_config):
|
||||||
|
print GREEN+"kde-config was found"+NORMAL
|
||||||
|
else:
|
||||||
|
print RED+"kde-config was NOT found in your PATH"+NORMAL
|
||||||
|
print "Make sure kde is installed properly"
|
||||||
|
print "(missing package kdebase-devel?)"
|
||||||
|
env.Exit(1)
|
||||||
|
env['KDEDIR'] = os.popen('kde-config -prefix').read().strip()
|
||||||
|
|
||||||
|
print "Checking for kde version : ",
|
||||||
|
kde_version = os.popen("kde-config --version|grep KDE").read().strip().split()[1]
|
||||||
|
if int(kde_version[0]) != 3 or int(kde_version[2]) < 2:
|
||||||
|
print RED+kde_version
|
||||||
|
print RED+"Your kde version can be too old"+NORMAL
|
||||||
|
print RED+"Please make sure kde is at least 3.2"+NORMAL
|
||||||
|
else:
|
||||||
|
print GREEN+kde_version+NORMAL
|
||||||
|
|
||||||
|
## Detect the qt library
|
||||||
|
print "Checking for the qt library : ",
|
||||||
|
qtdir = os.getenv("QTDIR")
|
||||||
|
if qtdir:
|
||||||
|
print GREEN+"qt is in "+qtdir+NORMAL
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
tmplibdir = os.popen('kde-config --expandvars --install lib').read().strip()
|
||||||
|
libkdeuiSO = tmplibdir+'/'+getSOfromLA(tmplibdir+'/libkdeui.la')
|
||||||
|
m = re.search('(.*)/lib/libqt.*', os.popen('ldd ' + libkdeuiSO + ' | grep libqt').read().strip().split()[2])
|
||||||
|
except:
|
||||||
|
m=None
|
||||||
|
if m:
|
||||||
|
qtdir = m.group(1)
|
||||||
|
print YELLOW+"qt was found as "+m.group(1)+NORMAL
|
||||||
|
else:
|
||||||
|
print RED+"qt was not found"+NORMAL
|
||||||
|
print RED+"Please set QTDIR first (/usr/lib/qt3?) or try scons -h for more options"+NORMAL
|
||||||
|
env.Exit(1)
|
||||||
|
env['QTDIR'] = qtdir.strip()
|
||||||
|
|
||||||
|
## Find the necessary programs uic and moc
|
||||||
|
print "Checking for uic : ",
|
||||||
|
uic = qtdir + "/bin/uic"
|
||||||
|
if os.path.isfile(uic):
|
||||||
|
print GREEN+"uic was found as "+uic+NORMAL
|
||||||
|
else:
|
||||||
|
uic = os.popen("which uic 2>/dev/null").read().strip()
|
||||||
|
if len(uic):
|
||||||
|
print YELLOW+"uic was found as "+uic+NORMAL
|
||||||
|
else:
|
||||||
|
uic = os.popen("which uic 2>/dev/null").read().strip()
|
||||||
|
if len(uic):
|
||||||
|
print YELLOW+"uic was found as "+uic+NORMAL
|
||||||
|
else:
|
||||||
|
print RED+"uic was not found - set QTDIR put it in your PATH ?"+NORMAL
|
||||||
|
env.Exit(1)
|
||||||
|
env['QT_UIC'] = uic
|
||||||
|
|
||||||
|
print "Checking for moc : ",
|
||||||
|
moc = qtdir + "/bin/moc"
|
||||||
|
if os.path.isfile(moc):
|
||||||
|
print GREEN + "moc was found as " + moc + NORMAL
|
||||||
|
else:
|
||||||
|
moc = os.popen("which moc 2>/dev/null").read().strip()
|
||||||
|
if len(moc):
|
||||||
|
print YELLOW + "moc was found as " + moc + NORMAL
|
||||||
|
elif os.path.isfile("/usr/share/qt3/bin/moc"):
|
||||||
|
moc = "/usr/share/qt3/bin/moc"
|
||||||
|
print YELLOW + "moc was found as " + moc + NORMAL
|
||||||
|
else:
|
||||||
|
print RED + "moc was not found - set QTDIR or put it in your PATH ?" + NORMAL
|
||||||
|
env.Exit(1)
|
||||||
|
env['QT_MOC'] = moc
|
||||||
|
|
||||||
|
## check for the qt and kde includes
|
||||||
|
print "Checking for the qt includes : ",
|
||||||
|
if qtincludes and os.path.isfile(qtincludes + "/qlayout.h"):
|
||||||
|
# The user told where to look for and it looks valid
|
||||||
|
print GREEN + "ok " + qtincludes + NORMAL
|
||||||
|
else:
|
||||||
|
if os.path.isfile(qtdir + "/include/qlayout.h"):
|
||||||
|
# Automatic detection
|
||||||
|
print GREEN + "ok " + qtdir + "/include/ " + NORMAL
|
||||||
|
qtincludes = qtdir + "/include/"
|
||||||
|
elif os.path.isfile("/usr/include/qt3/qlayout.h"):
|
||||||
|
# Debian probably
|
||||||
|
print YELLOW + "the qt headers were found in /usr/include/qt3/ " + NORMAL
|
||||||
|
qtincludes = "/usr/include/qt3"
|
||||||
|
else:
|
||||||
|
print RED + "the qt headers were not found" + NORMAL
|
||||||
|
env.Exit(1)
|
||||||
|
|
||||||
|
print "Checking for the kde includes : ",
|
||||||
|
kdeprefix = os.popen("kde-config --prefix").read().strip()
|
||||||
|
if not kdeincludes:
|
||||||
|
kdeincludes = kdeprefix+"/include/"
|
||||||
|
if os.path.isfile(kdeincludes + "/klineedit.h"):
|
||||||
|
print GREEN + "ok " + kdeincludes + NORMAL
|
||||||
|
else:
|
||||||
|
if os.path.isfile(kdeprefix+"/include/kde/klineedit.h"):
|
||||||
|
# Debian, Fedora probably
|
||||||
|
print YELLOW + "the kde headers were found in " + kdeprefix + "/include/kde/" + NORMAL
|
||||||
|
kdeincludes = kdeprefix + "/include/kde/"
|
||||||
|
else:
|
||||||
|
print RED + "The kde includes were NOT found" + NORMAL
|
||||||
|
env.Exit(1)
|
||||||
|
|
||||||
|
# kde-config options
|
||||||
|
kdec_opts = {'KDEBIN' : 'exe', 'KDEAPPS' : 'apps',
|
||||||
|
'KDEDATA' : 'data', 'KDEICONS' : 'icon',
|
||||||
|
'KDEMODULE' : 'module', 'KDELOCALE' : 'locale',
|
||||||
|
'KDEKCFG' : 'kcfg', 'KDEDOC' : 'html',
|
||||||
|
'KDEMENU' : 'apps', 'KDEXDG' : 'xdgdata-apps',
|
||||||
|
'KDEMIME' : 'mime', 'KDEXDGDIR' : 'xdgdata-dirs',
|
||||||
|
'KDESERV' : 'services','KDESERVTYPES' : 'servicetypes',
|
||||||
|
'KDEINCLUDE': 'include'
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix:
|
||||||
|
## use the user-specified prefix
|
||||||
|
if not execprefix:
|
||||||
|
execprefix = prefix
|
||||||
|
if not datadir:
|
||||||
|
datadir=prefix+"/share"
|
||||||
|
if not libdir:
|
||||||
|
libdir=execprefix+"/lib"+libsuffix
|
||||||
|
|
||||||
|
subst_vars = lambda x: x.replace('${exec_prefix}', execprefix)\
|
||||||
|
.replace('${datadir}', datadir)\
|
||||||
|
.replace('${libdir}', libdir)
|
||||||
|
debian_fix = lambda x: x.replace('/usr/share', '${datadir}')
|
||||||
|
env['PREFIX'] = prefix
|
||||||
|
env['KDELIB'] = libdir
|
||||||
|
for (var, option) in kdec_opts.items():
|
||||||
|
dir = os.popen('kde-config --install ' + option).read().strip()
|
||||||
|
if var == 'KDEDOC': dir = debian_fix(dir)
|
||||||
|
env[var] = subst_vars(dir)
|
||||||
|
|
||||||
|
else:
|
||||||
|
env['PREFIX'] = os.popen('kde-config --expandvars --prefix').read().strip()
|
||||||
|
env['KDELIB'] = os.popen('kde-config --expandvars --install lib').read().strip()
|
||||||
|
for (var, option) in kdec_opts.items():
|
||||||
|
dir = os.popen('kde-config --expandvars --install ' + option).read().strip()
|
||||||
|
env[var] = dir
|
||||||
|
|
||||||
|
env['QTPLUGINS']=os.popen('kde-config --expandvars --install qtplugins').read().strip()
|
||||||
|
|
||||||
|
## kde libs and includes
|
||||||
|
env['KDEINCLUDEPATH']=kdeincludes
|
||||||
|
if not kdelibs:
|
||||||
|
kdelibs=os.popen('kde-config --expandvars --install lib').read().strip()
|
||||||
|
env['KDELIBPATH']=kdelibs
|
||||||
|
|
||||||
|
## qt libs and includes
|
||||||
|
env['QTINCLUDEPATH']=qtincludes
|
||||||
|
if not qtlibs:
|
||||||
|
qtlibs=qtdir+"/lib"+libsuffix
|
||||||
|
env['QTLIBPATH']=qtlibs
|
||||||
|
|
||||||
|
def generate(env):
|
||||||
|
""""Set up the qt and kde environment and builders - the moc part is difficult to understand """
|
||||||
|
|
||||||
|
# attach this function immediately
|
||||||
|
SConsEnvironment.KDEuse = KDEuse
|
||||||
|
|
||||||
|
if env['HELP']:
|
||||||
|
print """\033[1m*** KDE options ***
|
||||||
|
-------------------\033[0m
|
||||||
|
\033[1m* prefix \033[0m: base install path, ie: /usr/local
|
||||||
|
\033[1m* execprefix \033[0m: install path for binaries, ie: /usr/bin
|
||||||
|
\033[1m* datadir \033[0m: install path for the data, ie: /usr/local/share
|
||||||
|
\033[1m* libdir \033[0m: install path for the libs, ie: /usr/lib
|
||||||
|
\033[1m* libsuffix \033[0m: suffix of libraries on amd64, ie: 64, 32
|
||||||
|
\033[1m* kdeincludes\033[0m: path to the kde includes (/usr/include/kde on debian, ...)
|
||||||
|
\033[1m* qtincludes \033[0m: same punishment, for qt includes (/usr/include/qt on debian, ...)
|
||||||
|
\033[1m* kdelibs \033[0m: path to the kde libs, for linking the programs
|
||||||
|
\033[1m* qtlibs \033[0m: same punishment, for qt libraries
|
||||||
|
ie: \033[1mscons configure libdir=/usr/local/lib qtincludes=/usr/include/qt\033[0m
|
||||||
|
"""
|
||||||
|
return
|
||||||
|
|
||||||
|
import SCons.Defaults
|
||||||
|
import SCons.Tool
|
||||||
|
import SCons.Util
|
||||||
|
import SCons.Node
|
||||||
|
|
||||||
|
CLVar = SCons.Util.CLVar
|
||||||
|
splitext = SCons.Util.splitext
|
||||||
|
Builder = SCons.Builder.Builder
|
||||||
|
|
||||||
|
# Detect the environment - replaces ./configure implicitely and store the options into a cache
|
||||||
|
from SCons.Options import Options
|
||||||
|
cachefile=env['CACHEDIR']+'kde.cache.py'
|
||||||
|
opts = Options(cachefile)
|
||||||
|
opts.AddOptions(
|
||||||
|
('PREFIX', 'root of the program installation'),
|
||||||
|
|
||||||
|
('QTDIR', ''),
|
||||||
|
('QTLIBPATH', 'path to the qt libraries'),
|
||||||
|
('QTINCLUDEPATH', 'path to the qt includes'),
|
||||||
|
('QT_UIC', 'uic command'),
|
||||||
|
('QT_MOC', 'moc command'),
|
||||||
|
('QTPLUGINS', 'uic executable command'),
|
||||||
|
|
||||||
|
('KDEDIR', ''),
|
||||||
|
('KDELIBPATH', 'path to the installed kde libs'),
|
||||||
|
('KDEINCLUDEPATH', 'path to the installed kde includes'),
|
||||||
|
|
||||||
|
('KDEBIN', 'inst path of the kde binaries'),
|
||||||
|
('KDEINCLUDE', 'inst path of the kde include files'),
|
||||||
|
('KDELIB', 'inst path of the kde libraries'),
|
||||||
|
('KDEMODULE', 'inst path of the parts and libs'),
|
||||||
|
('KDEDATA', 'inst path of the application data'),
|
||||||
|
('KDELOCALE', ''), ('KDEDOC', ''), ('KDEKCFG', ''),
|
||||||
|
('KDEXDG', ''), ('KDEXDGDIR', ''), ('KDEMENU', ''),
|
||||||
|
('KDEMIME', ''), ('KDEICONS', ''), ('KDESERV', ''),
|
||||||
|
('KDESERVTYPES', ''), ('KDEAPPS', ''),
|
||||||
|
)
|
||||||
|
opts.Update(env)
|
||||||
|
|
||||||
|
def getInstDirForResType(lenv,restype):
|
||||||
|
if len(restype) == 0 or not lenv.has_key(restype):
|
||||||
|
print RED+"unknown resource type "+restype+NORMAL
|
||||||
|
lenv.Exit(1)
|
||||||
|
else:
|
||||||
|
instdir = lenv[restype]
|
||||||
|
basedir=lenv['DESTDIR']
|
||||||
|
## support for installing into other folders when PREFIX is set - used by gnu stow
|
||||||
|
if basedir: instdir = instdir.replace(lenv['PREFIX'], basedir)
|
||||||
|
return instdir
|
||||||
|
|
||||||
|
# reconfigure when things are missing
|
||||||
|
if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('QTDIR') or not env.has_key('KDEDIR')):
|
||||||
|
detect_kde(env)
|
||||||
|
opts.Save(cachefile, env)
|
||||||
|
|
||||||
|
## set default variables, one can override them in sconscript files
|
||||||
|
env.Append(CXXFLAGS = ['-I'+env['KDEINCLUDEPATH'], '-I'+env['QTINCLUDEPATH'] ],
|
||||||
|
LIBPATH = [env['KDELIBPATH'], env['QTLIBPATH'] ])
|
||||||
|
|
||||||
|
env['QT_AUTOSCAN'] = 1
|
||||||
|
env['QT_DEBUG'] = 0
|
||||||
|
|
||||||
|
env['MEINPROC'] = 'meinproc'
|
||||||
|
env['MSGFMT'] = 'msgfmt'
|
||||||
|
|
||||||
|
## ui file processing
|
||||||
|
def uic_processing(target, source, env):
|
||||||
|
inc_kde ='#include <klocale.h>\n#include <kdialog.h>\n'
|
||||||
|
inc_moc ='#include "%s"\n' % target[2].name
|
||||||
|
comp_h ='$QT_UIC -L $QTPLUGINS -nounload -o %s %s' % (target[0].path, source[0].path)
|
||||||
|
comp_c ='$QT_UIC -L $QTPLUGINS -nounload -tr tr2i18n -impl %s %s' % (target[0].path, source[0].path)
|
||||||
|
comp_moc ='$QT_MOC -o %s %s' % (target[2].path, target[0].path)
|
||||||
|
if env.Execute(comp_h):
|
||||||
|
return ret
|
||||||
|
dest = open( target[1].path, "w" )
|
||||||
|
dest.write(inc_kde)
|
||||||
|
dest.close()
|
||||||
|
if env.Execute( comp_c+" >> "+target[1].path ):
|
||||||
|
return ret
|
||||||
|
dest = open( target[1].path, "a" )
|
||||||
|
dest.write(inc_moc)
|
||||||
|
dest.close()
|
||||||
|
ret = env.Execute( comp_moc )
|
||||||
|
return ret
|
||||||
|
def uicEmitter(target, source, env):
|
||||||
|
adjustixes = SCons.Util.adjustixes
|
||||||
|
bs = SCons.Util.splitext(str(source[0].name))[0]
|
||||||
|
bs = os.path.join(str(target[0].get_dir()),bs)
|
||||||
|
target.append(bs+'.cpp')
|
||||||
|
target.append(bs+'.moc')
|
||||||
|
return target, source
|
||||||
|
env['BUILDERS']['Uic']=Builder(action=uic_processing,emitter=uicEmitter,suffix='.h',src_suffix='.ui')
|
||||||
|
|
||||||
|
def kcfg_buildit(target, source, env):
|
||||||
|
comp='kconfig_compiler -d%s %s %s' % (str(source[0].get_dir()), source[1].path, source[0].path)
|
||||||
|
return env.Execute(comp)
|
||||||
|
def kcfg_stringit(target, source, env):
|
||||||
|
print "processing %s to get %s and %s" % (source[0].name, target[0].name, target[1].name)
|
||||||
|
def kcfgEmitter(target, source, env):
|
||||||
|
adjustixes = SCons.Util.adjustixes
|
||||||
|
bs = SCons.Util.splitext(str(source[0].name))[0]
|
||||||
|
bs = os.path.join(str(target[0].get_dir()),bs)
|
||||||
|
# .h file is already there
|
||||||
|
target.append(bs+'.cpp')
|
||||||
|
|
||||||
|
if not os.path.isfile(str(source[0])):
|
||||||
|
print RED+'kcfg file given '+str(source[0])+' does not exist !'+NORMAL
|
||||||
|
print os.popen('pwd').read()
|
||||||
|
return target, source
|
||||||
|
kfcgfilename=""
|
||||||
|
kcfgFileDeclRx = re.compile("^[fF]ile\s*=\s*(.+)\s*$")
|
||||||
|
for line in file(str(source[0]), "r").readlines():
|
||||||
|
match = kcfgFileDeclRx.match(line.strip())
|
||||||
|
if match:
|
||||||
|
kcfgfilename = match.group(1)
|
||||||
|
break
|
||||||
|
if not kcfgfilename:
|
||||||
|
print 'invalid kcfgc file'
|
||||||
|
return 0
|
||||||
|
source.append(str(source[0].get_dir())+'/'+kcfgfilename)
|
||||||
|
return target, source
|
||||||
|
|
||||||
|
env['BUILDERS']['Kcfg']=Builder(action=env.Action(kcfg_buildit, kcfg_stringit),
|
||||||
|
emitter=kcfgEmitter, suffix='.h', src_suffix='.kcfgc')
|
||||||
|
|
||||||
|
## MOC processing
|
||||||
|
env['BUILDERS']['Moc']=Builder(action='$QT_MOC -o $TARGET $SOURCE',suffix='.moc',src_suffix='.h')
|
||||||
|
env['BUILDERS']['Moccpp']=Builder(action='$QT_MOC -o $TARGET $SOURCE',suffix='_moc.cpp',src_suffix='.h')
|
||||||
|
|
||||||
|
## KIDL file
|
||||||
|
env['BUILDERS']['Kidl']=Builder(action= 'dcopidl $SOURCE > $TARGET || (rm -f $TARGET ; false)',
|
||||||
|
suffix='.kidl', src_suffix='.h')
|
||||||
|
## DCOP
|
||||||
|
env['BUILDERS']['Dcop']=Builder(action='dcopidl2cpp --c++-suffix cpp --no-signals --no-stub $SOURCE',
|
||||||
|
suffix='_skel.cpp', src_suffix='.kidl')
|
||||||
|
## STUB
|
||||||
|
env['BUILDERS']['Stub']=Builder(action= 'dcopidl2cpp --c++-suffix cpp --no-signals --no-skel $SOURCE',
|
||||||
|
suffix='_stub.cpp', src_suffix='.kidl')
|
||||||
|
## DOCUMENTATION
|
||||||
|
env['BUILDERS']['Meinproc']=Builder(action='$MEINPROC --check --cache $TARGET $SOURCE',suffix='.cache.bz2')
|
||||||
|
## TRANSLATIONS
|
||||||
|
env['BUILDERS']['Transfiles']=Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
|
||||||
|
|
||||||
|
## Handy helpers for building kde programs
|
||||||
|
## You should not have to modify them ..
|
||||||
|
|
||||||
|
ui_ext = [".ui"]
|
||||||
|
kcfg_ext = ['.kcfgc']
|
||||||
|
header_ext = [".h", ".hxx", ".hpp", ".hh"]
|
||||||
|
cpp_ext = [".cpp", ".cxx", ".cc"]
|
||||||
|
skel_ext = [".skel", ".SKEL"]
|
||||||
|
stub_ext = [".stub", ".STUB"]
|
||||||
|
|
||||||
|
def KDEfiles(lenv, target, source):
|
||||||
|
""" Returns a list of files for scons (handles kde tricks like .skel)
|
||||||
|
It also makes custom checks against double includes like : ['file.ui', 'file.cpp']
|
||||||
|
(file.cpp is already included because of file.ui) """
|
||||||
|
|
||||||
|
q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]')
|
||||||
|
def scan_moc(bs, file_cpp):
|
||||||
|
addfile=None
|
||||||
|
# try to find the header
|
||||||
|
h_ext=''
|
||||||
|
for n_h_ext in header_ext:
|
||||||
|
if os.path.isfile(bs+n_h_ext):
|
||||||
|
h_ext=n_h_ext
|
||||||
|
break
|
||||||
|
# We have the header corresponding to the cpp file
|
||||||
|
if h_ext:
|
||||||
|
needscan=0
|
||||||
|
# User asked for fastmoc, try to avoid scanning
|
||||||
|
if env.has_key('BKSYS_FASTMOC'):
|
||||||
|
if os.path.isfile(bs+'.moc'):
|
||||||
|
lenv.Moc(bs+h_ext)
|
||||||
|
elif os.path.isfile(bs+'_moc.cpp'):
|
||||||
|
lenv.Moccpp(bs+h_ext)
|
||||||
|
addfile=bs+'_moc.cpp'
|
||||||
|
else:
|
||||||
|
#print "need scanning "+os.getcwd()+'/'+bs+".moc"
|
||||||
|
needscan=1
|
||||||
|
else:
|
||||||
|
needscan=1
|
||||||
|
# We cannot avoid scanning the files ...
|
||||||
|
if needscan:
|
||||||
|
file_h=bs+h_ext
|
||||||
|
h_contents = open(file_h, 'rb').read()
|
||||||
|
if q_object_search.search(h_contents):
|
||||||
|
# we know now there is Q_OBJECT macro
|
||||||
|
lst = bs.split('/')
|
||||||
|
val = lst[ len(lst) - 1 ]
|
||||||
|
reg = '\n\s*#include\s*("|<)'+val+'.moc("|>)'
|
||||||
|
meta_object_search = re.compile(reg)
|
||||||
|
cpp_contents = open(file_cpp, 'rb').read()
|
||||||
|
if meta_object_search.search(cpp_contents):
|
||||||
|
lenv.Moc(file_h)
|
||||||
|
else:
|
||||||
|
lenv.Moccpp(file_h)
|
||||||
|
addfile=bs+'_moc.cpp'
|
||||||
|
print "WARNING: moc.cpp for "+bs+h_ext+" consider using #include <file.moc> instead"
|
||||||
|
return addfile
|
||||||
|
|
||||||
|
src=[]
|
||||||
|
ui_files=[]
|
||||||
|
kcfg_files=[]
|
||||||
|
other_files=[]
|
||||||
|
kidl=[]
|
||||||
|
|
||||||
|
source_=lenv.make_list(source)
|
||||||
|
|
||||||
|
# For each file, check wether it is a dcop file or not, and create the complete list of sources
|
||||||
|
for file in source_:
|
||||||
|
bs = SCons.Util.splitext(file)[0]
|
||||||
|
ext = SCons.Util.splitext(file)[1]
|
||||||
|
if ext in skel_ext:
|
||||||
|
if not bs in kidl:
|
||||||
|
kidl.append(bs)
|
||||||
|
lenv.Dcop(bs+'.kidl')
|
||||||
|
src.append(bs+'_skel.cpp')
|
||||||
|
elif ext in stub_ext:
|
||||||
|
if not bs in kidl:
|
||||||
|
kidl.append(bs)
|
||||||
|
lenv.Stub(bs+'.kidl')
|
||||||
|
src.append(bs+'_stub.cpp')
|
||||||
|
elif ext == ".moch":
|
||||||
|
lenv.Moccpp(bs+'.h')
|
||||||
|
src.append(bs+'_moc.cpp')
|
||||||
|
elif ext in cpp_ext:
|
||||||
|
src.append(file)
|
||||||
|
if not env.has_key('NOMOCFILE'):
|
||||||
|
ret = scan_moc(bs, file)
|
||||||
|
if ret:
|
||||||
|
src.append( ret )
|
||||||
|
elif ext in ui_ext:
|
||||||
|
lenv.Uic(file)
|
||||||
|
src.append(bs+'.cpp')
|
||||||
|
elif ext in kcfg_ext:
|
||||||
|
lenv.Kcfg(file)
|
||||||
|
src.append(bs+'.cpp')
|
||||||
|
else:
|
||||||
|
src.append(file)
|
||||||
|
|
||||||
|
for base in kidl:
|
||||||
|
lenv.Kidl(base+'.h')
|
||||||
|
|
||||||
|
# Now check against typical newbie errors
|
||||||
|
for file in ui_files:
|
||||||
|
for ofile in other_files:
|
||||||
|
if ofile == file:
|
||||||
|
print RED+"WARNING: You have included "+file+".ui and another file of the same prefix"+NORMAL
|
||||||
|
print "Files generated by uic (file.h, file.cpp must not be included"
|
||||||
|
for file in kcfg_files:
|
||||||
|
for ofile in other_files:
|
||||||
|
if ofile == file:
|
||||||
|
print RED+"WARNING: You have included "+file+".kcfg and another file of the same prefix"+NORMAL
|
||||||
|
print "Files generated by kconfig_compiler (settings.h, settings.cpp) must not be included"
|
||||||
|
return src
|
||||||
|
|
||||||
|
|
||||||
|
""" In the future, these functions will contain the code that will dump the
|
||||||
|
configuration for re-use from an IDE """
|
||||||
|
import glob
|
||||||
|
def KDEinstall(lenv, restype, subdir, files):
|
||||||
|
if env.has_key('DUMPCONFIG'):
|
||||||
|
print "<install type=\"%s\" subdir=\"%s\">" % (restype, subdir)
|
||||||
|
for i in lenv.make_list(files):
|
||||||
|
print " <file name=\"%s\"/>" % i
|
||||||
|
print "</install>"
|
||||||
|
return
|
||||||
|
|
||||||
|
if not env['_INSTALL']:
|
||||||
|
return
|
||||||
|
dir = getInstDirForResType(lenv, restype)
|
||||||
|
install_list = lenv.bksys_install(dir+'/'+subdir, files, nodestdir=1)
|
||||||
|
return install_list
|
||||||
|
|
||||||
|
def KDEinstallas(lenv, restype, destfile, file):
|
||||||
|
if not env['_INSTALL']:
|
||||||
|
return
|
||||||
|
dir = getInstDirForResType(lenv, restype)
|
||||||
|
install_list = lenv.InstallAs(dir+'/'+destfile, file)
|
||||||
|
env.Alias('install', install_list)
|
||||||
|
return install_list
|
||||||
|
|
||||||
|
def KDEprogram(lenv, target, source,
|
||||||
|
includes='', localshlibs='', globallibs='', globalcxxflags=''):
|
||||||
|
""" Makes a kde program
|
||||||
|
The program is installed except if one sets env['NOAUTOINSTALL'] """
|
||||||
|
src = KDEfiles(lenv, target, source)
|
||||||
|
program_list = lenv.Program(target, src)
|
||||||
|
|
||||||
|
# we link the program against a shared library done locally, add the dependency
|
||||||
|
if not lenv.has_key('nosmart_includes'):
|
||||||
|
lenv.AppendUnique(CPPPATH=['./'])
|
||||||
|
if len(localshlibs)>0:
|
||||||
|
lst=lenv.make_list(localshlibs)
|
||||||
|
lenv.link_local_shlib(lst)
|
||||||
|
lenv.Depends( program_list, lst )
|
||||||
|
|
||||||
|
if len(includes)>0:
|
||||||
|
lenv.KDEaddpaths_includes(includes)
|
||||||
|
if len(globallibs)>0:
|
||||||
|
lenv.KDEaddlibs(globallibs)
|
||||||
|
if len(globalcxxflags)>0:
|
||||||
|
lenv.KDEaddflags_cxx(globalcxxflags)
|
||||||
|
|
||||||
|
if not lenv.has_key('NOAUTOINSTALL'):
|
||||||
|
KDEinstall(lenv, 'KDEBIN', '', target)
|
||||||
|
return program_list
|
||||||
|
|
||||||
|
def KDEshlib(lenv, target, source, kdelib=0, libprefix='lib',
|
||||||
|
includes='', localshlibs='', globallibs='', globalcxxflags='', vnum=''):
|
||||||
|
""" Makes a shared library for kde (.la file for klibloader)
|
||||||
|
The library is installed except if one sets env['NOAUTOINSTALL'] """
|
||||||
|
src = KDEfiles(lenv, target, source)
|
||||||
|
|
||||||
|
if not lenv.has_key('nosmart_includes'):
|
||||||
|
lenv.AppendUnique(CPPPATH=['./'])
|
||||||
|
# we link the program against a shared library done locally, add the dependency
|
||||||
|
lst=[]
|
||||||
|
if len(localshlibs)>0:
|
||||||
|
lst=lenv.make_list(localshlibs)
|
||||||
|
lenv.link_local_shlib(lst)
|
||||||
|
if len(includes)>0:
|
||||||
|
lenv.KDEaddpaths_includes(includes)
|
||||||
|
if len(globallibs)>0:
|
||||||
|
lenv.KDEaddlibs(globallibs)
|
||||||
|
if len(globalcxxflags)>0:
|
||||||
|
lenv.KDEaddflags_cxx(globalcxxflags)
|
||||||
|
|
||||||
|
restype = 'KDEMODULE'
|
||||||
|
if kdelib==1:
|
||||||
|
restype = 'KDELIB'
|
||||||
|
|
||||||
|
library_list = lenv.bksys_shlib(target, src, getInstDirForResType(lenv, restype), libprefix, vnum, nodestdir=1)
|
||||||
|
if len(lst)>0: lenv.Depends( library_list, lst )
|
||||||
|
|
||||||
|
return library_list
|
||||||
|
|
||||||
|
def KDEstaticlib(lenv, target, source):
|
||||||
|
""" Makes a static library for kde - in practice you should not use static libraries
|
||||||
|
1. they take more memory than shared ones
|
||||||
|
2. makefile.am needed it because of limitations
|
||||||
|
(cannot handle sources in separate folders - takes extra processing) """
|
||||||
|
if not lenv.has_key('nosmart_includes'):
|
||||||
|
lenv.AppendUnique(CPPPATH=['./'])
|
||||||
|
src = KDEfiles(lenv, target, source)
|
||||||
|
return lenv.StaticLibrary(target, src)
|
||||||
|
# do not install static libraries by default
|
||||||
|
|
||||||
|
def KDEaddflags_cxx(lenv, fl):
|
||||||
|
""" Compilation flags for C++ programs """
|
||||||
|
lenv.AppendUnique(CXXFLAGS = lenv.make_list(fl))
|
||||||
|
|
||||||
|
def KDEaddflags_c(lenv, fl):
|
||||||
|
""" Compilation flags for C programs """
|
||||||
|
lenv.AppendUnique(CFLAGS = lenv.make_list(fl))
|
||||||
|
|
||||||
|
def KDEaddflags_link(lenv, fl):
|
||||||
|
""" Add link flags - Use this if KDEaddlibs below is not enough """
|
||||||
|
lenv.PrependUnique(LINKFLAGS = lenv.make_list(fl))
|
||||||
|
|
||||||
|
def KDEaddlibs(lenv, libs):
|
||||||
|
""" Helper function """
|
||||||
|
lenv.AppendUnique(LIBS = lenv.make_list(libs))
|
||||||
|
|
||||||
|
def KDEaddpaths_includes(lenv, paths):
|
||||||
|
""" Add new include paths """
|
||||||
|
lenv.AppendUnique(CPPPATH = lenv.make_list(paths))
|
||||||
|
|
||||||
|
def KDEaddpaths_libs(lenv, paths):
|
||||||
|
""" Add paths to libraries """
|
||||||
|
lenv.PrependUnique(LIBPATH = lenv.make_list(paths))
|
||||||
|
|
||||||
|
def KDElang(lenv, folder, appname):
|
||||||
|
""" Process translations (.po files) in a po/ dir """
|
||||||
|
transfiles = glob.glob(folder+'/*.po')
|
||||||
|
for lang in transfiles:
|
||||||
|
result = lenv.Transfiles(lang)
|
||||||
|
country = SCons.Util.splitext(result[0].name)[0]
|
||||||
|
KDEinstallas(lenv, 'KDELOCALE', country+'/LC_MESSAGES/'+appname+'.mo', result)
|
||||||
|
|
||||||
|
def KDEicon(lenv, icname='*', path='./', restype='KDEICONS', subdir=''):
|
||||||
|
"""Contributed by: "Andrey Golovizin" <grooz()gorodok()net>
|
||||||
|
modified by "Martin Ellis" <m.a.ellis()ncl()ac()uk>
|
||||||
|
|
||||||
|
Installs icons with filenames such as cr22-action-frame.png into
|
||||||
|
KDE icon hierachy with names like icons/crystalsvg/22x22/actions/frame.png.
|
||||||
|
|
||||||
|
Global KDE icons can be installed simply using env.KDEicon('name').
|
||||||
|
The second parameter, path, is optional, and specifies the icons
|
||||||
|
location in the source, relative to the SConscript file.
|
||||||
|
|
||||||
|
To install icons that need to go under an applications directory (to
|
||||||
|
avoid name conflicts, for example), use e.g.
|
||||||
|
env.KDEicon('name', './', 'KDEDATA', 'appname/icons')"""
|
||||||
|
|
||||||
|
if env.has_key('DUMPCONFIG'):
|
||||||
|
print "<icondirent subdir=\"%s\">" % (path+subdir)
|
||||||
|
return
|
||||||
|
|
||||||
|
type_dic = { 'action' : 'actions', 'app' : 'apps', 'device' :
|
||||||
|
'devices', 'filesys' : 'filesystems', 'mime' : 'mimetypes' }
|
||||||
|
dir_dic = {
|
||||||
|
'los' :'locolor/16x16',
|
||||||
|
'lom' :'locolor/32x32',
|
||||||
|
'him' :'hicolor/32x32',
|
||||||
|
'hil' :'hicolor/48x48',
|
||||||
|
'lo16' :'locolor/16x16',
|
||||||
|
'lo22' :'locolor/22x22',
|
||||||
|
'lo32' :'locolor/32x32',
|
||||||
|
'hi16' :'hicolor/16x16',
|
||||||
|
'hi22' :'hicolor/22x22',
|
||||||
|
'hi32' :'hicolor/32x32',
|
||||||
|
'hi48' :'hicolor/48x48',
|
||||||
|
'hi64' :'hicolor/64x64',
|
||||||
|
'hi128':'hicolor/128x128',
|
||||||
|
'hisc' :'hicolor/scalable',
|
||||||
|
'cr16' :'crystalsvg/16x16',
|
||||||
|
'cr22' :'crystalsvg/22x22',
|
||||||
|
'cr32' :'crystalsvg/32x32',
|
||||||
|
'cr48' :'crystalsvg/48x48',
|
||||||
|
'cr64' :'crystalsvg/64x64',
|
||||||
|
'cr128':'crystalsvg/128x128',
|
||||||
|
'crsc' :'crystalsvg/scalable'
|
||||||
|
}
|
||||||
|
|
||||||
|
iconfiles = []
|
||||||
|
for ext in "png xpm mng svg svgz".split():
|
||||||
|
files = glob.glob(path+'/'+'*-*-%s.%s' % (icname, ext))
|
||||||
|
iconfiles += files
|
||||||
|
for iconfile in iconfiles:
|
||||||
|
lst = iconfile.split('/')
|
||||||
|
filename = lst[ len(lst) - 1 ]
|
||||||
|
tmp = filename.split('-')
|
||||||
|
if len(tmp)!=3:
|
||||||
|
print RED+'WARNING: icon filename has unknown format: '+iconfile+NORMAL
|
||||||
|
continue
|
||||||
|
[icon_dir, icon_type, icon_filename]=tmp
|
||||||
|
try:
|
||||||
|
basedir=getInstDirForResType(lenv, restype)
|
||||||
|
destfile = '%s/%s/%s/%s/%s' % (basedir, subdir, dir_dic[icon_dir], type_dic[icon_type], icon_filename)
|
||||||
|
except KeyError:
|
||||||
|
print RED+'WARNING: unknown icon type: '+iconfile+NORMAL
|
||||||
|
continue
|
||||||
|
## Do not use KDEinstallas here, as parsing from an ide will be necessary
|
||||||
|
if env['_INSTALL']:
|
||||||
|
env.Alias('install', env.InstallAs( destfile, iconfile ) )
|
||||||
|
|
||||||
|
## This function uses env imported above
|
||||||
|
def docfolder(lenv, folder, lang, destination=""):
|
||||||
|
# folder is the folder to process
|
||||||
|
# lang is the language
|
||||||
|
# destination is the subdirectory in KDEDOC
|
||||||
|
docfiles = glob.glob(folder+"/???*.*") # file files that are at least 4 chars wide :)
|
||||||
|
# warn about errors
|
||||||
|
#if len(lang) != 2:
|
||||||
|
# print "error, lang must be a two-letter string, like 'en'"
|
||||||
|
|
||||||
|
# when the destination is not given, use the folder
|
||||||
|
if len(destination) == 0:
|
||||||
|
destination=folder
|
||||||
|
docbook_list = []
|
||||||
|
for file in docfiles:
|
||||||
|
# do not process folders
|
||||||
|
if not os.path.isfile(file):
|
||||||
|
continue
|
||||||
|
# do not process the cache file
|
||||||
|
if file == 'index.cache.bz2':
|
||||||
|
continue
|
||||||
|
# ignore invalid files (TODO??)
|
||||||
|
if len( SCons.Util.splitext( file ) ) <= 1 :
|
||||||
|
continue
|
||||||
|
|
||||||
|
ext = SCons.Util.splitext( file )[1]
|
||||||
|
|
||||||
|
# docbook files are processed by meinproc
|
||||||
|
if ext != '.docbook':
|
||||||
|
continue
|
||||||
|
docbook_list.append( file )
|
||||||
|
lenv.KDEinstall('KDEDOC', lang+'/'+destination, file)
|
||||||
|
# Now process the index.docbook files ..
|
||||||
|
if len(docbook_list) == 0:
|
||||||
|
return
|
||||||
|
if not os.path.isfile( folder+'/index.docbook' ):
|
||||||
|
print "Error, index.docbook was not found in "+folder+'/index.docbook'
|
||||||
|
return
|
||||||
|
## Define this to 1 if you are writing documentation else to 0 :)
|
||||||
|
if env.has_key('i_am_a_documentation_writer'):
|
||||||
|
for file in docbook_list:
|
||||||
|
lenv.Depends( folder+'index.cache.bz2', file )
|
||||||
|
lenv.Meinproc( folder+'/index.cache.bz2', folder+'/index.docbook' )
|
||||||
|
lenv.KDEinstall( 'KDEDOC', lang+'/'+destination, folder+'/index.cache.bz2' )
|
||||||
|
|
||||||
|
#valid_targets = "program shlib kioslave staticlib".split()
|
||||||
|
import generic
|
||||||
|
class kobject(generic.genobj):
|
||||||
|
def __init__(self, val, senv=None):
|
||||||
|
if senv: generic.genobj.__init__(self, val, senv)
|
||||||
|
else: generic.genobj.__init__(self, val, env)
|
||||||
|
self.iskdelib=0
|
||||||
|
def it_is_a_kdelib(self): self.iskdelib=1
|
||||||
|
def execute(self):
|
||||||
|
self.lockchdir()
|
||||||
|
if self.orenv.has_key('DUMPCONFIG'):
|
||||||
|
print self.xml()
|
||||||
|
return
|
||||||
|
if (self.type=='shlib' or self.type=='kioslave'):
|
||||||
|
install_dir = 'KDEMODULE'
|
||||||
|
if self.iskdelib==1: install_dir = 'KDELIB'
|
||||||
|
self.instdir=getInstDirForResType(self.orenv, install_dir)
|
||||||
|
self.nodestdir=1
|
||||||
|
elif self.type=='program':
|
||||||
|
self.instdir=getInstDirForResType(self.orenv, 'KDEBIN')
|
||||||
|
self.nodestdir=1
|
||||||
|
|
||||||
|
self.src=KDEfiles(env, self.target, self.source)
|
||||||
|
generic.genobj.execute(self)
|
||||||
|
self.unlockchdir()
|
||||||
|
|
||||||
|
def xml(self):
|
||||||
|
ret= '<compile type="%s" chdir="%s" target="%s" cxxflags="%s" cflags="%s" includes="%s" linkflags="%s" libpaths="%s" libs="%s" vnum="%s" iskdelib="%s" libprefix="%s">\n' % (self.type, self.chdir, self.target, self.cxxflags, self.cflags, self.includes, self.linkflags, self.libpaths, self.libs, self.vnum, self.iskdelib, self.libprefix)
|
||||||
|
if self.source:
|
||||||
|
for i in self.orenv.make_list(self.source):
|
||||||
|
ret += ' <source file="%s"/>\n' % i
|
||||||
|
ret += "</compile>"
|
||||||
|
return ret
|
||||||
|
|
||||||
|
# Attach the functions to the environment so that SConscripts can use them
|
||||||
|
SConsEnvironment.KDEprogram = KDEprogram
|
||||||
|
SConsEnvironment.KDEshlib = KDEshlib
|
||||||
|
SConsEnvironment.KDEstaticlib = KDEstaticlib
|
||||||
|
SConsEnvironment.KDEinstall = KDEinstall
|
||||||
|
SConsEnvironment.KDEinstallas = KDEinstallas
|
||||||
|
SConsEnvironment.KDElang = KDElang
|
||||||
|
SConsEnvironment.KDEicon = KDEicon
|
||||||
|
|
||||||
|
SConsEnvironment.KDEaddflags_cxx = KDEaddflags_cxx
|
||||||
|
SConsEnvironment.KDEaddflags_c = KDEaddflags_c
|
||||||
|
SConsEnvironment.KDEaddflags_link = KDEaddflags_link
|
||||||
|
SConsEnvironment.KDEaddlibs = KDEaddlibs
|
||||||
|
SConsEnvironment.KDEaddpaths_includes = KDEaddpaths_includes
|
||||||
|
SConsEnvironment.KDEaddpaths_libs = KDEaddpaths_libs
|
||||||
|
|
||||||
|
SConsEnvironment.docfolder = docfolder
|
||||||
|
SConsEnvironment.kobject = kobject
|
||||||
|
|
Binary file not shown.
@ -0,0 +1,164 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# Configure script for abakus. I think it's better than the sample that came
|
||||||
|
# with bksys. Feel free to do with it what you want.
|
||||||
|
# By Michael Pyne <michael.pyne@kdemail.net>
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
BOLD="\033[1m"
|
||||||
|
RED="\033[91m"
|
||||||
|
GREEN="\033[92m"
|
||||||
|
YELLOW="\033[93m"
|
||||||
|
CYAN="\033[96m"
|
||||||
|
NORMAL="\033[0m"
|
||||||
|
|
||||||
|
PROGRAM_NAME='aa.kss'
|
||||||
|
|
||||||
|
# First let's see if they asked for help.
|
||||||
|
if '--help' in sys.argv:
|
||||||
|
print '''This is a configure script to prepare %s for building.
|
||||||
|
|
||||||
|
You can pass the command line argument debug=1 to enable debugging for the
|
||||||
|
application, which can be useful if you have problems.
|
||||||
|
|
||||||
|
Otherwise, just run ./configure, and if you don't already have scons, a mini
|
||||||
|
version will be installed suitable for building %s.
|
||||||
|
'''.replace('%s', PROGRAM_NAME)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# Check that we have the minimum version of Python needs to run SCons.
|
||||||
|
if sys.hexversion < 0x02030000:
|
||||||
|
# Use regexp for compatibility with ancient Python
|
||||||
|
version = re.split(' ', sys.version)[0]
|
||||||
|
|
||||||
|
print RED + 'Sorry, your version of Python is too old.' + NORMAL
|
||||||
|
print PROGRAM_NAME + ' requires Python 2.3 or greater to build.'
|
||||||
|
print "\nYou have Python " + version
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Check if scons is installed. We can use cool Python features now that we
|
||||||
|
# know we aren't using an ancient version of Python.
|
||||||
|
result = os.system('scons -v > /dev/null 2>&1')
|
||||||
|
scons = 'scons'
|
||||||
|
|
||||||
|
if os.WEXITSTATUS(result) == 0:
|
||||||
|
print GREEN + "scons already installed." + NORMAL
|
||||||
|
else:
|
||||||
|
# If we didn't find scons, don't whine to the user about it, just fix it.
|
||||||
|
print YELLOW + 'scons not installed, installing local copy.' + NORMAL
|
||||||
|
|
||||||
|
# Split this into two steps since some tars don't use j to mean bzip2
|
||||||
|
# compressed.
|
||||||
|
result = os.system('bzcat admin/scons-mini.tar.bz2 | tar x')
|
||||||
|
|
||||||
|
if os.WEXITSTATUS(result) != 0:
|
||||||
|
print RED + 'Unable to extract scons' + NORMAL
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
scons = '%s/scons' % os.getcwd()
|
||||||
|
|
||||||
|
# Now we now where scons is. Let's create a Makefile (after we configure) so
|
||||||
|
# that all the user has to do is type 'make'. Allow the user to pass command
|
||||||
|
# line arguments, which will be passed to the configure process.
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
options = ''
|
||||||
|
else:
|
||||||
|
options = " ".join(sys.argv[1:])
|
||||||
|
# reduce is pretty cool
|
||||||
|
# options = reduce(lambda x, y: x + '\n' + y, sys.argv[1:])
|
||||||
|
|
||||||
|
result = os.system(scons + ' configure ' + options)
|
||||||
|
if os.WEXITSTATUS(result) != 0:
|
||||||
|
print RED + 'Unable to configure scons' + NORMAL
|
||||||
|
sys.exit(3)
|
||||||
|
|
||||||
|
# Recursive generates a makefile for a directory. If topDir is True, the
|
||||||
|
# Makefile is slightly different.
|
||||||
|
def generate_makefile(dir, topDir = False):
|
||||||
|
|
||||||
|
file = name + "/Makefile"
|
||||||
|
|
||||||
|
# Write out Makefile.
|
||||||
|
try:
|
||||||
|
makefile = open(file, 'w')
|
||||||
|
except IOError:
|
||||||
|
print RED + "Unable to open " + file + NORMAL
|
||||||
|
sys.exit(4)
|
||||||
|
|
||||||
|
text = '''
|
||||||
|
## Makefile automatically generated by configure
|
||||||
|
|
||||||
|
SCONS=$scons
|
||||||
|
|
||||||
|
# $scons : compile
|
||||||
|
# $scons -c : clean
|
||||||
|
# $scons install : install
|
||||||
|
# $scons -c install : uninstall and clean
|
||||||
|
|
||||||
|
# Default target: use scons to build the program
|
||||||
|
all:
|
||||||
|
@$(SCONS) -Q
|
||||||
|
|
||||||
|
# Debugging possibilies:
|
||||||
|
# $scons --debug=explain, $scons --debug=tree
|
||||||
|
|
||||||
|
# To optimize the runtime:
|
||||||
|
# $scons --max-drift=1 --implicit-deps-unchanged
|
||||||
|
debug:
|
||||||
|
@$(SCONS) -Q --debug=tree
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@$(SCONS) -c
|
||||||
|
|
||||||
|
install:
|
||||||
|
@$(SCONS) install
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
@$(SCONS) uninstall
|
||||||
|
|
||||||
|
# This target creates a tarball of the project (in theory)
|
||||||
|
dist:
|
||||||
|
@$(SCONS) dist
|
||||||
|
'''
|
||||||
|
|
||||||
|
if topDir:
|
||||||
|
text = text.replace('$scons', scons)
|
||||||
|
else:
|
||||||
|
text = text.replace('$scons', scons + ' -u')
|
||||||
|
|
||||||
|
try:
|
||||||
|
print "Generating " + GREEN + file + NORMAL
|
||||||
|
makefile.write(text)
|
||||||
|
makefile.close()
|
||||||
|
except IOError:
|
||||||
|
print RED + "Unable to write to the Makefile!" + NORMAL
|
||||||
|
sys.exit(5)
|
||||||
|
|
||||||
|
# Recursively generate Makefiles for convienience.
|
||||||
|
for name, dirs, files in os.walk('.'):
|
||||||
|
# Don't try to build hidden directories.
|
||||||
|
remove = filter(lambda x: x[0] == '.', dirs)
|
||||||
|
for i in remove:
|
||||||
|
dirs.remove(i)
|
||||||
|
|
||||||
|
if 'SConstruct' in files:
|
||||||
|
# We're in the very top directory.
|
||||||
|
generate_makefile(name, topDir = True)
|
||||||
|
|
||||||
|
for dir in ['cache', 'admin']:
|
||||||
|
if dir in dirs:
|
||||||
|
dirs.remove(dir)
|
||||||
|
elif 'SConscript' in files:
|
||||||
|
generate_makefile(name)
|
||||||
|
|
||||||
|
# The Makefile has been written, we're pretty much done.
|
||||||
|
message = '''
|
||||||
|
The Makefile(s) have been generated. Type:
|
||||||
|
`make' to build %s, and
|
||||||
|
`make install' to install %s.
|
||||||
|
'''.replace('%s', PROGRAM_NAME)
|
||||||
|
|
||||||
|
print GREEN + message + NORMAL
|
@ -0,0 +1,4 @@
|
|||||||
|
File=asciiquarium.kcfg
|
||||||
|
ClassName=AASaverConfig
|
||||||
|
Singleton=true
|
||||||
|
Mutators=true
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,44 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
## This script demonstrates how to build and install
|
||||||
|
## a simple kde program having KconfigXT settings
|
||||||
|
## with scons
|
||||||
|
##
|
||||||
|
## Thomas Nagy, 2004, 2005
|
||||||
|
|
||||||
|
## This file can be reused freely for any project (see COPYING)
|
||||||
|
|
||||||
|
############################
|
||||||
|
## load the config
|
||||||
|
|
||||||
|
## Use the environment and the tools set in the top-level
|
||||||
|
## SConstruct file (set with 'Export') - this is very important
|
||||||
|
|
||||||
|
Import( 'env' )
|
||||||
|
myenv=env.Copy()
|
||||||
|
|
||||||
|
#############################
|
||||||
|
## the programs to build
|
||||||
|
|
||||||
|
# The sources for our program - only .ui, .skel and .cpp are accepted
|
||||||
|
aa_sources = """
|
||||||
|
aasaver.cpp
|
||||||
|
screen.cpp
|
||||||
|
frame.cpp
|
||||||
|
sprite.cpp
|
||||||
|
AASaverConfig.kcfgc
|
||||||
|
settingswidget.ui
|
||||||
|
"""
|
||||||
|
|
||||||
|
myenv.KDEprogram( "asciiquarium.kss", aa_sources )
|
||||||
|
|
||||||
|
############################
|
||||||
|
## Customization
|
||||||
|
|
||||||
|
## Additional include paths for compiling the source files
|
||||||
|
## Always add '../' (top-level directory) because moc makes code that needs it
|
||||||
|
myenv.KDEaddpaths_includes('#/src/ #/')
|
||||||
|
|
||||||
|
## Necessary libraries to link against
|
||||||
|
myenv.KDEaddlibs( 'qt-mt kdecore kdeui kscreensaver' )
|
||||||
|
myenv.KDEinstall('KDEAPPS', 'System/ScreenSavers', 'asciiquarium.desktop')
|
||||||
|
myenv.KDEinstall('KDEKCFG', '', 'asciiquarium.kcfg')
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,199 @@
|
|||||||
|
/*
|
||||||
|
* Asciiquarium - Native KDE Screensaver based on the Asciiquarium program
|
||||||
|
* (c) Kirk Baucom <kbaucom@schizoid.com>, which you can find at
|
||||||
|
* http://www.robobunny.com/projects/asciiquarium/
|
||||||
|
*
|
||||||
|
* Ported to KDE by Maksim Orlovich <maksim@kde.org> and
|
||||||
|
* Michael Pyne <michael.pyne@kdemail.net>.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003 Kirk Baucom <kbaucom@schizoid.com>
|
||||||
|
* Copyright (c) 2005 Maksim Orlovich <maksim@kde.org>
|
||||||
|
* Copyright (c) 2005 Michael Pyne <michael.pyne@kdemail.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AA_AASAVER_H
|
||||||
|
#define AA_AASAVER_H
|
||||||
|
|
||||||
|
#include <kscreensaver.h>
|
||||||
|
#include <kapplication.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
class Screen;
|
||||||
|
class Sprite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \mainpage Asciiquarium.
|
||||||
|
*
|
||||||
|
* \section intro Introduction
|
||||||
|
*
|
||||||
|
* Asciiquarium is a KDE screensaver to draw an ASCII art aquarium. This is the
|
||||||
|
* documentation of the API used in the program to generate the effect. It should
|
||||||
|
* be fairly simple, but basically:
|
||||||
|
*
|
||||||
|
* class AASaver is the main class, which handles outside events. All of the
|
||||||
|
* processing happens in the Screen class however, which manages a list of
|
||||||
|
* Sprites, updating them and drawing them as needed. When AASaver receives a
|
||||||
|
* paintEvent(), it forwards it on to Screen to handle it.
|
||||||
|
*
|
||||||
|
* Each Sprite is composed of 1 or more Frames. When a Screen wants a Sprite
|
||||||
|
* to draw itself, the Sprite forwards the request to its currently shown Frame.
|
||||||
|
*
|
||||||
|
* The Frame is rectangular, and created from textual ASCII art, with a ASCII
|
||||||
|
* art shape and color mask. The mask is optional. See aasaver.cpp for
|
||||||
|
* examples for creating a Frame.
|
||||||
|
*
|
||||||
|
* The Frame supports transparency and colors, and will convert the textual data
|
||||||
|
* into a QPixmap representation on demand in order to reduce CPU load (at the
|
||||||
|
* expense of a slight memory usage increase for each sprite).
|
||||||
|
*
|
||||||
|
* Screen handles the timing for the project, and at each timeout will call
|
||||||
|
* Sprite::tickUpdate() from Screen::doAnimate().
|
||||||
|
*
|
||||||
|
* This whole program was inspired/copied from Kirk Baucom's asciiquarium
|
||||||
|
* program, from http://www.robobunny.com/projects/asciiquarium/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main class for the Asciiquarium screensaver.
|
||||||
|
*/
|
||||||
|
class AASaver: public KScreenSaver
|
||||||
|
{
|
||||||
|
/// Handles the animation and drawing.
|
||||||
|
Screen* screen;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Construct the screensaver with window id \p id.
|
||||||
|
AASaver( WId id );
|
||||||
|
|
||||||
|
/// Returns a random double between [0.0, limit).
|
||||||
|
static double doubleRand(double limit)
|
||||||
|
{
|
||||||
|
return (limit * (static_cast<double>(KApplication::random()) / RAND_MAX));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a random integer between [0, limit)
|
||||||
|
static int intRand(int limit)
|
||||||
|
{
|
||||||
|
return KApplication::random() % limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a QString holding a color mask, created by choosing random colors
|
||||||
|
* to replace numbers in \p color_mask.
|
||||||
|
*/
|
||||||
|
static QString randColor(QString color_mask);
|
||||||
|
|
||||||
|
/// Adds the castle sprite to the screen.
|
||||||
|
void addCastle();
|
||||||
|
|
||||||
|
/// Adds the environment (sea, etc.) to the screen.
|
||||||
|
void addEnvironment();
|
||||||
|
|
||||||
|
/// Adds the seaweed to the screen.
|
||||||
|
void addAllSeaweed();
|
||||||
|
|
||||||
|
/// Adds the initial layout of fish to the sea, scaling the number of fish
|
||||||
|
/// based on the current screen size.
|
||||||
|
void addAllFish();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a seaweed to a random position of the sea bottom.
|
||||||
|
*
|
||||||
|
* @param screen The Screen to add into.
|
||||||
|
*/
|
||||||
|
static void addSeaweed(Screen* screen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new fish sprite, which has not yet been added to a screen.
|
||||||
|
*
|
||||||
|
* @param screen The Screen to use when constructing the Sprite.
|
||||||
|
* @todo Combine with addFish().
|
||||||
|
*/
|
||||||
|
static Sprite *newFish(Screen *screen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new fish sprite to \p screen.
|
||||||
|
*
|
||||||
|
* @param screen The Screen to add a fish to.
|
||||||
|
*/
|
||||||
|
static void addFish(Screen *screen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new air bubble sprite to \p screen. The \p x, \p y, and \p z
|
||||||
|
* coordinates are all in logical coordinates.
|
||||||
|
*
|
||||||
|
* @param screen The Screen to add the bubble to.
|
||||||
|
* @param x The x position to start the bubble at.
|
||||||
|
* @param y The y position to start the bubble at.
|
||||||
|
* @param z The z position to start the bubble at.
|
||||||
|
*/
|
||||||
|
static void addBubble(Screen* screen, int x, int y, int z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a Nessie, the Loch Ness Monster sprite to \p screen.
|
||||||
|
*
|
||||||
|
* @param screen The Screen to add Nessie to.
|
||||||
|
*/
|
||||||
|
static void addNessie(Screen* screen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a big fish sprite to \p screen.
|
||||||
|
*
|
||||||
|
* @param screen The Screen to add the big fish to.
|
||||||
|
*/
|
||||||
|
static void addBigFish(Screen* screen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a whale sprite to \p screen.
|
||||||
|
*
|
||||||
|
* @param screen The Screen to add the whale to.
|
||||||
|
*/
|
||||||
|
static void addWhale(Screen* screen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a shark sprite to \p screen. The shark can kill() fish it comes in
|
||||||
|
* contact with (they will spawn more fish automatically).
|
||||||
|
*
|
||||||
|
* @param screen The Screen to add the shark to.
|
||||||
|
*/
|
||||||
|
static void addShark(Screen* screen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a ship sprite to \p screen.
|
||||||
|
*
|
||||||
|
* @param screen The Screen to add the ship to.
|
||||||
|
*/
|
||||||
|
static void addShip(Screen* screen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a random object from the set (Shark, Big Fish, Nessie, Whale, Ship)
|
||||||
|
* to the sea.
|
||||||
|
*
|
||||||
|
* @param screen The Screen to add to.
|
||||||
|
*/
|
||||||
|
static void addRandom(Screen* screen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reimplemented to update the widget when it gets dirty.
|
||||||
|
*/
|
||||||
|
virtual void paintEvent(QPaintEvent* pe);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* AA_AASAVER_H */
|
||||||
|
|
||||||
|
// vim: set et ts=8 sw=4:
|
@ -0,0 +1,23 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Encoding=UTF-8
|
||||||
|
Exec=asciiquarium.kss
|
||||||
|
Icon=kscreensaver
|
||||||
|
Type=Application
|
||||||
|
Actions=InWindow;Root;Setup
|
||||||
|
Name=Asciiquarium
|
||||||
|
X-KDE-Category=Miscellaneous
|
||||||
|
|
||||||
|
[Desktop Action InWindow]
|
||||||
|
Exec=asciiquarium.kss -window-id %w
|
||||||
|
Name=Display in specified window
|
||||||
|
NoDisplay=true
|
||||||
|
|
||||||
|
[Desktop Action Root]
|
||||||
|
Exec=asciiquarium.kss -root
|
||||||
|
Name=Display in root window
|
||||||
|
NoDisplay=true
|
||||||
|
|
||||||
|
[Desktop Action Setup]
|
||||||
|
Exec=asciiquarium.kss -setup
|
||||||
|
Name=Display setup dialog
|
||||||
|
NoDisplay=true
|
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE kcfg SYSTEM "http://www.kde.org/standards/kcfg/1.0/kcfg.dtd">
|
||||||
|
<kcfg>
|
||||||
|
<kcfgfile name="asciiquariumrc"/>
|
||||||
|
<group name="Settings">
|
||||||
|
<entry name="fishCount" type="Int">
|
||||||
|
<label>Amount of fish to have in the sea.</label>
|
||||||
|
<default>20</default>
|
||||||
|
<whatsthis>You can use this value to select the number of fish that will be
|
||||||
|
on screen at a given time.</whatsthis>
|
||||||
|
</entry>
|
||||||
|
</group>
|
||||||
|
</kcfg>
|
||||||
|
<!-- vim: set noet ts=4: -->
|
@ -0,0 +1,309 @@
|
|||||||
|
BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
|
||||||
|
font-family: sans-serif, Geneva, Arial, Helvetica;
|
||||||
|
}
|
||||||
|
BODY,TD {
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
H1 {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 160%;
|
||||||
|
}
|
||||||
|
H2 {
|
||||||
|
font-size: 120%;
|
||||||
|
}
|
||||||
|
H3 {
|
||||||
|
font-size: 110%;
|
||||||
|
}
|
||||||
|
CAPTION { font-weight: bold }
|
||||||
|
DIV.qindex {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #eeeeff;
|
||||||
|
border: 1px solid #b0b0b0;
|
||||||
|
text-align: center;
|
||||||
|
margin: 2px;
|
||||||
|
padding: 2px;
|
||||||
|
line-height: 140%;
|
||||||
|
}
|
||||||
|
DIV.nav {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #eeeeff;
|
||||||
|
border: 1px solid #b0b0b0;
|
||||||
|
text-align: center;
|
||||||
|
margin: 2px;
|
||||||
|
padding: 2px;
|
||||||
|
line-height: 140%;
|
||||||
|
}
|
||||||
|
DIV.navtab {
|
||||||
|
background-color: #eeeeff;
|
||||||
|
border: 1px solid #b0b0b0;
|
||||||
|
text-align: center;
|
||||||
|
margin: 2px;
|
||||||
|
margin-right: 15px;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
TD.navtab {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
A.qindex {
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #1A419D;
|
||||||
|
}
|
||||||
|
A.qindex:visited {
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #1A419D
|
||||||
|
}
|
||||||
|
A.qindex:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #ddddff;
|
||||||
|
}
|
||||||
|
A.qindexHL {
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
background-color: #6666cc;
|
||||||
|
color: #ffffff;
|
||||||
|
border: 1px double #9295C2;
|
||||||
|
}
|
||||||
|
A.qindexHL:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #6666cc;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }
|
||||||
|
A.el { text-decoration: none; font-weight: bold }
|
||||||
|
A.elRef { font-weight: bold }
|
||||||
|
A.code:link { text-decoration: none; font-weight: normal; color: #0000FF}
|
||||||
|
A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}
|
||||||
|
A.codeRef:link { font-weight: normal; color: #0000FF}
|
||||||
|
A.codeRef:visited { font-weight: normal; color: #0000FF}
|
||||||
|
A:hover { text-decoration: none; background-color: #f2f2ff }
|
||||||
|
DL.el { margin-left: -1cm }
|
||||||
|
.fragment {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 105%;
|
||||||
|
}
|
||||||
|
PRE.fragment {
|
||||||
|
border: 1px solid #CCCCCC;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
margin-top: 4px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
margin-left: 2px;
|
||||||
|
margin-right: 8px;
|
||||||
|
padding-left: 6px;
|
||||||
|
padding-right: 6px;
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
}
|
||||||
|
DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
|
||||||
|
TD.md { background-color: #F4F4FB; font-weight: bold; }
|
||||||
|
TD.mdPrefix {
|
||||||
|
background-color: #F4F4FB;
|
||||||
|
color: #606060;
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
TD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; }
|
||||||
|
TD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; }
|
||||||
|
DIV.groupHeader {
|
||||||
|
margin-left: 16px;
|
||||||
|
margin-top: 12px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
DIV.groupText { margin-left: 16px; font-style: italic; font-size: 95% }
|
||||||
|
BODY {
|
||||||
|
background: white;
|
||||||
|
color: black;
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
TD.indexkey {
|
||||||
|
background-color: #eeeeff;
|
||||||
|
font-weight: bold;
|
||||||
|
padding-right : 10px;
|
||||||
|
padding-top : 2px;
|
||||||
|
padding-left : 10px;
|
||||||
|
padding-bottom : 2px;
|
||||||
|
margin-left : 0px;
|
||||||
|
margin-right : 0px;
|
||||||
|
margin-top : 2px;
|
||||||
|
margin-bottom : 2px;
|
||||||
|
border: 1px solid #CCCCCC;
|
||||||
|
}
|
||||||
|
TD.indexvalue {
|
||||||
|
background-color: #eeeeff;
|
||||||
|
font-style: italic;
|
||||||
|
padding-right : 10px;
|
||||||
|
padding-top : 2px;
|
||||||
|
padding-left : 10px;
|
||||||
|
padding-bottom : 2px;
|
||||||
|
margin-left : 0px;
|
||||||
|
margin-right : 0px;
|
||||||
|
margin-top : 2px;
|
||||||
|
margin-bottom : 2px;
|
||||||
|
border: 1px solid #CCCCCC;
|
||||||
|
}
|
||||||
|
TR.memlist {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
P.formulaDsp { text-align: center; }
|
||||||
|
IMG.formulaDsp { }
|
||||||
|
IMG.formulaInl { vertical-align: middle; }
|
||||||
|
SPAN.keyword { color: #008000 }
|
||||||
|
SPAN.keywordtype { color: #604020 }
|
||||||
|
SPAN.keywordflow { color: #e08000 }
|
||||||
|
SPAN.comment { color: #800000 }
|
||||||
|
SPAN.preprocessor { color: #806020 }
|
||||||
|
SPAN.stringliteral { color: #002080 }
|
||||||
|
SPAN.charliteral { color: #008080 }
|
||||||
|
.mdTable {
|
||||||
|
border: 1px solid #868686;
|
||||||
|
background-color: #F4F4FB;
|
||||||
|
}
|
||||||
|
.mdRow {
|
||||||
|
padding: 8px 10px;
|
||||||
|
}
|
||||||
|
.mdescLeft {
|
||||||
|
padding: 0px 8px 4px 8px;
|
||||||
|
font-size: 80%;
|
||||||
|
font-style: italic;
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
border-top: 1px none #E0E0E0;
|
||||||
|
border-right: 1px none #E0E0E0;
|
||||||
|
border-bottom: 1px none #E0E0E0;
|
||||||
|
border-left: 1px none #E0E0E0;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
.mdescRight {
|
||||||
|
padding: 0px 8px 4px 8px;
|
||||||
|
font-size: 80%;
|
||||||
|
font-style: italic;
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
border-top: 1px none #E0E0E0;
|
||||||
|
border-right: 1px none #E0E0E0;
|
||||||
|
border-bottom: 1px none #E0E0E0;
|
||||||
|
border-left: 1px none #E0E0E0;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
.memItemLeft {
|
||||||
|
padding: 1px 0px 0px 8px;
|
||||||
|
margin: 4px;
|
||||||
|
border-top-width: 1px;
|
||||||
|
border-right-width: 1px;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-left-width: 1px;
|
||||||
|
border-top-color: #E0E0E0;
|
||||||
|
border-right-color: #E0E0E0;
|
||||||
|
border-bottom-color: #E0E0E0;
|
||||||
|
border-left-color: #E0E0E0;
|
||||||
|
border-top-style: solid;
|
||||||
|
border-right-style: none;
|
||||||
|
border-bottom-style: none;
|
||||||
|
border-left-style: none;
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
.memItemRight {
|
||||||
|
padding: 1px 8px 0px 8px;
|
||||||
|
margin: 4px;
|
||||||
|
border-top-width: 1px;
|
||||||
|
border-right-width: 1px;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-left-width: 1px;
|
||||||
|
border-top-color: #E0E0E0;
|
||||||
|
border-right-color: #E0E0E0;
|
||||||
|
border-bottom-color: #E0E0E0;
|
||||||
|
border-left-color: #E0E0E0;
|
||||||
|
border-top-style: solid;
|
||||||
|
border-right-style: none;
|
||||||
|
border-bottom-style: none;
|
||||||
|
border-left-style: none;
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
.memTemplItemLeft {
|
||||||
|
padding: 1px 0px 0px 8px;
|
||||||
|
margin: 4px;
|
||||||
|
border-top-width: 1px;
|
||||||
|
border-right-width: 1px;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-left-width: 1px;
|
||||||
|
border-top-color: #E0E0E0;
|
||||||
|
border-right-color: #E0E0E0;
|
||||||
|
border-bottom-color: #E0E0E0;
|
||||||
|
border-left-color: #E0E0E0;
|
||||||
|
border-top-style: none;
|
||||||
|
border-right-style: none;
|
||||||
|
border-bottom-style: none;
|
||||||
|
border-left-style: none;
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
.memTemplItemRight {
|
||||||
|
padding: 1px 8px 0px 8px;
|
||||||
|
margin: 4px;
|
||||||
|
border-top-width: 1px;
|
||||||
|
border-right-width: 1px;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-left-width: 1px;
|
||||||
|
border-top-color: #E0E0E0;
|
||||||
|
border-right-color: #E0E0E0;
|
||||||
|
border-bottom-color: #E0E0E0;
|
||||||
|
border-left-color: #E0E0E0;
|
||||||
|
border-top-style: none;
|
||||||
|
border-right-style: none;
|
||||||
|
border-bottom-style: none;
|
||||||
|
border-left-style: none;
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
.memTemplParams {
|
||||||
|
padding: 1px 0px 0px 8px;
|
||||||
|
margin: 4px;
|
||||||
|
border-top-width: 1px;
|
||||||
|
border-right-width: 1px;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-left-width: 1px;
|
||||||
|
border-top-color: #E0E0E0;
|
||||||
|
border-right-color: #E0E0E0;
|
||||||
|
border-bottom-color: #E0E0E0;
|
||||||
|
border-left-color: #E0E0E0;
|
||||||
|
border-top-style: solid;
|
||||||
|
border-right-style: none;
|
||||||
|
border-bottom-style: none;
|
||||||
|
border-left-style: none;
|
||||||
|
color: #606060;
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
.search { color: #003399;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
FORM.search {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
INPUT.search { font-size: 75%;
|
||||||
|
color: #000080;
|
||||||
|
font-weight: normal;
|
||||||
|
background-color: #eeeeff;
|
||||||
|
}
|
||||||
|
TD.tiny { font-size: 75%;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #252E78;
|
||||||
|
}
|
||||||
|
a:visited {
|
||||||
|
color: #3D2185;
|
||||||
|
}
|
||||||
|
.dirtab { padding: 4px;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border: 1px solid #b0b0b0;
|
||||||
|
}
|
||||||
|
TH.dirtab { background: #eeeeff;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
HR { height: 1px;
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid black;
|
||||||
|
}
|
@ -0,0 +1,204 @@
|
|||||||
|
/*
|
||||||
|
* Asciiquarium - Native KDE Screensaver based on the Asciiquarium program
|
||||||
|
* (c) Kirk Baucom <kbaucom@schizoid.com>, which you can find at
|
||||||
|
* http://www.robobunny.com/projects/asciiquarium/
|
||||||
|
*
|
||||||
|
* Ported to KDE by Maksim Orlovich <maksim@kde.org> and
|
||||||
|
* Michael Pyne <michael.pyne@kdemail.net>.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003 Kirk Baucom <kbaucom@schizoid.com>
|
||||||
|
* Copyright (c) 2005 Maksim Orlovich <maksim@kde.org>
|
||||||
|
* Copyright (c) 2005 Michael Pyne <michael.pyne@kdemail.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kglobalsettings.h>
|
||||||
|
#include <kdebug.h>
|
||||||
|
|
||||||
|
#include <qvaluevector.h>
|
||||||
|
#include <qstringlist.h>
|
||||||
|
#include <qimage.h>
|
||||||
|
#include <qfontmetrics.h>
|
||||||
|
#include <qpainter.h>
|
||||||
|
#include <qbitmap.h>
|
||||||
|
|
||||||
|
#include "frame.h"
|
||||||
|
|
||||||
|
void Frame::convertDataToPixmap(const Screen *screen)
|
||||||
|
{
|
||||||
|
if(!height() || !width()) {
|
||||||
|
// Assume we're not ready to go.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int w = screen->cellWidth(), h = screen->cellHeight();
|
||||||
|
QPixmap pix(width() * w, height() * h);
|
||||||
|
pix.fill();
|
||||||
|
|
||||||
|
QBitmap mask(pix.size(), true);
|
||||||
|
|
||||||
|
QPainter p, p2;
|
||||||
|
|
||||||
|
p.begin(&pix, true);
|
||||||
|
p2.begin(&mask, true);
|
||||||
|
|
||||||
|
p.setFont(KGlobalSettings::fixedFont());
|
||||||
|
QFontMetrics fm(p.font());
|
||||||
|
int leadHeight = fm.leading() + fm.descent();
|
||||||
|
|
||||||
|
for(unsigned j = 0; j < m_data.count(); ++j) {
|
||||||
|
QValueVector<Screen::Pixel> row = m_data[j];
|
||||||
|
if(row.isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
unsigned first, last;
|
||||||
|
for (first = 0; first < row.count() && row[first].letter == ' '; ++first)
|
||||||
|
;
|
||||||
|
|
||||||
|
last = row.count() - 1; // Assume the end is already stripped.
|
||||||
|
|
||||||
|
for(unsigned i = first; i <= last; ++i) {
|
||||||
|
if(row[i].letter == m_transparentChar)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
p2.fillRect(i * w, j * h, w, h, Qt::color1);
|
||||||
|
|
||||||
|
p.setPen(row[i].color);
|
||||||
|
p.fillRect(i * w, j * h, w, h, Qt::black);
|
||||||
|
p.drawText(i * w, j * h + (h - 1 - leadHeight), QChar(row[i].letter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pix.setMask(mask);
|
||||||
|
|
||||||
|
QPixmap erase(pix);
|
||||||
|
erase.fill(Qt::black);
|
||||||
|
erase.setMask(mask);
|
||||||
|
|
||||||
|
m_pixmap = pix;
|
||||||
|
m_erasePixmap = erase;
|
||||||
|
|
||||||
|
// Clear m_data to save a wee bit of memory.
|
||||||
|
m_data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Frame::Frame (QString text, QString mask, QRgb defaultColor, QChar transparent)
|
||||||
|
{
|
||||||
|
//First, process the pixels.
|
||||||
|
|
||||||
|
QStringList rows = QStringList::split('\n', text, true);
|
||||||
|
m_height = rows.size();
|
||||||
|
m_width = 0;
|
||||||
|
m_transparentChar = transparent;
|
||||||
|
|
||||||
|
for (QStringList::iterator i = rows.begin(); i != rows.end(); ++i)
|
||||||
|
{
|
||||||
|
QValueVector<Screen::Pixel> row;
|
||||||
|
for (int pos = 0; pos < (*i).length(); ++pos)
|
||||||
|
{
|
||||||
|
Screen::Pixel p;
|
||||||
|
p.letter = (*i).at(pos).unicode();
|
||||||
|
p.color = defaultColor;
|
||||||
|
row.append(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_width = QMAX(m_width, row.size());
|
||||||
|
m_data.append(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Now, the colors.
|
||||||
|
QStringList cols = QStringList::split('\n', mask, true);
|
||||||
|
int y = 0;
|
||||||
|
for (QStringList::iterator i = cols.begin(); i != cols.end(); ++i)
|
||||||
|
{
|
||||||
|
if (y >= m_data.size())
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (int pos = 0; pos < (*i).length() && pos < m_data[y].size(); ++pos)
|
||||||
|
{
|
||||||
|
switch ((*i).at(pos).unicode())
|
||||||
|
{
|
||||||
|
//Colors stolen from konsole, TEWidget.cpp
|
||||||
|
case 'R':
|
||||||
|
m_data[y][pos].color = 0xFF5454;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
m_data[y][pos].color = 0xB21818;
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
m_data[y][pos].color = 0x54FFFF;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
m_data[y][pos].color = 0x18B2B2;
|
||||||
|
break;
|
||||||
|
case 'Y':
|
||||||
|
m_data[y][pos].color = 0xFFFF54;
|
||||||
|
break;
|
||||||
|
case 'y':
|
||||||
|
m_data[y][pos].color = 0xB26818;
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
m_data[y][pos].color = 0x54FF54;
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
m_data[y][pos].color = 0x18B218;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
m_data[y][pos].color = 0x5454FF;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
m_data[y][pos].color = 0x1818B2;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
m_data[y][pos].color = 0xFF54FF;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
m_data[y][pos].color = 0xB218B2;
|
||||||
|
break;
|
||||||
|
case 'W':
|
||||||
|
m_data[y][pos].color = 0xFFFFFF;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
m_data[y][pos].color = 0xB2B2B2;
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qDebug("dunno about color code:'%c'", (*i).at(pos).unicode());
|
||||||
|
m_data[y][pos].color = 0xFFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Frame::paint(Screen* scr, int x, int y)
|
||||||
|
{
|
||||||
|
if(m_pixmap.isNull())
|
||||||
|
convertDataToPixmap(scr);
|
||||||
|
|
||||||
|
scr->updateSpan(x, y, m_pixmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Frame::erase(Screen* scr, int x, int y)
|
||||||
|
{
|
||||||
|
if(m_erasePixmap.isNull())
|
||||||
|
convertDataToPixmap(scr);
|
||||||
|
|
||||||
|
scr->clearSpan(x, y, m_erasePixmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: set et ts=8 sw=4:
|
@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
* Asciiquarium - Native KDE Screensaver based on the Asciiquarium program
|
||||||
|
* (c) Kirk Baucom <kbaucom@schizoid.com>, which you can find at
|
||||||
|
* http://www.robobunny.com/projects/asciiquarium/
|
||||||
|
*
|
||||||
|
* Ported to KDE by Maksim Orlovich <maksim@kde.org> and
|
||||||
|
* Michael Pyne <michael.pyne@kdemail.net>.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003 Kirk Baucom <kbaucom@schizoid.com>
|
||||||
|
* Copyright (c) 2005 Maksim Orlovich <maksim@kde.org>
|
||||||
|
* Copyright (c) 2005 Michael Pyne <michael.pyne@kdemail.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AA_FRAME_H
|
||||||
|
#define AA_FRAME_H
|
||||||
|
|
||||||
|
#include <qstring.h>
|
||||||
|
#include <qvaluevector.h>
|
||||||
|
#include <qpixmap.h>
|
||||||
|
#include "screen.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a single frame of a sprite's animation.
|
||||||
|
*
|
||||||
|
* @see Sprite
|
||||||
|
*/
|
||||||
|
class Frame
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Two-dimensional array of Pixels, which represent the appearance of this
|
||||||
|
* frame. This is used to create m_pixmap and m_erasePixmap when they are
|
||||||
|
* needed.
|
||||||
|
*
|
||||||
|
* @see Pixel
|
||||||
|
*/
|
||||||
|
QValueVector<QValueVector<Screen::Pixel> > m_data;
|
||||||
|
|
||||||
|
/// Masked pixmap of the animation frame. Created by convertDataToPixmap().
|
||||||
|
QPixmap m_pixmap;
|
||||||
|
|
||||||
|
/// Masked pixmap used to clear frame. Created by convertDataToPixmap().
|
||||||
|
QPixmap m_erasePixmap;
|
||||||
|
|
||||||
|
/// Height of this frame of animation in logical coordinates.
|
||||||
|
int m_height;
|
||||||
|
|
||||||
|
/// Width of this frame of animation in logical coordinates.
|
||||||
|
int m_width;
|
||||||
|
|
||||||
|
/// Character to be used as a special 'transparent' character. Normally is
|
||||||
|
/// the '?' character.
|
||||||
|
QChar m_transparentChar;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an empty animation Frame. Do not insert this into a Sprite.
|
||||||
|
*/
|
||||||
|
Frame() : m_height(0), m_width(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an animation frame.
|
||||||
|
*
|
||||||
|
* @param text Newline-separated text used to construct the Pixel arrays.
|
||||||
|
* The lines do not have to be equal length, any extra needed
|
||||||
|
* characters will automatically be filled with transparency.
|
||||||
|
* Any whitespace at the beginning of a line is converted to
|
||||||
|
* transparency as well.
|
||||||
|
*
|
||||||
|
* @param mask Newline-separated text used to mask \p text's colors. This
|
||||||
|
* can be empty or null in which case no masking is performed.
|
||||||
|
* However, if present, there should be the same number of
|
||||||
|
* lines in \p mask as in \p text, although individual lines
|
||||||
|
* can be shorter or empty as convienient. You can use letters
|
||||||
|
* to stand for colors, e.g. 'r' will make the letter in \p
|
||||||
|
* text at the same position dark red.
|
||||||
|
*
|
||||||
|
* @param defaultColor The default color to apply to characters. This
|
||||||
|
* color is used for all characters in \p text that are
|
||||||
|
* not altered by \p mask.
|
||||||
|
*
|
||||||
|
* @param transparent The character to use to represent transparent areas
|
||||||
|
* in \p text. This can be useful when the
|
||||||
|
* auto-transparency feature can't detect transparent
|
||||||
|
* areas.
|
||||||
|
*/
|
||||||
|
Frame(QString text, QString mask, QRgb defaultColor, QChar transparent = '?');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paints this Frame into the given screen.
|
||||||
|
*
|
||||||
|
* @param scr The Screen to draw into.
|
||||||
|
* @param x The logical x coordinate of the left edge of the update region.
|
||||||
|
* @param y The logical y coordinate of the top edge of the update region.
|
||||||
|
*/
|
||||||
|
void paint(Screen* scr, int x, int y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erases this Frame from the given screen.
|
||||||
|
*
|
||||||
|
* @param scr The Screen to draw into.
|
||||||
|
* @param x The logical x coordinate of the left edge of the update region.
|
||||||
|
* @param y The logical y coordinate of the top edge of the update region.
|
||||||
|
*/
|
||||||
|
void erase(Screen* scr, int x, int y);
|
||||||
|
|
||||||
|
/// Returns the logical width of this frame.
|
||||||
|
int width() const
|
||||||
|
{
|
||||||
|
return m_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the logical height of this frame.
|
||||||
|
int height() const
|
||||||
|
{
|
||||||
|
return m_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function converts the Pixel data in m_data to setup m_pixmap
|
||||||
|
* and m_erasePixmap, which are not setup until this function is called.
|
||||||
|
*
|
||||||
|
* m_data is not valid after this call is performed to save memory.
|
||||||
|
*
|
||||||
|
* @param screen The Screen we will be drawing into later.
|
||||||
|
*/
|
||||||
|
void convertDataToPixmap(const Screen *screen);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// vim: set et ts=8 sw=4:
|
@ -0,0 +1,251 @@
|
|||||||
|
/*
|
||||||
|
* Asciiquarium - Native KDE Screensaver based on the Asciiquarium program
|
||||||
|
* (c) Kirk Baucom <kbaucom@schizoid.com>, which you can find at
|
||||||
|
* http://www.robobunny.com/projects/asciiquarium/
|
||||||
|
*
|
||||||
|
* Ported to KDE by Maksim Orlovich <maksim@kde.org> and
|
||||||
|
* Michael Pyne <michael.pyne@kdemail.net>.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003 Kirk Baucom <kbaucom@schizoid.com>
|
||||||
|
* Copyright (c) 2005 Maksim Orlovich <maksim@kde.org>
|
||||||
|
* Copyright (c) 2005 Michael Pyne <michael.pyne@kdemail.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <qcolor.h>
|
||||||
|
#include <qfontmetrics.h>
|
||||||
|
#include <qpainter.h>
|
||||||
|
#include <qpixmap.h>
|
||||||
|
#include <qtimer.h>
|
||||||
|
#include <qwidget.h>
|
||||||
|
|
||||||
|
#include <kglobalsettings.h>
|
||||||
|
|
||||||
|
#include "screen.h"
|
||||||
|
#include "sprite.h"
|
||||||
|
#include "aasaver.h"
|
||||||
|
|
||||||
|
Screen::Screen(AASaver* widget): m_widget(widget)
|
||||||
|
{
|
||||||
|
QFontMetrics fm(KGlobalSettings::fixedFont());
|
||||||
|
|
||||||
|
// Compute cell geometries.
|
||||||
|
m_cellW = fm.maxWidth();
|
||||||
|
m_cellH = fm.lineSpacing();
|
||||||
|
|
||||||
|
// Computer number of full cells that will fit.
|
||||||
|
m_width = widget->width() / m_cellW;
|
||||||
|
m_height = widget->height() / m_cellH;
|
||||||
|
|
||||||
|
// Calculate offset needed to evenly distribute excess screen space.
|
||||||
|
m_offX = (widget->width() - m_width * m_cellW) / 2;
|
||||||
|
m_offY = (widget->height() - m_height * m_cellH) / 2;
|
||||||
|
|
||||||
|
// Create double buffer.
|
||||||
|
m_backBuffer = QPixmap(m_widget->size());
|
||||||
|
m_backBuffer.fill(black);
|
||||||
|
|
||||||
|
// FIXME: handle resizing!
|
||||||
|
|
||||||
|
// Setup animation timer.
|
||||||
|
QTimer* timer = new QTimer(this);
|
||||||
|
connect(timer, SIGNAL(timeout()), SLOT(doAnimate()));
|
||||||
|
|
||||||
|
timer->start(msPerTick());
|
||||||
|
}
|
||||||
|
|
||||||
|
int Screen::msPerTick() const
|
||||||
|
{
|
||||||
|
return 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
Screen::~Screen()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::updateSpan(int x, int y, const QPixmap &updatePixmap)
|
||||||
|
{
|
||||||
|
if (y < 0 || y >= m_height) return;
|
||||||
|
|
||||||
|
QPoint upperLeft(m_offX + x * m_cellW, m_offY + y * m_cellH);
|
||||||
|
bitBlt(&m_backBuffer, upperLeft, &updatePixmap, updatePixmap.rect(), Qt::CopyROP);
|
||||||
|
m_widget->update(QRect(upperLeft, updatePixmap.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::clearSpan(int x, int y, const QPixmap &clearPixmap)
|
||||||
|
{
|
||||||
|
if (y < 0 || y >= m_height) return;
|
||||||
|
|
||||||
|
QPoint upperLeft(m_offX + x * m_cellW, m_offY + y * m_cellH);
|
||||||
|
bitBlt(&m_backBuffer, upperLeft, &clearPixmap, clearPixmap.rect(), Qt::CopyROP);
|
||||||
|
m_widget->update(QRect(upperLeft, clearPixmap.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Actually paints the region on the widget.
|
||||||
|
void Screen::paint(QRegion r)
|
||||||
|
{
|
||||||
|
QPainter p(m_widget);
|
||||||
|
QMemArray<QRect> rects = r.rects();
|
||||||
|
|
||||||
|
for (int r = 0; r < rects.size(); ++r)
|
||||||
|
{
|
||||||
|
//Determine the grid locations described by the rect
|
||||||
|
QRect bound = rects[r];
|
||||||
|
|
||||||
|
bitBlt(m_widget, bound.topLeft(), &m_backBuffer, bound, Qt::CopyROP);
|
||||||
|
} //for rect in region
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility type used to faciliate sorting of the Sprite list in order to
|
||||||
|
* implement the Painter's Algorithm when painting the back buffer.
|
||||||
|
*/
|
||||||
|
struct ZKey
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Logical depth of sprite. Now 0 is farthest away from the eyes, unlike
|
||||||
|
* with Sprite::depth().
|
||||||
|
*/
|
||||||
|
int z;
|
||||||
|
|
||||||
|
Sprite* addr;
|
||||||
|
|
||||||
|
ZKey(): z(0), addr(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ZKey(Sprite* spr): z(1000 - spr->depth()), addr(spr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool operator<(const ZKey& other) const
|
||||||
|
{
|
||||||
|
if (z < other.z) return true;
|
||||||
|
if (z > other.z) return false;
|
||||||
|
|
||||||
|
return addr < other.addr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void Screen::doAnimate()
|
||||||
|
{
|
||||||
|
//First, rebuild a new list of sprites, and build a dirty region
|
||||||
|
QRegion dirtyRegion;
|
||||||
|
|
||||||
|
QValueVector<Sprite*> sprites;
|
||||||
|
QValueVector<Sprite*> colliders;
|
||||||
|
|
||||||
|
// Look for sprites that can suffer a collision.
|
||||||
|
for (unsigned pos = 0; pos < m_sprites.size(); ++pos)
|
||||||
|
{
|
||||||
|
if(m_sprites[pos]->canCollide())
|
||||||
|
colliders.append(m_sprites[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find collisions.
|
||||||
|
// FIXME: Use transparent regions for accuracy.
|
||||||
|
for (unsigned pos = 0; pos < colliders.size(); ++pos)
|
||||||
|
for (unsigned sprite = 0; sprite < m_sprites.size(); ++sprite)
|
||||||
|
{
|
||||||
|
if(m_sprites[sprite] == colliders[pos])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(colliders[pos]->geom().intersects(m_sprites[sprite]->geom()))
|
||||||
|
colliders[pos]->collision(m_sprites[sprite]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Retain all live existing sprites
|
||||||
|
for (int pos = 0; pos < m_sprites.size(); ++pos)
|
||||||
|
{
|
||||||
|
Sprite* sprite = m_sprites[pos];
|
||||||
|
QRect oldRect = sprite->geom();
|
||||||
|
if (!sprite->isKilled()) {
|
||||||
|
bool dirty = sprite->tickUpdate();
|
||||||
|
|
||||||
|
if (dirty)
|
||||||
|
dirtyRegion |= oldRect | sprite->geom();
|
||||||
|
|
||||||
|
if (!sprite->isKilled())
|
||||||
|
sprites.append(sprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sprite->isKilled()) //note:may be made true by updateTick!
|
||||||
|
{
|
||||||
|
dirtyRegion |= oldRect;
|
||||||
|
delete sprite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add new sprites.
|
||||||
|
for (int pos = 0; pos < m_addedSprites.size(); ++pos)
|
||||||
|
{
|
||||||
|
dirtyRegion |= m_addedSprites[pos]->geom();
|
||||||
|
sprites.append(m_addedSprites[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_addedSprites.clear();
|
||||||
|
m_sprites = sprites;
|
||||||
|
|
||||||
|
//Compute the list of sprites affected. Note that this is
|
||||||
|
//done iteratively until fixed point.
|
||||||
|
QValueVector<Sprite*> paintSprites;
|
||||||
|
QValueVector<Sprite*> remSprites;
|
||||||
|
|
||||||
|
bool changed;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
changed = false;
|
||||||
|
remSprites.clear();
|
||||||
|
|
||||||
|
for (int c = 0; c < sprites.size(); ++c)
|
||||||
|
{
|
||||||
|
Sprite* sprite = sprites[c];
|
||||||
|
|
||||||
|
if (dirtyRegion.intersect(sprite->geom()).isEmpty())
|
||||||
|
remSprites.append(sprite); //not to be painted thus far
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//This sprite is to be painted
|
||||||
|
paintSprites.append(sprite);
|
||||||
|
|
||||||
|
//make sure we repaint everything overlapping it
|
||||||
|
dirtyRegion |= sprite->geom();
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sprites = remSprites;
|
||||||
|
}
|
||||||
|
while (changed);
|
||||||
|
|
||||||
|
//Z-sort the items.
|
||||||
|
QMap<ZKey, Sprite* > sorted;
|
||||||
|
for (int pos = 0; pos < paintSprites.size(); ++pos)
|
||||||
|
sorted[ZKey(paintSprites[pos])] = paintSprites[pos];
|
||||||
|
|
||||||
|
//Paint, in Z-order
|
||||||
|
for (QMapIterator<ZKey, Sprite*> i = sorted.begin();
|
||||||
|
i != sorted.end(); ++i)
|
||||||
|
i.data()->paint();
|
||||||
|
|
||||||
|
// Make sure black strip at edge is still present.
|
||||||
|
if(!paintSprites.isEmpty())
|
||||||
|
{
|
||||||
|
QPainter p(&m_backBuffer);
|
||||||
|
p.fillRect(m_backBuffer.width() - m_offX, 0, m_offX, m_backBuffer.height(), Qt::black);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "screen.moc"
|
||||||
|
|
||||||
|
// vim: set et ts=8 sw=4:
|
@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* Asciiquarium - Native KDE Screensaver based on the Asciiquarium program
|
||||||
|
* (c) Kirk Baucom <kbaucom@schizoid.com>, which you can find at
|
||||||
|
* http://www.robobunny.com/projects/asciiquarium/
|
||||||
|
*
|
||||||
|
* Ported to KDE by Maksim Orlovich <maksim@kde.org> and
|
||||||
|
* Michael Pyne <michael.pyne@kdemail.net>.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003 Kirk Baucom <kbaucom@schizoid.com>
|
||||||
|
* Copyright (c) 2005 Maksim Orlovich <maksim@kde.org>
|
||||||
|
* Copyright (c) 2005 Michael Pyne <michael.pyne@kdemail.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AA_SCREEN_H
|
||||||
|
#define AA_SCREEN_H
|
||||||
|
|
||||||
|
#include <qcolor.h>
|
||||||
|
#include <qfont.h>
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qvaluevector.h>
|
||||||
|
#include <qpixmap.h>
|
||||||
|
|
||||||
|
class Sprite;
|
||||||
|
class AASaver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the main display class of Asciiquarium. We use a pseudo-terminal-ish
|
||||||
|
* type coordinate system, where although this is a full fledged GUI application,
|
||||||
|
* Sprites and most external functions deal with logical text position
|
||||||
|
* coordinates instead of GUI coordinates. (x, y) starts in the upper-left of
|
||||||
|
* the real screen at (0, 0), and continues on to (width - 1, height - 1).
|
||||||
|
*
|
||||||
|
* Use addSprite() to add new Sprites to the Screen after you have created them
|
||||||
|
* and added their Frames.
|
||||||
|
*/
|
||||||
|
class Screen: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Represents a logical character on the Screen.
|
||||||
|
*/
|
||||||
|
struct Pixel {
|
||||||
|
char letter; ///< Character to display in the cell.
|
||||||
|
QRgb color; ///< Color to use for the cell.
|
||||||
|
|
||||||
|
/// Default constructor.
|
||||||
|
Pixel(): letter(' '), color(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
AASaver* m_widget; ///< Widget that we should paint on.
|
||||||
|
int m_width; ///< Number of logical columns in the screen.
|
||||||
|
int m_height; ///< Number of logical rows on the screen.
|
||||||
|
int m_offX; ///< Number of pixels on left side needed to center image.
|
||||||
|
int m_offY; ///< Number of pixels on top side needed to center image.
|
||||||
|
|
||||||
|
/** Pixmap cache of the image used to speed up rendering. All paints happen
|
||||||
|
* to the pixmap, which is then bitBlt()'ed to m_widget when the time comes
|
||||||
|
* to paint.
|
||||||
|
*/
|
||||||
|
QPixmap m_backBuffer;
|
||||||
|
|
||||||
|
int m_cellW; ///< The GUI width of a character cell.
|
||||||
|
int m_cellH; ///< The GUI height of a character cell.
|
||||||
|
|
||||||
|
QValueVector<Sprite*> m_sprites; ///< List of Sprites on screen.
|
||||||
|
QValueVector<Sprite*> m_addedSprites; ///< List of Sprites to be added next frame.
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
/**
|
||||||
|
* Handles updating the screen buffer to draw the next frame.
|
||||||
|
*/
|
||||||
|
void doAnimate();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param widget The widget to draw on.
|
||||||
|
*/
|
||||||
|
Screen(AASaver* widget);
|
||||||
|
~Screen();
|
||||||
|
|
||||||
|
/// Returns the logical width of the screen.
|
||||||
|
int width() const
|
||||||
|
{
|
||||||
|
return m_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the logical height of the screen.
|
||||||
|
int height() const
|
||||||
|
{
|
||||||
|
return m_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the GUI width of a character cell.
|
||||||
|
int cellWidth() const
|
||||||
|
{
|
||||||
|
return m_cellW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the GUI height of a character cell.
|
||||||
|
int cellHeight() const
|
||||||
|
{
|
||||||
|
return m_cellH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a sprite to the internal sprite list.
|
||||||
|
*
|
||||||
|
* @param sprite The Sprite to add. It will show up in the next frame.
|
||||||
|
*/
|
||||||
|
void addSprite(Sprite* sprite)
|
||||||
|
{
|
||||||
|
m_addedSprites.append(sprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the number of milliseconds separating each animation tick.
|
||||||
|
int msPerTick() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the backbuffer, and asks the portion of the widget to be
|
||||||
|
* repainted.
|
||||||
|
*
|
||||||
|
* @param x The logical x coordinate of the left edge of the update area.
|
||||||
|
* @param y The logical y coordinate of the top edge of the update area.
|
||||||
|
* @param updatePixmap The pixmap to draw into the buffer, which should be
|
||||||
|
* masked to only draw non-transparent regions.
|
||||||
|
*/
|
||||||
|
void updateSpan(int x, int y, const QPixmap &updatePixmap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the given portion of the backbuffer, asks for a repaint.
|
||||||
|
*
|
||||||
|
* @param x The logical x coordinate of the left edge of the update region.
|
||||||
|
* @param y The logical y coordinate of the top edge of the update region.
|
||||||
|
* @param clearPixmap the pixmap to use to clear the span, which should be
|
||||||
|
* the background color of the Screen, and masked to
|
||||||
|
* only draw the area that needs cleared.
|
||||||
|
*/
|
||||||
|
void clearSpan(int x, int y, const QPixmap &clearPixmap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actually paints the region on the widget.
|
||||||
|
*
|
||||||
|
* @param r The region of the widget to update.
|
||||||
|
*/
|
||||||
|
void paint(QRegion r);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// vim: set et ts=8 sw=4:
|
@ -0,0 +1,50 @@
|
|||||||
|
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
|
||||||
|
<class>SettingsWidget</class>
|
||||||
|
<widget class="QWidget">
|
||||||
|
<property name="name">
|
||||||
|
<cstring>SettingsWidget</cstring>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>399</width>
|
||||||
|
<height>45</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="caption">
|
||||||
|
<string>Asciiquarium Settings</string>
|
||||||
|
</property>
|
||||||
|
<hbox>
|
||||||
|
<property name="name">
|
||||||
|
<cstring>unnamed</cstring>
|
||||||
|
</property>
|
||||||
|
<widget class="QLabel">
|
||||||
|
<property name="name">
|
||||||
|
<cstring>textLabel1</cstring>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Number of Fish:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QSpinBox">
|
||||||
|
<property name="name">
|
||||||
|
<cstring>kcfg_fishCount</cstring>
|
||||||
|
</property>
|
||||||
|
<property name="maxValue">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
<property name="minValue">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="lineStep">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</hbox>
|
||||||
|
</widget>
|
||||||
|
<layoutdefaults spacing="6" margin="0"/>
|
||||||
|
</UI>
|
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Asciiquarium - Native KDE Screensaver based on the Asciiquarium program
|
||||||
|
* (c) Kirk Baucom <kbaucom@schizoid.com>, which you can find at
|
||||||
|
* http://www.robobunny.com/projects/asciiquarium/
|
||||||
|
*
|
||||||
|
* Ported to KDE by Maksim Orlovich <maksim@kde.org> and
|
||||||
|
* Michael Pyne <michael.pyne@kdemail.net>.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003 Kirk Baucom <kbaucom@schizoid.com>
|
||||||
|
* Copyright (c) 2005 Maksim Orlovich <maksim@kde.org>
|
||||||
|
* Copyright (c) 2005 Michael Pyne <michael.pyne@kdemail.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sprite.h"
|
||||||
|
|
||||||
|
Sprite::Sprite(Screen* screen, int x, int y, int z, int frameDelay):
|
||||||
|
m_screen(screen), m_currentFrame(0), m_x(x), m_y(y), m_z(z),
|
||||||
|
m_isKilled(false), m_killAfterLastFrame(false),
|
||||||
|
m_ticksSinceFrameChange(0), m_frameDelay(frameDelay)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sprite::addFrame(const Frame& frame)
|
||||||
|
{
|
||||||
|
m_frames.append(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sprite::erase()
|
||||||
|
{
|
||||||
|
m_frames[m_currentFrame].erase(m_screen, m_x, m_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sprite::paint()
|
||||||
|
{
|
||||||
|
m_frames[m_currentFrame].paint(m_screen, m_x, m_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sprite::timerTick()
|
||||||
|
{
|
||||||
|
++m_ticksSinceFrameChange;
|
||||||
|
if (m_ticksSinceFrameChange * m_screen->msPerTick() < m_frameDelay)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//Ring! Ring!
|
||||||
|
m_ticksSinceFrameChange = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sprite::tickUpdate()
|
||||||
|
{
|
||||||
|
if (m_frames.size() == 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!timerTick())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
erase();
|
||||||
|
|
||||||
|
++m_currentFrame;
|
||||||
|
if (m_currentFrame == m_frames.size())
|
||||||
|
{
|
||||||
|
m_currentFrame = 0;
|
||||||
|
|
||||||
|
if(m_killAfterLastFrame)
|
||||||
|
{
|
||||||
|
erase();
|
||||||
|
kill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect Sprite::geom() const
|
||||||
|
{
|
||||||
|
return QRect(m_x, m_y, m_frames[0].width(), m_frames[0].height());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// vim: set et ts=8 sw=4:
|
@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* Asciiquarium - Native KDE Screensaver based on the Asciiquarium program
|
||||||
|
* (c) Kirk Baucom <kbaucom@schizoid.com>, which you can find at
|
||||||
|
* http://www.robobunny.com/projects/asciiquarium/
|
||||||
|
*
|
||||||
|
* Ported to KDE by Maksim Orlovich <maksim@kde.org> and
|
||||||
|
* Michael Pyne <michael.pyne@kdemail.net>.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003 Kirk Baucom <kbaucom@schizoid.com>
|
||||||
|
* Copyright (c) 2005 Maksim Orlovich <maksim@kde.org>
|
||||||
|
* Copyright (c) 2005 Michael Pyne <michael.pyne@kdemail.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AA_SPRITE_H
|
||||||
|
#define AA_SPRITE_H
|
||||||
|
|
||||||
|
#include <qvaluevector.h>
|
||||||
|
#include "frame.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a on-screen character of some sort. These make up
|
||||||
|
* the building blocks of the animation.
|
||||||
|
*
|
||||||
|
* You can use multiple frames of animation, but movement is not supported in
|
||||||
|
* this class, try MovingSprite. If you use multiple frames, use
|
||||||
|
* setFrameDelay to control the interval between frames, and use
|
||||||
|
* setDieAfterLastFrame to set whether the animation should loop or cause
|
||||||
|
* the Sprite to go away.
|
||||||
|
*
|
||||||
|
* Use kill() to get rid of a Sprite, do not delete it by yourself, as Screen
|
||||||
|
* will do that as needed.
|
||||||
|
*/
|
||||||
|
class Sprite
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Screen* m_screen; ///< The Screen that we belong to.
|
||||||
|
int m_currentFrame; ///< The current frame of animation.
|
||||||
|
int m_x; ///< Our current logical x position.
|
||||||
|
int m_y; ///< Our current logical y position.
|
||||||
|
int m_z; ///< Our current depth.
|
||||||
|
|
||||||
|
QValueVector<Frame> m_frames; ///< Array of animation frames.
|
||||||
|
bool m_isKilled; ///< True if we've been killed.
|
||||||
|
bool m_killAfterLastFrame; ///< True if we should auto-kill after the last frame.
|
||||||
|
int m_ticksSinceFrameChange; ///< Number of timer ticks since we last changed frame.
|
||||||
|
int m_frameDelay; ///< Number of milliseconds to show a frame for.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increments the animation timer.
|
||||||
|
*
|
||||||
|
* @return true if time has elapsed past m_frameDelay since the last frame
|
||||||
|
* change.
|
||||||
|
*/
|
||||||
|
bool timerTick();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a sprite without automatically adding it to \p screen.
|
||||||
|
*
|
||||||
|
* @param screen The Screen that the sprite belongs to.
|
||||||
|
* @param x The x column position for the left edge of this sprite.
|
||||||
|
* @param y The y row position for the upper line of this sprite.
|
||||||
|
* @param z The depth of the sprite (0 is closest to screen).
|
||||||
|
* @param frameDelay Amount of milliseconds to elapse between animation
|
||||||
|
* frames.
|
||||||
|
*/
|
||||||
|
Sprite(Screen* screen, int x, int y, int z, int frameDelay = 100);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destuctor. Does nothing at this point, present to ensure a continuous
|
||||||
|
* line of virtual destructors.
|
||||||
|
*/
|
||||||
|
virtual ~Sprite()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this sprite can be involved in a collision with another
|
||||||
|
* Sprite. The other sprite doesn't necessarily have to have this
|
||||||
|
* also set to true.
|
||||||
|
*/
|
||||||
|
virtual bool canCollide() const { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a collision occurs with *any* Sprite on-screen if canCollide()
|
||||||
|
* returns true.
|
||||||
|
*
|
||||||
|
* @param sprite The Sprite that a collision happened with. It is safe to
|
||||||
|
* kill() the Sprite, move it, etc.
|
||||||
|
*/
|
||||||
|
virtual void collision (Sprite *sprite)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends a frame of animation to the end of the current list.
|
||||||
|
*
|
||||||
|
* @param frame Frame of animation to add. It should be the same size as
|
||||||
|
* the other frames already in the list.
|
||||||
|
*/
|
||||||
|
void addFrame(const Frame& frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the amount of time to show a frame for.
|
||||||
|
*
|
||||||
|
* @param delay The frame delay, in milliseconds of time.
|
||||||
|
*/
|
||||||
|
void setFrameDelay(int delay)
|
||||||
|
{
|
||||||
|
m_frameDelay = delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether this Sprite should automatically call kill() after the
|
||||||
|
* last frame of animation has run.
|
||||||
|
*
|
||||||
|
* @param dieAfterLast If true, this Sprite will automatically call kill()
|
||||||
|
* after its last frame has elapsed.
|
||||||
|
*/
|
||||||
|
void setDieAfterLastFrame(bool dieAfterLast)
|
||||||
|
{
|
||||||
|
m_killAfterLastFrame = dieAfterLast;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The Screen this Sprite belongs to.
|
||||||
|
*/
|
||||||
|
Screen *screen() const
|
||||||
|
{
|
||||||
|
return m_screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this Sprite is dead. If true, it will probably soon be
|
||||||
|
* deleted by its Screen.
|
||||||
|
*/
|
||||||
|
bool isKilled() const
|
||||||
|
{
|
||||||
|
return m_isKilled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The depth of the Sprite. 0 is closest to the screen.
|
||||||
|
*/
|
||||||
|
int depth() const
|
||||||
|
{
|
||||||
|
return m_z;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The rectangular geometry of this object in the Pixel coordinate
|
||||||
|
* system.
|
||||||
|
*/
|
||||||
|
QRect geom() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erases this Sprite from its Screen, using the current animation frame to
|
||||||
|
* form the clear mask. This should be called *before* any change which
|
||||||
|
* will change the on-screen display of the object, such as motion or
|
||||||
|
* animation changes.
|
||||||
|
*/
|
||||||
|
void erase();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws this Sprite onto the Screen.
|
||||||
|
*/
|
||||||
|
void paint();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kills this Sprite. The parent Screen will delete this Sprite on the next
|
||||||
|
* animation cycle.
|
||||||
|
*/
|
||||||
|
virtual void kill()
|
||||||
|
{
|
||||||
|
m_isKilled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//main animation hook. Should return true + erase if something changed
|
||||||
|
/**
|
||||||
|
* Called when the current frame expires. This function needs to perform
|
||||||
|
* any actions necessary to make sure that it is ready to be painted,
|
||||||
|
* including calling erase(). You do not need to call paint() from this
|
||||||
|
* function.
|
||||||
|
*
|
||||||
|
* @return true if the on-screen representation of this Sprite changed,
|
||||||
|
* false, otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool tickUpdate();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// vim: set et ts=8 sw=4:
|
Loading…
Reference in New Issue