Table of Contents

AutoDrawing

Turn your computer into an artist!

Overview

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.

Components

1) A unix computer
2) An x-windows environment
3) X-paint

Script Breakdown

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.

Initialization

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

Lets draw!

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 Xwit Command

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.

The Xte Command

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

The Script

    #!/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