#!/usr/bin/env python
"""
This file is part of Circus
Circus 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.
Circus 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
Circus; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
"""
import sys
import Image
from Xlib import *
from Xlib.protocol import rq
debug = 0
USAGE = """
csetroot [-s] image
-s scales image to screen
"""
class PutImage(rq.Request):
_request = rq.Struct(
rq.Opcode(72),
rq.Set('format', 1, (X.XYBitmap, X.XYPixmap, X.ZPixmap)),
rq.RequestLength(),
rq.Drawable('drawable'),
rq.GC('gc'),
rq.Card16('width'),
rq.Card16('height'),
rq.Int16('dst_x'),
rq.Int16('dst_y'),
rq.Card8('left_pad'),
rq.Card8('depth'),
rq.Pad(2),
#rq.List('data', rq.Card8Obj),
rq.String8('data', 0),
)
def roundup(value, unit):
return (value + (unit - 1)) & ~(unit - 1)
def put_image_request(win, format, gc, image, dst_x, dst_y,
depth, rawmode, stride):
width, height = image.size
data = image.tostring("raw", rawmode, stride, 0)
PutImage(display = win.display,
format = format,
drawable = win.id,
gc = gc,
width = width,
height = height,
dst_x = dst_x,
dst_y = dst_y,
left_pad = 0,
depth = depth,
data = data)
def put_image(win, gc, image, dst_x, dst_y):
width, height = image.size
if image.mode == '1':
format = X.XYBitmap
depth = 1
if win.display.info.bitmap_format_bit_order == 0:
rawmode = '1;R'
else:
rawmode = '1'
pad = win.display.info.bitmap_format_scanline_pad
stride = roundup(width, pad) >> 3
elif image.mode == 'RGB':
format = X.ZPixmap
depth = 24
if win.display.info.image_byte_order == 0:
rawmode = 'BGRX'
else:
rawmode = 'RGBX'
pad = win.display.info.bitmap_format_scanline_pad
unit = win.display.info.bitmap_format_scanline_unit
stride = roundup(width * unit, pad) >> 3
else:
raise ValueError, 'Unknown data format'
maxlen = (win.display.info.max_request_length << 2) \
- PutImage._request.static_size
split = maxlen / stride
x1 = 0
x2 = width
y = 0
while y < height:
h = min(height, split)
if h < height:
subimage = image.crop((x1, y, x2, y + h))
else:
subimage = image
put_image_request(win, format, gc, subimage, dst_x, dst_y,
depth, rawmode, stride)
y += h
dst_y += h
def main():
# XXX change SCALE, etc. to global variables
SCALE = 0
GRADIENT = 0
#check number of arguments
if len(sys.argv) < 2:
print USAGE
sys.exit(-1)
#proccess arguments, default to tile
if sys.argv[1] != '-s':
image = Image.open(sys.argv[1])
else:
SCALE = 1
image = Image.open(sys.argv[2])
#get out display and screen info
disp = display.Display()
scrn = disp.screen()
root_geom = scrn.root.get_geometry()
ec = error.CatchError()
#should probably combine this with setting the SCALE
if SCALE:
pixmap = scrn.root.create_pixmap(root_geom.width,\
root_geom.height,\
24)
#now why isn't this working?
new_size = root_geom.width, root_geom.height
image.resize(new_size)
print root_geom.width, 'x', root_geom.height
print image.size
else:
pixmap = scrn.root.create_pixmap(image.size[0],\
image.size[1],\
24)
print image.size
#mode is RGB, for example
if image.mode == '1':
colormap = scrn.default_colormap
black = colormap.alloc_named_color("black")
white = colormap.alloc_named_color("white")
pix1 = scrn.root.create_pixmap(image.size[0], image.size[1], 1)
gc = pix1.create_gc()
put_image(pix1, gc, image.convert('1'), 0, 0)
gc.free()
gc = scrn.root.create_gc(background = black.pixel,
foreground = white.pixel)
pixmap.copy_plane(gc, pix1, 0, 0,
image.size[0], image.size[1], 0, 0, 1)
gc.free()
pix1.free()
else:
gc = scrn.root.create_gc()
put_image(pixmap, gc, image, 0, 0)
gc.free()
scrn.root.change_attributes(
background_pixmap = pixmap,
)
scrn.root.clear_area()
disp.sync()
if ec.get_error():
print ec.get_error()
pixmap.free()
disp.close()
if (debug):
#we know we have the root window
#if we could pass it to the C function XSWBP we'd be in business
print 'display = ', disp.get_display_name()
#print 'root window = ', scrn
#background.show() #this will display the image in a window
print 'pixmap = ', image
print '\n*****'
#print 'root_geometry size =',\
# root_geometry.width,\
# 'x',\
# root_geometry.height
#print 'root_geometry coords =',\
# root_geometry.x,\
# 'x',\
# root_geometry.y
if __name__ == '__main__':
main()