Turn your computer into an artist!
The goals of this project are the following:
1) Write a script to allow the computer to draw in Xpaint 2) Turn your computer into an award winning artist.
1) A unix computer 2) An x-windows environment 3) X-paint
We will go over the commands that will be used in the drawing program. The functionality of my script allows the computer to randomly draw different shapes in random sizes and positions. Since the inception of this program, I have seen some amazing work done by others! The limits are only your imagination.
To start out, we want to kill all instances of xpaint, if this is not done it will lead to script confusion and unpredictable errors.
This calls the pkill command to shut down all instances of x-paint calling SIGTERM to each instance.
echo `pkill xpaint`
We now start a new instance of xpaint with the options of a 1024×768 drawing space without a menu bar. Sleep for 4 seconds is called as well to allow time for the program to fully initialize.
/usr/bin/xpaint -size 1024x768 -nomenubar -popped& sleep 4
Let's set up some variables that we can use to call up the ID's of xpaint and the drawing window (the Untitled window.) We can use these variables for controlling the environment later.
toolID=`xwit -all -print | grep XPaint | sed -e 's/:.*//g'` winID=`xwit -all -print | grep Untitled | sed -e 's/:.*//g'
The following commands use xwit to manpulate a window's position using the grepped out ID obtained above. We supply commands to the variables focusWin and focusTools and echo them to the system. This moves the main window (The drawing space) and the xpain tools to the top left of the screen, and again we sleep two seconds to let the system catch up because we are so fast and efficent :D
focusWin=`xwit -id $winID -focus -raise -move 0 0` focusTools=`xwit -id $toolID -focus -raise -move 0 0` echo $focusTools echo $focusWin sleep 2
Drawing is pretty strait forward, basically you control the mouse via the computer, performing commands such as clicks, drags, and selection, but without manually interfering. The movements are all scripted using an x-y coordinate system. Lets see how it's done.
To begin with, in my script I am drawing random shapes in random positions, so I must set up a random number generation system and position variables. The program draws 100 shapes (the count being controlled with a while loop limited to a count of 100).
The random variables are set up as shown.
size=`echo $[($RANDOM % 30)]` xpos=`echo $[($RANDOM % 1024)]` ypos=`echo $[($RANDOM % 720 + 60)]` xwit -id $winID -warp $xpos $ypos
What happens is a random number limited to 30 is generated and stored in the “size” variable. Size is used to set the graphical limits of a shape to be drawn, for example, if size ends up as a value of 5, and the random shape is a square, the program will draw a square 5×5 pixels in size.
xpos = generates a random number “widthwise”, this is limted at 1024 because thats the width of our drawing space, if you increased the size of the drawing window, you would want to increase this number as well.
ypos = generates a random number for the height of the drawing space, we are adding 60 to push down the drawing space so that it does not include the title bar of the drawing window.
Using xwit, we warp the mouse over the drawing window who's window is selected using our winID variable to the generated xpos and ypos. This brings us to our initial drawing position.
Now we generate a random number to determine the shape we draw, and store it in the variable “shape” .. ironic eh?
shape=`echo $(($RANDOM % 3))`
The value of shape is ran through a series of selection structures and the commands within are executed if the number is a match. For example, if the random shape number was a “0” we would draw a square.
if [ $shape -eq 0 ] #Draw a square! then xte "mousedown 1" xte "mousermove $size 0" xte "mousermove 0 -$size" xte "mousermove -$size 0" xte "mousermove 0 $size" xte "mouseup 1" fi
This time we are using the “xte” command to control the mouse position and behavior. The mouse is controlled by supplying “mousedown 1” - activating the mouse click and holding it down, then by using “mousermove” and position variables to draw a line. It is VERY important to note, “mousermove” is mouse RELATIVE move, meaning that it moves relative to it's current position, if you accidentally type “mousemove” it will move from the 0,0 position on the screen, giving you some pretty wacky results.
The command “xwit” does not make your x-session witty, but it does have it's uses!
According to xwit's man page:
xwit is an X window interface tool. By default when used with no arguments in an xterm it de-iconifies and raises the window. You can specify a different function to do, such as iconifying the window, and apply it to several windows whose name begins with one of the given strings, or a particular window id given, or the window id found in the environment variable WINDOWID (which is set by xterm for the program it runs).
Therefore, by using the xwit command and grep, we extract the window ID's for our own devious purposes. Xwit also allows the “warping” of a mouse pointer to a position on the screen, very useful for setting things up.
According to the man page.
xte is a program that generates fake input using the XTest extension, more reliable than xse.
Short and sweet huh? With xte you can emulate pretty much anything you can do with a mouse, here is a good list of the functions you can perform.
key k Press and release key k keydown "k" Press key k down keyup k Release key k str string Do a bunch of key X events for each char in string mouseclick i Click mouse button i mousemove x y Move mouse to screen position x, y mousermove x y Move mouse relative from current location by x, y mousedown i Press mouse button i down mouseup i Release mouse button i sleep x Sleep x seconds usleep x Usleep x microseconds
#!/bin/bash ################################## # # Automated Drawing Program # v0.1 # Michael Gough # CSIT 1320 # 2/3/2010 # ################################## echo `pkill xpaint` /usr/bin/xpaint -size 1024x768 -nomenubar -popped& sleep 4 xwit -root -rwarp 100 100 # Grep out the xpaint, get it's ID and bring it to focus toolID=`xwit -all -print | grep XPaint | sed -e 's/:.*//g'` winID=`xwit -all -print | grep Untitled | sed -e 's/:.*//g'` focusWin=`xwit -id $winID -focus -raise -move 0 0` focusTools=`xwit -id $toolID -focus -raise -move 0 0` echo $focusTools echo $focusWin sleep 2 xwit -id $winID -warp 640 480 count=1 xwit -id $winID -focus while [ $count -le 100 ] do size=`echo $[($RANDOM % 30)]` xpos=`echo $[($RANDOM % 1024)]` ypos=`echo $[($RANDOM % 720 + 60)]` xwit -id $winID -warp $xpos $ypos # Lets draw a bit!! Add more shapes! shape=`echo $(($RANDOM % 3))` t_ypos=`echo $(($size/2))` if [ $shape -eq 1 ] #Draw a triangle! then xte "mousedown 1" xte "mousermove -$size 0" xte "mousermove $t_ypos -$size" xte "mousermove $t_ypos $size" xte "mouseup 1" fi if [ $shape -eq 0 ] #Draw a square! then xte "mousedown 1" xte "mousermove $size 0" xte "mousermove 0 -$size" xte "mousermove -$size 0" xte "mousermove 0 $size" xte "mouseup 1" fi if [ $shape -eq 2 ] #Get lazy and use the xpaint toolbar to draw a circle! then xwit -id $toolID -raise -focus xwit -id $toolID -warp 32 245 xte "mousedown 1" xte "mouseup 1" echo $focusWin xwit -id $winID -warp $xpos $ypos xte "mousedown 1" xte "mousermove -$size -$size" xte "mouseup 1" xwit -id $toolID -raise -focus xwit -id $toolID -warp 33 123 xte "mousedown 1" xte "mouseup 1" echo $focusWin xwit -id $winID -warp $xpos $ypos fi (( count++ )) done