Documentation

Starting The Shell

To start Unix Shell for Windows, double-click on the shell icon located on the Windows desktop. You can also click on Start, Programs, Janotech, Unix Shell. The shell will display a $ prompt at the top of the window indicating that it is ready to accept commands.

$ _

You can then type commands in at the prompt. Unix Shell for Windows contains a standard set of command tools that allow you to work in a window at a command prompt. Shell commands also get information directly from the Windows operating system. You can use for instance the ps or process status command to list the active processes running in the current shell by typing

$ ps
       PID CMD
      2648 console.exe
      2660 ksh.exe
      2724 ps.exe

Shell Command Syntax

When the shell starts up, it starts up in what is called interactive mode meaning that commands may be typed in directly from the keyboard.

The command syntax for all shell commands is as follows

command options arg1 arg2 ...

where command is the name of a command and options are in the form of a - followed by one or more option letters. There must be at least one space separating the command, the options and the arguments, but there should be no spaces between the - and the option characters themselves.

Command options can be specified one at a time as in

$ wc -l -c -w file1

or together as a string as in

$ wc -lcw file1

Basic Shell Commands

You can use the basic shell commands to navigate your way in Windows such as the ls command to list files, cd to change directory and the pwd command to display the current directory name.

In order to display what directory you are in at any time, you can type in pwd and press Enter. pwd stands for print working directory.

$ pwd
C:/Janotech/user

To dislay a list of the files that are located in the current directory you can type

$ ls
.sh_history kshrc.ksh   profile.ksh

The ls command also supports other options such as the commonly used -l or long format option for listing the details for each file.

$ ls -l
-rw-rw-rw-  1     1898 Mar 22 15:19 .sh_history
-rw-rw-rw-  1      128 Sep 13  2005 kshrc.ksh
-rw-rw-rw-  1     1752 Mar 16 22:16 profile.ksh

You can also change the size of the window from the command line just by typing

$ max

Max is a shell alias or shortcut for another command. The command aliased is console -maximize which maximizes the shell window.

The cls command is another command that you can use at any time to clear the contents of the shell window.

$ cls

There are other shell aliases that come configured with the standard shell. Here is a list with descriptions of each command.

a:cd to the A drive
b:cd to the B drive
c:cd to the C drive
d:cd to the D drive
e:cd to the E drive
hshell history listing (just type h and Enter)
rmset to recycle command to send deleted files to recycle bin
clsclear the console window
grepgrep -a to search file even if it contains binary data
maxmaximizes the console window
minminimizes the console window
moreruns the less pager
restore    restores the console window also from console -topmost

Changing the Directory

The cd or change directory command can be used to change the current directory. For example

$ cd /janotech
$ pwd
C:/janotech

You can cd back to the previous directory just by typing

$ cd -
$ pwd
C:/janotech/user

If you want to cd to a Windows directory that has spaces in it such as, C:/Program Files, then you must surround the pathname with quotation marks as in

$ cd "C:/Program Files"

Also you can cd back to the $HOME directory just by typing cd with no directory specified.

$ cd
$ pwd
c:/Janotech/user

Changing the Drive

Normally when you start the shell, it starts up in a directory on your system's C: drive. If you want to change to another drive letter you can use one of the pre-defined drive aliases. For instance to cd to the A: drive on your system, type

$ a:

Note if you do not have a disk in drive A, then you might get a message such as,

c:/janotech/bin/ksh: cd: a: - Permission denied

which is perfectly okay. This just means there is no disk in drive A:.

You can cd to a directory on another drive by typing cd followed by the drive:directory spec as in:

$ cd d:/cdrom_files

You can also copy files to a drive by specifying the drive letter followed by a directory path as in

$ cp file1 a:/

Exiting the Shell

To exit the shell and close the console window at the prompt you can type

$ exit

You can also just click on the close button of any shell window and the shell will exit. The shell will automatically save command history if exiting as well in this manner.

Unix Shell for Windows Installation File Layout

The following describes the standard directory layout of the Janotech Unix Shell for Windows software package using the default installation directory.

The shell variable $JANOTECH which defaults to C:/Janotech is the top directory of the tree. The $JANOTECH directory contains the following subdirectories:

binshell commands are located here: ls, cat, ...
docmanual pages are located here
kshunix shell programming directory
ksh/examplesexample scripts directory
ksh/includeUnix Shell for Windows include files directory

Running Programs

Programs such as Windows notepad can be run at the command prompt as well just by typing in the name of the program and pressing Enter.

$ notepad

Note: certain programs need to be made accessible to the shell via the PATH environment variable in order to be run from the shell prompt (see PATH variable example later on).

Background Processes

You will notice that when the notepad program runs in Windows as in the last example, the shell is in a wait state and you cannot enter any more commands even when you click on the shell window. This is because the notepad program is running as a foreground process in relation to the shell. This means you must exit the notepad program before you can return to the shell.

If you want to run the notepad and still have command of the shell at the same time, then you must run notepad as a background process.

To run the notepad program as a background process type the command followed by the & (ampersand) character.

$ notepad&
[1] 1788

Now you will notice that the shell displays a number in brackets followed by another number. The first number indicates the job number which in this example is 1 and the next number indicates the Windows process id of the notepad program.

You can keep track of job processes that are running in the shell using the standard shell jobs command.

$ jobs
[1] + Running              notepad

Also, notice that you can return back to the shell while notepad is running just by clicking on the console window. If you exit the notepad program you will notice that the shell responds with

$
[1] + Done                 notepad  

This indicates that the notepad program process has terminated. You could also have terminated the notepad process from the shell itself with either

$ kill %notepad

or

$ kill 1788

Pipes

Another powerful feature of the shell is the use of pipes or filters. A pipe is a series of commands that are connected together in such a way that one command's output feeds the input of the next command and so on until the the final result is produced. The following is an example of a pipe.

$ ls | lpr

In this example the directory listing is sent to the printer to be printed by piping the output of the ls command into the input of the lpr or print command. The | character is called the pipe symbol and is used to separate the commands in a pipe.

Using the Console

The console is a program that lets you run other commands in a separate window as in:

 
$ console -exec ksh&

This would start the shell in a completely new window and it would run as a background process.

The console command can also be used to change the look of the current window such as the window's font and colors. The following command sets the current window's background color to navy blue and the text color to gold.

$ console -bc $navy -tc $gold

To change the font of the current console you are running to use the Lucida Console font with a point size of 20 you would type

$ console -fn "lucida console" -fs 20

Along with the basic console command there are also options that can be used to change the size and position of the window. For instance

$ console -x 0 -y 0

This command will move the window into the upper left corner of the Windows desktop.

You also can do things like keep the console window the topmost window on the desktop by typing

$ console -topmost

To stop the console window from being the topmost window, you can type

$ console -restore

To see other options available for console type

$ console -?

You can also cut and paste text to and from console windows using the Windows clipboard if the -mouse on (default) option has been specified.

When you select text with the mouse in the console window using the left mouse button it gets copied immediately to the Windows clipboard. To paste text to another console window, just click on the right mouse button. Text will be immediately copied to the console window as though you had typed it in from the keyboard.

Also note that you must not left click anywhere on the client area of the console window after you have copied text, or the text that was copied to the clipboard will be lost. You must click on the title bar first of the console window that you wish to paste clipboard text to.

The Interrupt Key

When you run a program in the shell, and you wish to break out of the currently running command you can press the interrupt key which defaults to Ctrl-C (Press C while holding down Ctrl on the keyboard). For example, run the grep command with some text as in:

$ grep text

Now if you press Ctrl-C the program will exit. Pressing Ctrl-C will also exit the following while loop in the shell.

$ while true
> do
> done

Note: you can change which key on the keyboard is set to be the interrupt key using the console command (type console -? for a quick list of options).

The Pause Key

If you want to pause the output being displayed by a command you can press the Pause key. Once the output is paused, you can then press any other key to continue displaying output.

The History Command

The shell command history can be displayed by using the h command alias:

$ h
1 cls
2 ls
3 pwd

You can run a previous command by typing r followed by the event number as in:

$ r 2
ls
.sh_history kshrc.ksh   profile.ksh

You can also re-run the last command typed by using r by itself on a line:

$ r
ls
.sh_history kshrc.ksh   profile.ksh

Setting the Prompt

You can set the shell prompt to be something other than a $ by setting the PS1 variable. For example to make the primary prompt display the current path

$ PS1='$PWD> '
C:/Janotech/user> 

You could also create a prompt that just contains the shell history event number as in

$ PS1='!$ '
100$ pwd
C:/Janotech/user
101$

Floating Point Math

Unix Shell for Windows supports floating point arithmetic. You can specify floating point expressions and do computations using the ((...)) arithmetic expression construct. The float results are returned back as text.

Loop by .5 increments from 0 to 10.

$ x=0
$ while (( x <= 10 ))
> do
> print $x
> (( x += .5 ))
> done

You also can append an F suffix to shell variables for functions that explicitly require floats.

$ angle=30.0F
$ call glRotatef $angle $x $y $z

For passing double precision constants you would just omit the F suffix.

$ call -r double cos $(( 3.14 / 4 ))
0.707388

Note however that to return the result as a double from the cosine function requires the call -r option to specify return type to be double.

Summary of Unix Shell Command-line Utilities

awk The awk programming language utility.
basename   Return filename portion of a pathname.
cal Displays a calendar.
cat Display contents of a file.
cform Formats C/C++ program source code.
chmod Change permissions on files.
clear Clears the screen.
console Windows GUI console program.
cp Copy files.
cut Select fields from lines in a file using delimiters.
date Display and set the system date and time.
diff Display differences between files.
ed The ed line editor.
expand Expands tabs to spaces.
find Find files.
fmt Simple document formatter.
fold Folds long lines in a file.
free Displays amount of free and used system memory.
getopt Parse command options.
grep Search for text in a file.
hd Hex dump utility.
head Display first few lines of a file.
iconify Run a minimized command.
ksh The Unix Shell command interpreter.
less File pager.
lpr Printer utility.
ls List contents of a directory.
man On-line manual command script.
mkdir Create directories.
mv Move/rename files.
pr Print files with pagination.
printf Print formatted output.
ps List Windows system processes.
recycle Send files to the Windows recycle bin.
rm Remove files.
rmdir Remove directories.
sed Stream-line editor.
sh Copy of Unix Shell command interpreter.
sort Sort files.
speed Get CPU speed in MHZ.
tail Display last lines of a file.
tee Copy standard input to standard output.
tr Translate characters.
unexpand Change spaces to tabs.
uniq Filter repeated lines in a file.
vi The vi editor.
virec Recover lost vi files.
wc Count word, chars, lines in a file.
wcopy Copy data to Windows clipboard.
winexec Execute Windows command.
wpaste Paste data from Windows clipboard.

Most of these commands are part of the standard Unix command set. Here are descriptions of some of the commands.

man

You can get help on any of the commands in the shell directly by using the man command. For instance to get the full man page for the ls command you can type

$ man ls

clear

The clear command clears the contents of the shell window and does a home cursor.

console

This command allows a program written using the Janotech Standard Windows Library (stdwin) to run in a graphical console window. Programs written using the stdwin API do not need a console, but they can communicate with the console when running in it. See the next section on using the console. The shell program itself runs properly only when running using the console.

hd

Hex dump utility. The hd command is a utility to be used to output hex, ascii, octal, or binary output format of the data contained in a file. The output looks very similar to the output of the standard od (octal dump) utility.

iconify

The iconify program can be used to build wrapper scripts for commands that are not normally Windows GUI programs but that output to standard out. For instance to create a wrapper script using iconify for the Windows ping command you would write something like this:

# ping.ksh - ping wrapper script
iconify ping.exe $* | $JANOTECH/bin/tee

This wrapper script allows the output of the ping command to be redirected to the shell window. Also the window created initially by the DOS console will be minimized.

Note: dir.ksh is another wrapper script for the DIR command that uses iconify.

lpr

You can use the lpr command to send output directly to the Windows print subsystem.

$ lpr output

send the contents of output to the printer

You can also bring up a Windows dialog box for printing with the -dlg option

$ lpr file -dlg 

ps

The ps command list the active processes for the system. If no options are given, then the process list is just for the current console. If the -a option is used the process list contains the list for the entire system. The -l is the long listing format as for example:

$ ps -l                              
       PID       PPID PRI THREADS CMD
       412       1408   8       2 console.exe
      1784        412   8       7 ksh.exe
      3608       1784   8       4 ps.exe

recycle

The recycle command will send files to the Windows recycle bin instead of just deleting the files.

wcopy

You can send text directly to the Windows clipboard using wcopy. For instance to send a directory listing to the clipboard:

$ ls -l | wcopy

wpaste

You can copy the text in the Windows clipboard directly to standard out in the shell by using wpaste. The output is not acted upon, so wpaste with no arguments only will write to shell standard out. To save the clipboard contents to a file you would do something like:

$ wpaste > output

Configuring the Unix Shell for Windows Startup Files

There are two files that contain the start up settings for the shell. When the shell is first launched from the Windows desktop it is executed with the -l or login option which will look for a file called profile.ksh, the user's shell profile, either in the directory specified by the "Start in:" property of the Windows desktop shell shortcut or in the $HOME environment variable.

The shell will also attempt to execute the file specified in the $ENV variable. The default is set to the file kshrc.ksh. This file gets executed every time a new copy of the shell is run and is a good place to store aliases that need to be initialized each time the shell is run.

   profile.ksh  Unix Shell startup user profile
   kshrc.ksh  Specified by $ENV variable in profile.ksh

Make sure that you understand how to use the vi editor to make changes to a file. If you modify any of the shell startup files incorrectly, you might lock yourself out of being able to start the shell and may have to reinstall the software.

It is always good practice to backup any file you intend to modify, so you might first start the shell and then do:

$ cp profile.ksh profile.ksh.old
$ cp kshrc.ksh kshrc.ksh.old

Then, if you make a mistake modifying the profile.ksh you can always go into Windows to the C:\JANOTECH\your_user_name folder and copy the backup files back to profile.ksh and kshrc.ksh.

A common change that is usually made to the profile.ksh is to set the PS1 prompt automatically so that you do not always have to set it every time you run the shell. Currently the line in profile.ksh sets the prompt to a $ followed by a space as in:

PS1='$ '

Another common change to the shell profile is usually to extend the PATH variable. For instance, if the Windows program you are trying to run from the command line does not start, it's possible that it is not being found when the shell searches the $PATH environment variable. You would need to either specify the full pathname to the program or add the directory where the application is located to the PATH variable.

Example: on Windows 98 if you wanted to run the mspaint.exe drawing program from the shell without having to type the full path, you would need to add the following line to your shell profile.ksh file:

export PATH="$PATH;/Program Files/Accessories;"

Command Substitution $(...)

Unix Shell for Windows does support command substitution. However, eventhough it is based on a version of the public domain korn shell, it does not support the standard Korn Shell, Bourne Shell or POSIX behavior of running the commands in a subshell. If you need this behavior, you can use the set +o nofork command option, or start the shell with ksh +o nofork. The nofork option is not supported however.

Instead of running commands in a subshell, the shell favors a command substitution scheme where the result is returned, but no subshell process is created unless the command itself creates a process.

For example, to return the result of a command and store it in a shell variable:

$ d=$(date)
$ echo $d
Tue Mar 1 13:21:50 Eastern Standard Time 2005

This version of the shell normally does not create a separate subshell for commands enclosed in either the $(...) or (...) command constructs. Variables can be kept local to the command substitution environment by declaring them locally as in:

$ $(typeset j=100)

The main reason for this difference between the standard POSIX KornShell and Unix Shell for Windows has to do with the environment. In effect, spawning a new subshell means that the new environment in the subshell cannot return any resources back to the parent process. For instance, if the subshell allocated memory, then the memory address would only be valid to the subshell process. By not spawning subshells, Unix Shell for Windows allows these resources to be returned back to the current environment since the calls are being made in the current shell's process space.

Programming Using Unix Shell for Windows Extended Features

Unix Shell for Windows allows you to write standard shell programs just like on Linux and Unix systems. But in addition to this capability, Unix Shell for Windows offers the programmer the ability to write programs that are far beyond just standard shell programs. With the Unix Shell for Windows extended features you can actually write Windows applications.

Here is a simple example:

$ message="hello world"
$ call mb_printf $(@ -a message)
1

This example actually displays a window with the message, "hello world" in it. There are a few things to notice here. The first is the use of the call command. The call command is used to make a call to a library function. The function can be either the name of a Windows DLL (Dynamic Link Library) function or it can be one of the pre-defined Standard Windows Library functions defined in the shell.

The function mb_printf() is a Standard Windows Library function. If you type in the following:

$ man mb_printf

You will notice that what is displayed is the C programming usage for the mb_printf() function.

Note the difference between calling functions in C versus Unix Shell for Windows. In C you would call a function using the following syntax:

func(arg0, arg1, ..., argn);

Whereas, in Unix Shell for Windows you would use the call command as in:

call func arg0 arg1 ... argn

Notice also that in the shell you do not need to put parentheses around the arguments and you do not need to use commas. You only need to put spaces between each argument.

The only thing you do need to remember is that the arguments that you pass to the function must be numeric since they are only either numeric arguments or memory addresses. In order to pass a string to a function you need to get the address of the variable in shell.

As in the example, to get the address of the variable $message you use the @ operator. The -a option specifies that you want the actual shell memory address of the variable. For example to display the address of the shell variable $message you would type:

$ @ -a message
39784160

This value can then be passed as a memory address to the called function as in:

$ call -z mb_printf $(@ -a message)

The -z option tells the call command to suppress output of the function's return value.

To call a Windows DLL function such as GetDesktopWindow() and store the resulting handle in a shell variable you can do something like:

$ hwnd=$(call GetDesktopWindow)

Make sure when calling DLL functions that you specify the exact name of the function in terms of its spelling and case or the function will not be found. For example:

$ call getdesktopwindow
C:/Janotech/bin/ksh.exe: call: getdesktopwindow not found

Notice that using getdesktopwindow (all lowercase) did not find the function.

The shell variable $KSH_LIBS specifies the list of DLL's that are to be searched when making a call to a function. The default profile sets this variable when you start the shell:

export KSH_LIBS="kernel32.dll user32.dll gdi32.dll msvcrt.dll"

To specify more libraries you can either modify this variable or add libraries to the search list using the call -l option.

If the Windows DLL function you are trying to call cannot be found and the spelling and case are correct, then it is possible that the DLL name has not been specified in the search list.

Structures In Unix Shell for Windows

The struct command allows you to define structures directly in the shell.

The basic struct syntax is as follows:

struct [struct_name] [type member_name ... ]

We will start with a simple example. To define a structure to store an x and y coordinate point where x and y are two integers you could use the following struct definition:

$ struct point "int x int y"

Notice that you enclose the entire list of type member names in quotation marks after the struct name. This is because the struct type member name list is only one argument to the struct command. The struct name is the first argument. You can list the structure definition at any time by typing:

$ struct point
struct point 'int x int y'

Now let's allocate some memory for a struct variable of type point. This requires use of the sizeof operator to return the size of the point struct in bytes and to be used in a call to the malloc():

$ z=$(call malloc $(sizeof point))

Finally, we tell the memory address referenced by $z to be of type point:

$ struct point $z

Now we are ready to access the members of the structure. To set the members of the point struct we use the @ operator as in:

$ @ $z.x=100
$ @ $z.y=200

You can display the members of the struct for instance using:

$ @ $z.x
100
$ @ $z.y
200

You can also display the entire struct just by using the $z address as in:

$ @ $z
100 200

You can also initialize the entire struct using a quoted string as in:

$ @ $z="300 400"
$ @ $z.x
300
$ @ $z.y
400

The Union Type

Union types are also possible in the shell. To define a union using the union command the basic syntax is:

union [union_name] [type member_name ...]        

For instance to define a union that can hold either a float or an integer you would use the following definition:

$ union u 'float f int i'

You can then use the union in the same way as you would a struct as in:

$ z=$(call malloc $(sizeof u))
$ union u $z
$ @ $z.i=10
$ @ $z.i
10

or

$ @ $z.f=1.23
$ @ $z.f
1.23

Freeing Memory

You can use the free() function call to free memory allocated using malloc()

When you are finished using a structure or any memory that was allocated using the malloc() function, you would first free up the memory pointed to it as in:

$ call free $z
1

Also if you were not again going to use a struct or union that you have previously defined, you can free the memory allocated for the structure or union definition using the destruct command as in:

$ destruct point

This deallocates the memory used by the definition of the structure or union itself.

Structure Member Basic Types

The following basic types can be used in a shell struct definition:

	char
	int
	short
	long
	float
	double
	pointer
	unsigned char
	unsigned int
	unsigned short
	unsigned long

Using the Unsigned Types

The unsigned basic data types are represented by double-quoted strings within the struct type member name list itself. For instance:

$ struct date '"unsigned int" month "unsigned int" day "unsigned int" year'

This may seem a little confusing so the easiest thing is to define structures for the unsigned types themselves and then use them as types in the new structure. This is similar to a C typedef. For example, to define a structure for an unsigned integer type:

$ struct UINT '"unsigned int" val'

Then the date structure can be defined more easily as:

$ struct date "UINT month UINT day UINT year"

The Char Type

We can define a struct that uses type array of char. The following example struct definition in the shell illustrates this

$ struct mystruct 'char name[20] int age char middle'
$ z=$(call malloc $(sizeof mystruct))
$ struct mystruct $z

To assign some text to the name member variable:

$ @ $z.name='"John Smith"'

The reason for the single and then double quotes is that the shell will remove the double quotes if we just used double quotes. The single quote mechanism will allow the double quotes to be passed to the assignment. Since this is a character array we need double quotes to assign a character string. Otherwise the assignment for a type char is taken to be a numeric character equivalent.

For instance to assign the character value of an ASCII 'A' or 65 to the middle member of the above struct we could do

$ @ $z.middle=65 

or

$ @ $z.middle='"A"'

You can also assign the entire struct in a string by doing something like:

$ @ $z='"John Smith" 23 "A"'
$ @ $z
"John Smith\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 23 "A"

You can also assign values to individual array locations.

$ @ $z.name[2]='"a"'
$ @ $z.name
Joan Smith

The Sizeof Command

The sizeof operator works the same way in shell as it does in for instance in the C language. The only difference is that you do not need to specify the struct key word when getting the size of a struct.

For instance displaying size of the date struct would be:

$ . windows.ksh # load Windows definitions (see below)
$ struct date "UINT month UINT day UINT year"
$ sizeof date
12

You can of course specify sizeof with basic types as in:

$ sizeof char
1
$ sizeof short
2
$ sizeof float
4

Using the Shell Include Files

When writing programs that use Windows functions you can use the set of shell include files that are supplied with this package to provide the standard Windows definition, structures, and constants. These include files are located in $JANOTECH/ksh/include.

To include a file you would just use the file as a dot script to include it into the current shell program environment as in

$ . windows

Note: there must be a space after the dot.

You can then do set pipe into more to see all of the definitions.

$ set | more

to get a listing of all of the Windows structures that were added to the current shell environment you can type struct on a line by itself.

$ struct

Including the windows.ksh file is somewhat equivalent to including the windows.h file when doing C programming.

Message Handlers

So far, the examples that have been shown have been presented in shell interactive mode so that you can type them at the command prompt and see how the current environment is affected. For the next examples we will show simple shell scripts that will in effect handle Windows messages.

To add a Windows message handler for the WM_CLOSE message to a Window that was created with a CreateWindowEx() call you would do the following:

handler OnClose $WM_CLOSE

Here's the code for a complete Windows program that implements the Windows message handler:

. windows	# include Windows standard definitions
. shell_window	# include example create window code
. message_loop	# example message loop code

register_class	# this registers the shell window class

OnClose() 	# the WM_CLOSE handler shell function
{
	call DestroyWindow $1
	call PostQuitMessage 0
}

handler "OnClose" $WM_CLOSE
create_window "new window"
message_loop

Note that $1 in the above example OnClose() handler gets passed the Window handle or HWND. $2 becomes the Windows message UINT value and $3 and $4 get passed the WPARAM value and LPARAM values respectively.

This next example will add the WM_PAINT message handler shell function.

 
. windows	# include Windows standard definitions
. shell_window	# include example create window code
. message_loop	# example message loop code

register_class	# this registers the shell window class

OnClose()
{
	call DestroyWindow $1
	call PostQuitMessage 0
}

OnPaint()
{
	message="Hello World!"
	ps=$(call malloc $(sizeof PAINTSTRUCT))
	struct PAINTSTRUCT $ps
	hdc=$(call BeginPaint $1 $ps)
	call TextOut $hdc 0 0 $(@ -a message) ${#message}
	call EndPaint $1 $ps
}

handler "OnClose" $WM_CLOSE
handler "OnPaint" $WM_PAINT
create_window "new window"
message_loop

Callback Functions

Writing Windows callback functions such as those used to enumerate Windows fonts or devices in the shell can be accomplished by specifying the -c option to the call command. Here is the code for an example that enumerates the names of all of the Windows fonts.

. windows

EnumFontsProc()
{
	struct LOGFONT $1
	z=$(@ $1.lfFaceName)
	echo $z
	return 1
}

hwnd=$(call GetDesktopWindow)
hdc=$(call GetDC $hwnd)
params="pointer pointer long long"
call -znc0 -p "$params" -f EnumFontsProc EnumFonts $hdc 0 $CALLBACK0 0

Running Shell Programs From the Windows Desktop

In order to run a shell program standalone from an icon on the windows desktop, you can do the following:

First of all make sure that the shell script you are trying to run sets the PATH and KSH_LIBS variables correctly. For example, you might need to add the following lines to the beginning of the program before any . includes.

export KSH_LIBS='kernel32.dll user32.dll gdi32.dll msvcrt.dll'
export PATH="$JANOTECH/bin;$JANOTECH/ksh/include;$PATH"

Next, when you create the Windows shortcut you need to specify a Start in: directory where the program resides. This might be something like:

C:\Janotech\Ksh\Examples

Finally you need to set the target line. For example:

C:\Janotech\Bin\Console.exe -hide -set JANOTECH="C:\Janotech" -set HOME="C:\Janotech\User" "C:\Janotech\Bin\Ksh.exe C:\Janotech\Ksh\Examples\Hello.ksh" -shmem 4096 

Using the OpenGL Graphics Library

There are some example OpenGL header files that can be included as . scripts when writing programs that use OpenGL. They are gl.ksh and glu.ksh. For instance you would start the program with:

. windows
. gl
. glu

There are two things to note when using graphics library. The first is that the DLL's must be specified first in the $KSH_LIBS variable as in:

export KSH_LIBS='opengl32.lib glu32.lib kernel32.dll user32.dll gdi32.dll msvcrt.dll'

The reason is that there may be other versions of functions like ChoosePixelFormat() that are found in some of the standard Windows libraries. So the OpenGL version might not get called.

The other thing to note when using graphics libraries is the use of float and double arguments to functions. When passing arguments to an OpenGL function such as glFrustum() that needs doubles, you should not specify the arguments with an F float suffix. For instance:

call glFrustum -0.5 0.5 -0.5 0.5 1.0 3.0

However when passing arguments to OpenGL functions that require floats, you would use the F suffix as in:

call glRotatef 30.0F 1.0F 0.0F 0.0F

© Janotech, LLC 2008