## 36.26. Outputting Text to an X Window

Unix has a lot of ways to output text from the command line into the terminal (or window) where a script is running. But there are times you'd like to pop open a new window (under the X Window System (Section 1.22)), give the user a message -- and maybe let the user reply too. X comes with a standard client named xmessage that does this. It pops open a window like Figure 36-7 with a message, then waits for the user to click a button (possibly one of many) or press RETURN. For details, you can read the xmessage manual page. I'll show how I integrated xmessage into a shell script.

#### Figure 36-7. An xmessage window from xwrist

Go to http://examples.oreilly.com/upt3 for more information on: xwrist

A good way to prevent wrist injuries (from too much typing) is by taking periodic breaks. The xwrist script uses xmessage to remind me (every 10 minutes) to take a break -- and prints a fortune for me to read while I do.

Let's look at two parts of the script. First, the script checks to see if the X Window System DISPLAY environment variable (Section 35.5) is set; if not, it complains (with a message like `xwrist: DISPLAY: unset? I only work under the X Window System`) and exits:

`:` Section 36.6, `${..?..}` Section 36.7

>     : ${DISPLAY?"unset? I only work under the X Window System"}

After checking the command-line arguments and setting some shell variables, the script does its main work with an endless loop:

``...``Section 28.14

>     while sleep $delay
>     do
>         if xmessage -nearmouse -geometry $geometry -title "$title" \
>             -buttons okay:1,quit:0 -default okay \
>             "`/usr/games/fortune | fmt $fmtarg`"
>         then exit 0
>         fi
>     done

The while loop (Section 35.15) is endless because sleep normally returns 0 (Section 35.12). As long as the user keeps clicking the okay button, a new xmessage window will pop up again `$delay` seconds after the previous one. The xmessage command line is split into three pieces. It's run by an if statement (Section 35.13). On the second line, `-buttons okay:1,quit:0` tells xmessage to make the two buttons. If the user clicks the quit button, xmessage returns 0 status and the if runs `exit 0` to end the script. Otherwise, xmessage returns 1 (because the user clicked okay or pressed RETURN; the `-default okay` sets this up) and the loop repeats.

(Here's a fun enhancement, left as an exercise for you. Add a third button labeled mail this that uses mail(1) to send you ($USER) an email copy of the current fortune. You'll need to change the if to a case statement (Section 35.10) that tests $? (Section 35.12).)

The last xmessage argument is the text to put on the screen. fmt (Section 21.2) reformats the output of fortune roughly to fit the window. (There's no fancy coding here to be sure that the text fits the window exactly; I just tweak the output width, set in the fmtarg variable, to match the window geometry, which is set in the geometry variable.) If you set the geometry to make a fairly wide window, you may not need fmt at all.

-- JP

Copyright © 2003 O'Reilly & Associates. All rights reserved.